From 78b002863839b4e90b29ea530f9e1e0b84bbf5a8 Mon Sep 17 00:00:00 2001 From: Matt Lord Date: Wed, 5 Nov 2025 13:08:32 -0500 Subject: [PATCH 001/112] [release-22.0] Bump to `v22.0.3-SNAPSHOT` after the `v22.0.2` release (#18881) Signed-off-by: Matt Lord --- go/vt/servenv/version.go | 2 +- java/client/pom.xml | 2 +- java/example/pom.xml | 2 +- java/grpc-client/pom.xml | 2 +- java/jdbc/pom.xml | 2 +- java/pom.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go/vt/servenv/version.go b/go/vt/servenv/version.go index 191f1443e5b..6aea4b9c65d 100644 --- a/go/vt/servenv/version.go +++ b/go/vt/servenv/version.go @@ -19,4 +19,4 @@ package servenv // DO NOT EDIT // THIS FILE IS AUTO-GENERATED DURING NEW RELEASES BY THE VITESS-RELEASER -const versionName = "22.0.2" +const versionName = "22.0.3-SNAPSHOT" diff --git a/java/client/pom.xml b/java/client/pom.xml index 6bc2412c7a4..1c356ea6330 100644 --- a/java/client/pom.xml +++ b/java/client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 22.0.2 + 22.0.3-SNAPSHOT vitess-client Vitess Java Client diff --git a/java/example/pom.xml b/java/example/pom.xml index 7bade73e127..927192a593e 100644 --- a/java/example/pom.xml +++ b/java/example/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 22.0.2 + 22.0.3-SNAPSHOT vitess-example Vitess Java Client Example diff --git a/java/grpc-client/pom.xml b/java/grpc-client/pom.xml index 7106c80a917..dbb42fb51ea 100644 --- a/java/grpc-client/pom.xml +++ b/java/grpc-client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 22.0.2 + 22.0.3-SNAPSHOT vitess-grpc-client Vitess gRPC Client diff --git a/java/jdbc/pom.xml b/java/jdbc/pom.xml index f4480d6a09f..97b89ca0c9e 100644 --- a/java/jdbc/pom.xml +++ b/java/jdbc/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 22.0.2 + 22.0.3-SNAPSHOT vitess-jdbc Vitess JDBC Driver diff --git a/java/pom.xml b/java/pom.xml index 47da86c75fb..74c2fa37bf2 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -11,7 +11,7 @@ io.vitess vitess-parent - 22.0.2 + 22.0.3-SNAPSHOT pom Vitess Java Client libraries [Parent] From e88223d2d886157363205652a3567e19faa6b96a Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Tue, 18 Nov 2025 14:07:52 -0500 Subject: [PATCH 002/112] [release-22.0] Improve Semi-Sync Monitor Behavior to Prevent Errant ERS (#18884) (#18906) Signed-off-by: Matt Lord Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Matt Lord --- .../tabletmanager/rpc_replication_test.go | 134 ++- .../tabletmanager/semisyncmonitor/monitor.go | 163 ++-- .../semisyncmonitor/monitor_test.go | 789 +++++++++++++----- 3 files changed, 815 insertions(+), 271 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/rpc_replication_test.go b/go/vt/vttablet/tabletmanager/rpc_replication_test.go index cec0027fb55..7ba8fc6729c 100644 --- a/go/vt/vttablet/tabletmanager/rpc_replication_test.go +++ b/go/vt/vttablet/tabletmanager/rpc_replication_test.go @@ -28,11 +28,12 @@ import ( "vitess.io/vitess/go/protoutil" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/mysqlctl" - topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/memorytopo" "vitess.io/vitess/go/vt/vttablet/tabletmanager/semisyncmonitor" "vitess.io/vitess/go/vt/vttablet/tabletserver" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) // TestWaitForGrantsToHaveApplied tests that waitForGrantsToHaveApplied only succeeds after waitForDBAGrants has been called. @@ -130,12 +131,17 @@ func TestDemotePrimaryWaitingForSemiSyncUnblock(t *testing.T) { tm.SemiSyncMonitor.Open() // Add a universal insert query pattern that would block until we make it unblock. + // ExecuteFetchMulti will execute each statement separately, so we need to add SET query. + fakeDb.AddQueryPattern("SET SESSION lock_wait_timeout=.*", &sqltypes.Result{}) ch := make(chan int) fakeDb.AddQueryPatternWithCallback("^INSERT INTO.*", sqltypes.MakeTestResult(nil), func(s string) { <-ch }) // Add a fake query that makes the semi-sync monitor believe that the tablet is blocked on semi-sync ACKs. - fakeDb.AddQuery("select variable_value from performance_schema.global_status where regexp_like(variable_name, 'Rpl_semi_sync_(source|master)_wait_sessions')", sqltypes.MakeTestResult(sqltypes.MakeTestFields("Variable_value", "varchar"), "1")) + fakeDb.AddQuery("SELECT /*+ MAX_EXECUTION_TIME(500) */ variable_name, variable_value FROM performance_schema.global_status WHERE REGEXP_LIKE(variable_name, 'Rpl_semi_sync_(source|master)_(wait_sessions|yes_tx)')", sqltypes.MakeTestResult( + sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), + "Rpl_semi_sync_source_wait_sessions|1", + "Rpl_semi_sync_source_yes_tx|5")) // Verify that in the beginning the tablet is serving. require.True(t, tm.QueryServiceControl.IsServing()) @@ -160,7 +166,10 @@ func TestDemotePrimaryWaitingForSemiSyncUnblock(t *testing.T) { require.False(t, fakeMysqlDaemon.SuperReadOnly.Load()) // Now we unblock the semi-sync monitor. - fakeDb.AddQuery("select variable_value from performance_schema.global_status where regexp_like(variable_name, 'Rpl_semi_sync_(source|master)_wait_sessions')", sqltypes.MakeTestResult(sqltypes.MakeTestFields("Variable_value", "varchar"), "0")) + fakeDb.AddQuery("SELECT /*+ MAX_EXECUTION_TIME(1000) */ variable_name, variable_value FROM performance_schema.global_status WHERE REGEXP_LIKE(variable_name, 'Rpl_semi_sync_(source|master)_(wait_sessions|yes_tx)')", sqltypes.MakeTestResult( + sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), + "Rpl_semi_sync_source_wait_sessions|0", + "Rpl_semi_sync_source_yes_tx|5")) close(ch) // This should unblock the demote primary operation eventually. @@ -171,6 +180,123 @@ func TestDemotePrimaryWaitingForSemiSyncUnblock(t *testing.T) { require.True(t, fakeMysqlDaemon.SuperReadOnly.Load()) } +// TestDemotePrimaryWithSemiSyncProgressDetection tests that demote primary proceeds +// without blocking when transactions are making progress (ackedTrxs increasing between checks). +func TestDemotePrimaryWithSemiSyncProgressDetection(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + ts := memorytopo.NewServer(ctx, "cell1") + tm := newTestTM(t, ts, 1, "ks", "0", nil) + // Make the tablet a primary. + err := tm.ChangeType(ctx, topodatapb.TabletType_PRIMARY, false) + require.NoError(t, err) + fakeMysqlDaemon := tm.MysqlDaemon.(*mysqlctl.FakeMysqlDaemon) + fakeDb := fakeMysqlDaemon.DB() + fakeDb.SetNeverFail(true) + + tm.SemiSyncMonitor.Open() + + // Set up the query to show waiting sessions, but with progress (ackedTrxs increasing). + // The monitor makes TWO calls to getSemiSyncStats with a sleep between them. + // We add the query result multiple times. The fakesqldb will return them in order (FIFO). + // First few calls: waiting sessions present, ackedTrxs=5. + for range 3 { + fakeDb.AddQuery("SELECT /*+ MAX_EXECUTION_TIME(1000) */ variable_name, variable_value FROM performance_schema.global_status WHERE REGEXP_LIKE(variable_name, 'Rpl_semi_sync_(source|master)_(wait_sessions|yes_tx)')", sqltypes.MakeTestResult( + sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), + "Rpl_semi_sync_source_wait_sessions|1", + "Rpl_semi_sync_source_yes_tx|5")) + } + // Next calls: waiting sessions present, but ackedTrxs=6 (progress!). + for range 10 { + fakeDb.AddQuery("SELECT /*+ MAX_EXECUTION_TIME(1000) */ variable_name, variable_value FROM performance_schema.global_status WHERE REGEXP_LIKE(variable_name, 'Rpl_semi_sync_(source|master)_(wait_sessions|yes_tx)')", sqltypes.MakeTestResult( + sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), + "Rpl_semi_sync_source_wait_sessions|1", + "Rpl_semi_sync_source_yes_tx|6")) + } + + // Verify that in the beginning the tablet is serving. + require.True(t, tm.QueryServiceControl.IsServing()) + + // Start the demote primary operation in a go routine. + var demotePrimaryFinished atomic.Bool + go func() { + _, err := tm.demotePrimary(ctx, false) + require.NoError(t, err) + demotePrimaryFinished.Store(true) + }() + + // Wait for the demote primary operation to have changed the serving state. + require.Eventually(t, func() bool { + return !tm.QueryServiceControl.IsServing() + }, 5*time.Second, 100*time.Millisecond) + + // DemotePrimary should finish quickly because progress is being made. + // It should NOT wait for semi-sync to unblock since ackedTrxs is increasing. + require.Eventually(t, func() bool { + return demotePrimaryFinished.Load() + }, 5*time.Second, 100*time.Millisecond) + + // We should have seen the super-read only query. + require.True(t, fakeMysqlDaemon.SuperReadOnly.Load()) +} + +// TestDemotePrimaryWhenSemiSyncBecomesUnblockedBetweenChecks tests that demote primary +// proceeds immediately when waiting sessions drops to 0 between the two checks. +func TestDemotePrimaryWhenSemiSyncBecomesUnblockedBetweenChecks(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + ts := memorytopo.NewServer(ctx, "cell1") + tm := newTestTM(t, ts, 1, "ks", "0", nil) + // Make the tablet a primary. + err := tm.ChangeType(ctx, topodatapb.TabletType_PRIMARY, false) + require.NoError(t, err) + fakeMysqlDaemon := tm.MysqlDaemon.(*mysqlctl.FakeMysqlDaemon) + fakeDb := fakeMysqlDaemon.DB() + fakeDb.SetNeverFail(true) + + tm.SemiSyncMonitor.Open() + + // Set up the query to show waiting sessions on first call, but 0 on second call. + // This simulates the semi-sync becoming unblocked between the two checks. + // The fakesqldb returns results in FIFO order. + // First call: waiting sessions present. + fakeDb.AddQuery("SELECT /*+ MAX_EXECUTION_TIME(1000) */ variable_name, variable_value FROM performance_schema.global_status WHERE REGEXP_LIKE(variable_name, 'Rpl_semi_sync_(source|master)_(wait_sessions|yes_tx)')", sqltypes.MakeTestResult( + sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), + "Rpl_semi_sync_source_wait_sessions|2", + "Rpl_semi_sync_source_yes_tx|5")) + // Second and subsequent calls: no waiting sessions (unblocked!). + for range 10 { + fakeDb.AddQuery("SELECT /*+ MAX_EXECUTION_TIME(1000) */ variable_name, variable_value FROM performance_schema.global_status WHERE REGEXP_LIKE(variable_name, 'Rpl_semi_sync_(source|master)_(wait_sessions|yes_tx)')", sqltypes.MakeTestResult( + sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), + "Rpl_semi_sync_source_wait_sessions|0", + "Rpl_semi_sync_source_yes_tx|5")) + } + + // Verify that in the beginning the tablet is serving. + require.True(t, tm.QueryServiceControl.IsServing()) + + // Start the demote primary operation in a go routine. + var demotePrimaryFinished atomic.Bool + go func() { + _, err := tm.demotePrimary(ctx, false) + require.NoError(t, err) + demotePrimaryFinished.Store(true) + }() + + // Wait for the demote primary operation to have changed the serving state. + require.Eventually(t, func() bool { + return !tm.QueryServiceControl.IsServing() + }, 5*time.Second, 100*time.Millisecond) + + // DemotePrimary should finish quickly because semi-sync became unblocked. + require.Eventually(t, func() bool { + return demotePrimaryFinished.Load() + }, 5*time.Second, 100*time.Millisecond) + + // We should have seen the super-read only query. + require.True(t, fakeMysqlDaemon.SuperReadOnly.Load()) +} + // TestUndoDemotePrimaryStateChange tests that UndoDemotePrimary // if able to change the state of the tablet to Primary if there // is a mismatch with the tablet record. @@ -188,7 +314,7 @@ func TestUndoDemotePrimaryStateChange(t *testing.T) { // Check that the tablet is initially a replica. require.EqualValues(t, topodatapb.TabletType_REPLICA, tm.Tablet().Type) - // Verify that the tablet record says the tablet should be a primary + // Verify that the tablet record says the tablet should be a primary. require.EqualValues(t, topodatapb.TabletType_PRIMARY, ti.Type) err = tm.UndoDemotePrimary(ctx, false) diff --git a/go/vt/vttablet/tabletmanager/semisyncmonitor/monitor.go b/go/vt/vttablet/tabletmanager/semisyncmonitor/monitor.go index 8f96a3bf0cd..13cad547a50 100644 --- a/go/vt/vttablet/tabletmanager/semisyncmonitor/monitor.go +++ b/go/vt/vttablet/tabletmanager/semisyncmonitor/monitor.go @@ -20,6 +20,7 @@ import ( "context" "fmt" "sync" + "sync/atomic" "time" "vitess.io/vitess/go/constants/sidecar" @@ -30,25 +31,36 @@ import ( "vitess.io/vitess/go/vt/dbconnpool" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/mysqlctl" + "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/servenv" "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv" ) const ( - semiSyncWaitSessionsRead = "select variable_value from performance_schema.global_status where regexp_like(variable_name, 'Rpl_semi_sync_(source|master)_wait_sessions')" - semiSyncHeartbeatWrite = "INSERT INTO %s.semisync_heartbeat (ts) VALUES (NOW())" - semiSyncHeartbeatClear = "TRUNCATE TABLE %s.semisync_heartbeat" - maxWritesPermitted = 15 - clearTimerDuration = 24 * time.Hour + // How many seconds we should wait for table/metadata locks. + // We do NOT want our TRUNCATE statement to block things indefinitely, and + // we do NOT want our INSERTs blocking indefinitely on any locks to appear + // as though they are blocking on a semi-sync ACK, which is what we really + // care about in the monitor as when we hit the limit of writers blocked + // on semi-sync ACKs we signal to VTOrc that we need help to unblock + // things and it will perform an ERS to do so. + // Note: this is something we are entirely fine being set in all of the + // monitor connection pool sessions, so we do not ever bother to set the + // session value back to the global default. + setLockWaitTimeoutQuery = "SET SESSION lock_wait_timeout=%d" + + semiSyncStatsQuery = "SELECT /*+ MAX_EXECUTION_TIME(%d) */ variable_name, variable_value FROM performance_schema.global_status WHERE REGEXP_LIKE(variable_name, 'Rpl_semi_sync_(source|master)_(wait_sessions|yes_tx)')" + semiSyncHeartbeatWrite = "INSERT INTO %s.semisync_heartbeat (ts) VALUES (NOW())" + semiSyncHeartbeatClear = "TRUNCATE TABLE %s.semisync_heartbeat" + maxWritesPermitted = 15 + clearTimerDuration = 24 * time.Hour ) -var ( - // waitBetweenWrites is the time to wait between consecutive writes. - // This is a variable instead of a constant only to be tweaked in tests. - waitBetweenWrites = 1 * time.Second -) +type semiSyncStats struct { + waitingSessions, ackedTrxs int64 +} // Monitor is a monitor that checks if the primary tablet // is blocked on a semi-sync ack from the replica. @@ -77,7 +89,7 @@ type Monitor struct { // isWriting stores if the monitor is currently writing to the DB. // We don't want two different threads initiating writes, so we use this // for synchronization. - isWriting bool + isWriting atomic.Bool // inProgressWriteCount is the number of writes currently in progress. // The writes from the monitor themselves might get blocked and hence a count for them is required. // After enough writes are blocked, we want to notify VTOrc to run an ERS. @@ -91,6 +103,11 @@ type Monitor struct { // errorCount is the number of errors that the semi-sync monitor ran into. // We ignore some of the errors, so the counter is a good way to track how many errors we have seen. errorCount *stats.Counter + + // actionDelay is the time to wait between various actions. + actionDelay time.Duration + // actionTimeout is when we should time out a given action. + actionTimeout time.Duration } // NewMonitor creates a new Monitor. @@ -105,6 +122,8 @@ func NewMonitor(config *tabletenv.TabletConfig, exporter *servenv.Exporter) *Mon errorCount: exporter.NewCounter("SemiSyncMonitorErrorCount", "Number of errors encountered by the semi-sync monitor"), appPool: dbconnpool.NewConnectionPool("SemiSyncMonitorAppPool", exporter, maxWritesPermitted+5, mysqlctl.DbaIdleTimeout, 0, mysqlctl.PoolDynamicHostnameResolution), waiters: make([]chan struct{}, 0), + actionDelay: config.SemiSyncMonitor.Interval / 10, + actionTimeout: config.SemiSyncMonitor.Interval / 2, } } @@ -174,10 +193,8 @@ func (m *Monitor) Close() { // and manufactures a write to unblock the primary. This function is safe to // be called multiple times in parallel. func (m *Monitor) checkAndFixSemiSyncBlocked() { - // Check if semi-sync is blocked or not - ctx, cancel := context.WithTimeout(context.Background(), topo.RemoteOperationTimeout) - defer cancel() - isBlocked, err := m.isSemiSyncBlocked(ctx) + // Check if semi-sync is blocked or not. + isBlocked, err := m.isSemiSyncBlocked() if err != nil { m.errorCount.Add(1) // If we are unable to determine whether the primary is blocked or not, @@ -197,7 +214,9 @@ func (m *Monitor) checkAndFixSemiSyncBlocked() { } // isSemiSyncBlocked checks if the primary is blocked on semi-sync. -func (m *Monitor) isSemiSyncBlocked(ctx context.Context) (bool, error) { +func (m *Monitor) isSemiSyncBlocked() (bool, error) { + ctx, cancel := context.WithTimeout(context.Background(), m.ticks.Interval()) + defer cancel() // Get a connection from the pool conn, err := m.appPool.Get(ctx) if err != nil { @@ -205,23 +224,16 @@ func (m *Monitor) isSemiSyncBlocked(ctx context.Context) (bool, error) { } defer conn.Recycle() - // Execute the query to check if the primary is blocked on semi-sync. - res, err := conn.Conn.ExecuteFetch(semiSyncWaitSessionsRead, 1, false) - if err != nil { + stats, err := m.getSemiSyncStats(conn) + if err != nil || stats.waitingSessions == 0 { return false, err } - // If we have no rows, then the primary doesn't have semi-sync enabled. - // It then follows, that the primary isn't blocked :) - if len(res.Rows) == 0 { - return false, nil - } - - // Read the status value and check if it is non-zero. - if len(res.Rows) != 1 || len(res.Rows[0]) != 1 { - return false, fmt.Errorf("unexpected number of rows received - %v", res.Rows) + time.Sleep(m.actionDelay) + followUpStats, err := m.getSemiSyncStats(conn) + if err != nil || followUpStats.waitingSessions == 0 || followUpStats.ackedTrxs > stats.ackedTrxs { + return false, err } - value, err := res.Rows[0][0].ToCastInt64() - return value != 0, err + return true, nil } // isClosed returns if the monitor is currently closed or not. @@ -272,25 +284,19 @@ func (m *Monitor) stillBlocked() bool { // checkAndSetIsWriting checks if the monitor is already writing to the DB. // If it is not, then it sets the isWriting field and signals the caller. func (m *Monitor) checkAndSetIsWriting() bool { - m.mu.Lock() - defer m.mu.Unlock() - if m.isWriting { - return false - } - m.isWriting = true - return true + return m.isWriting.CompareAndSwap(false, true) } // clearIsWriting clears the isWriting field. func (m *Monitor) clearIsWriting() { - m.mu.Lock() - defer m.mu.Unlock() - m.isWriting = false + m.isWriting.Store(false) } // startWrites starts writing to the DB. // It is re-entrant and will return if we are already writing. func (m *Monitor) startWrites() { + ctx, cancel := context.WithTimeout(context.Background(), m.ticks.Interval()) + defer cancel() // If we are already writing, then we can just return. if !m.checkAndSetIsWriting() { return @@ -300,13 +306,27 @@ func (m *Monitor) startWrites() { // Check if we need to continue writing or not. for m.stillBlocked() { + select { + case <-ctx.Done(): + return + default: + // We only need to do another write if there were no other successful + // writes and we're indeed still blocked. + blocked, err := m.isSemiSyncBlocked() + if err != nil { + return + } + if !blocked { + m.setIsBlocked(false) + return + } + } // We do the writes in a go-routine because if the network disruption // is somewhat long-lived, then the writes themselves can also block. // By doing them in a go-routine we give the system more time to recover while // exponentially backing off. We will not do more than maxWritesPermitted writes and once // all maxWritesPermitted writes are blocked, we'll wait for VTOrc to run an ERS. go m.write() - time.Sleep(waitBetweenWrites) } } @@ -330,7 +350,7 @@ func (m *Monitor) incrementWriteCount() bool { func (m *Monitor) AllWritesBlocked() bool { m.mu.Lock() defer m.mu.Unlock() - return m.isOpen && m.inProgressWriteCount == maxWritesPermitted + return m.isOpen && m.isBlocked && m.inProgressWriteCount == maxWritesPermitted } // decrementWriteCount decrements the write count. @@ -343,13 +363,12 @@ func (m *Monitor) decrementWriteCount() { // write writes a heartbeat to unblock semi-sync being stuck. func (m *Monitor) write() { - shouldWrite := m.incrementWriteCount() - if !shouldWrite { + if shouldWrite := m.incrementWriteCount(); !shouldWrite { return } defer m.decrementWriteCount() // Get a connection from the pool - ctx, cancel := context.WithTimeout(context.Background(), topo.RemoteOperationTimeout) + ctx, cancel := context.WithTimeout(context.Background(), m.actionTimeout) defer cancel() conn, err := m.appPool.Get(ctx) if err != nil { @@ -357,7 +376,7 @@ func (m *Monitor) write() { log.Errorf("SemiSync Monitor: failed to get a connection when writing to semisync_heartbeat table: %v", err) return } - _, err = conn.Conn.ExecuteFetch(m.bindSideCarDBName(semiSyncHeartbeatWrite), 0, false) + err = conn.Conn.ExecuteFetchMultiDrain(m.addLockWaitTimeout(m.bindSideCarDBName(semiSyncHeartbeatWrite))) conn.Recycle() if err != nil { m.errorCount.Add(1) @@ -388,14 +407,16 @@ func (m *Monitor) setIsBlocked(val bool) { // consumes too much space on the MySQL instance. func (m *Monitor) clearAllData() { // Get a connection from the pool - conn, err := m.appPool.Get(context.Background()) + ctx, cancel := context.WithTimeout(context.Background(), m.actionTimeout) + defer cancel() + conn, err := m.appPool.Get(ctx) if err != nil { m.errorCount.Add(1) log.Errorf("SemiSync Monitor: failed get a connection to clear semisync_heartbeat table: %v", err) return } defer conn.Recycle() - _, err = conn.Conn.ExecuteFetch(m.bindSideCarDBName(semiSyncHeartbeatClear), 0, false) + _, _, err = conn.Conn.ExecuteFetchMulti(m.addLockWaitTimeout(m.bindSideCarDBName(semiSyncHeartbeatClear)), 0, false) if err != nil { m.errorCount.Add(1) log.Errorf("SemiSync Monitor: failed to clear semisync_heartbeat table: %v", err) @@ -416,3 +437,47 @@ func (m *Monitor) addWaiter() chan struct{} { func (m *Monitor) bindSideCarDBName(query string) string { return sqlparser.BuildParsedQuery(query, sidecar.GetIdentifier()).Query } + +func (m *Monitor) addLockWaitTimeout(query string) string { + timeoutQuery := fmt.Sprintf(setLockWaitTimeoutQuery, int(m.actionTimeout.Seconds())) + return timeoutQuery + ";" + query +} + +func (m *Monitor) getSemiSyncStats(conn *dbconnpool.PooledDBConnection) (semiSyncStats, error) { + stats := semiSyncStats{} + // Execute the query to check if the primary is blocked on semi-sync. + query := fmt.Sprintf(semiSyncStatsQuery, m.actionTimeout.Milliseconds()) + res, err := conn.Conn.ExecuteFetch(query, 2, false) + if err != nil { + return stats, err + } + // If we have no rows, then the primary doesn't have semi-sync enabled. + // It then follows, that the primary isn't blocked :) + if len(res.Rows) == 0 { + return stats, nil + } + + // Read the status value and check if it is non-zero. + if len(res.Rows) != 2 { + return stats, vterrors.Errorf(vtrpc.Code_INTERNAL, "unexpected number of rows received, expected 2 but got %d, for semi-sync stats query %s", len(res.Rows), query) + } + if len(res.Rows[0]) != 2 { + return stats, vterrors.Errorf(vtrpc.Code_INTERNAL, "unexpected number of columns received, expected 2 but got %d, for semi-sync stats query %s", len(res.Rows[0]), query) + } + for i := range len(res.Rows) { + name := res.Rows[i][0].ToString() + value, err := res.Rows[i][1].ToCastInt64() + if err != nil { + return stats, vterrors.Wrapf(err, "unexpected results for semi-sync stats query %s: %v", query, res.Rows) + } + switch name { + case "Rpl_semi_sync_master_wait_sessions", "Rpl_semi_sync_source_wait_sessions": + stats.waitingSessions = value + case "Rpl_semi_sync_master_yes_tx", "Rpl_semi_sync_source_yes_tx": + stats.ackedTrxs = value + default: + return stats, vterrors.Errorf(vtrpc.Code_INTERNAL, "unexpected results for semi-sync stats query %s: %v", query, res.Rows) + } + } + return stats, nil +} diff --git a/go/vt/vttablet/tabletmanager/semisyncmonitor/monitor_test.go b/go/vt/vttablet/tabletmanager/semisyncmonitor/monitor_test.go index 9586514914b..5137d77ef97 100644 --- a/go/vt/vttablet/tabletmanager/semisyncmonitor/monitor_test.go +++ b/go/vt/vttablet/tabletmanager/semisyncmonitor/monitor_test.go @@ -26,8 +26,10 @@ import ( "github.com/stretchr/testify/require" + "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/mysql/fakesqldb" "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/test/utils" "vitess.io/vitess/go/vt/dbconfigs" "vitess.io/vitess/go/vt/servenv" "vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv" @@ -59,52 +61,339 @@ func createFakeDBAndMonitor(t *testing.T) (*fakesqldb.DB, *Monitor) { } // TestMonitorIsSemiSyncBlocked tests the functionality of isSemiSyncBlocked. +// NOTE: This test focuses on the first getSemiSyncStats call and early-return logic. +// The full two-call behavior is tested in TestMonitorIsSemiSyncBlockedProgressDetection. func TestMonitorIsSemiSyncBlocked(t *testing.T) { + defer utils.EnsureNoLeaks(t) + tests := []struct { name string - res *sqltypes.Result + result *sqltypes.Result want bool wantErr string }{ { - name: "no rows", - res: &sqltypes.Result{}, - want: false, + name: "no rows - semi-sync not enabled", + result: &sqltypes.Result{}, + want: false, }, { - name: "incorrect number of rows", - res: sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_value", "varchar"), "1", "1"), - wantErr: "Row count exceeded 1", + name: "incorrect results - invalid variable names", + result: sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), "foo|3", "foo|3"), + wantErr: "unexpected results for semi-sync stats query", }, { - name: "incorrect number of fields", - res: sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_value|a", "varchar|varchar"), "1|2"), - wantErr: `unexpected number of rows received - [[VARCHAR("1") VARCHAR("2")]]`, + name: "unblocked - zero waiting sessions", + result: sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), "Rpl_semi_sync_source_wait_sessions|0", "Rpl_semi_sync_source_yes_tx|1"), + want: false, }, { - name: "Unblocked", - res: sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_value", "varchar"), "0"), - want: false, + name: "has waiting sessions - needs second check", + result: sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), "Rpl_semi_sync_source_wait_sessions|1", "Rpl_semi_sync_source_yes_tx|5"), + // With fakesqldb limitation, second call returns same result, so it appears blocked. + want: true, }, { - name: "Blocked", - res: sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_value", "varchar"), "1"), + name: "master prefix for backwards compatibility", + result: sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), "Rpl_semi_sync_master_wait_sessions|2", "Rpl_semi_sync_master_yes_tx|50"), + // With fakesqldb limitation, second call returns same result, so it appears blocked. want: true, }, + { + name: "invalid variable value", + result: sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), "Rpl_semi_sync_source_wait_sessions|not_a_number", "Rpl_semi_sync_source_yes_tx|5"), + wantErr: "unexpected results for semi-sync stats query", + }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { db, m := createFakeDBAndMonitor(t) + m.actionDelay = 10 * time.Millisecond + m.actionTimeout = 1 * time.Second defer db.Close() - defer m.Close() - db.AddQuery(semiSyncWaitSessionsRead, tt.res) - got, err := m.isSemiSyncBlocked(context.Background()) + defer func() { + m.Close() + waitUntilWritingStopped(t, m) + }() + + db.AddQuery(fmt.Sprintf(semiSyncStatsQuery, m.actionTimeout.Milliseconds()), tt.result) + + got, err := m.isSemiSyncBlocked() if tt.wantErr != "" { - require.EqualError(t, err, tt.wantErr) + require.ErrorContains(t, err, tt.wantErr) return } require.NoError(t, err) - require.EqualValues(t, tt.want, got) + require.Equal(t, tt.want, got) + }) + } +} + +// TestMonitorIsSemiSyncBlockedConnectionError tests that we do not +// consider semi-sync blocked when we encounter an error trying to check. +func TestMonitorIsSemiSyncBlockedConnectionError(t *testing.T) { + defer utils.EnsureNoLeaks(t) + db, m := createFakeDBAndMonitor(t) + defer db.Close() + + // Close the pool to simulate connection errors. + m.mu.Lock() + m.appPool.Close() + m.mu.Unlock() + + defer func() { + m.Close() + waitUntilWritingStopped(t, m) + }() + + // The function should return an error when it can't get a connection. + got, err := m.isSemiSyncBlocked() + require.Error(t, err) + require.False(t, got) +} + +// TestMonitorIsSemiSyncBlockedWithBadResults tests error handling when +// the query returns an unexpected result. +func TestMonitorIsSemiSyncBlockedWithBadResults(t *testing.T) { + defer utils.EnsureNoLeaks(t) + + tests := []struct { + name string + res *sqltypes.Result + wantErr string + }{ + { + name: "one row instead of two", + res: sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), "Rpl_semi_sync_source_wait_sessions|1"), + wantErr: "unexpected number of rows received, expected 2 but got 1", + }, + { + name: "one column instead of two", + res: sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_value", "varchar"), "1", "1"), + wantErr: "unexpected number of columns received, expected 2 but got 1", + }, + { + name: "three rows instead of two", + res: sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), "Rpl_semi_sync_source_wait_sessions|1", "Rpl_semi_sync_source_yes_tx|5", "extra_row|10"), + // Note: The actual error is "Row count exceeded" because ExecuteFetch has maxrows=2. + wantErr: "Row count exceeded", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + db, m := createFakeDBAndMonitor(t) + m.actionDelay = 10 * time.Millisecond + m.actionTimeout = 1 * time.Second + defer db.Close() + defer func() { + m.Close() + waitUntilWritingStopped(t, m) + }() + + db.AddQuery(fmt.Sprintf(semiSyncStatsQuery, m.actionTimeout.Milliseconds()), tt.res) + + got, err := m.isSemiSyncBlocked() + require.False(t, got) + require.ErrorContains(t, err, tt.wantErr) + }) + } +} + +// TestMonitorIsSemiSyncBlockedProgressDetection tests various scenarios +// for detecting progress in semi-sync replication by directly calling +// getSemiSyncStats to verify the logic. +func TestMonitorIsSemiSyncBlockedProgressDetection(t *testing.T) { + defer utils.EnsureNoLeaks(t) + + tests := []struct { + name string + firstWaiting int64 + firstAcked int64 + secondWaiting int64 + secondAcked int64 + expectedBlocked bool + description string + }{ + { + name: "progress - acked increased by 1", + firstWaiting: 2, + firstAcked: 100, + secondWaiting: 2, + secondAcked: 101, + expectedBlocked: false, + description: "should detect progress when acked transactions increase", + }, + { + name: "progress - acked increased significantly", + firstWaiting: 1, + firstAcked: 50, + secondWaiting: 1, + secondAcked: 1000, + expectedBlocked: false, + description: "should detect progress with large acked transaction increase", + }, + { + name: "progress - waiting decreased to zero", + firstWaiting: 3, + firstAcked: 100, + secondWaiting: 0, + secondAcked: 100, + expectedBlocked: false, + description: "should detect progress when waiting sessions drop to zero", + }, + { + name: "blocked - waiting decreased but transactions not progressing", + firstWaiting: 5, + firstAcked: 100, + secondWaiting: 2, + secondAcked: 100, + expectedBlocked: true, + description: "should still be blocked when waiting sessions decrease but no transactions are acked", + }, + { + name: "blocked - no change in metrics", + firstWaiting: 2, + firstAcked: 100, + secondWaiting: 2, + secondAcked: 100, + expectedBlocked: true, + description: "should detect blocked state when no metrics change", + }, + { + name: "blocked - waiting increased", + firstWaiting: 1, + firstAcked: 100, + secondWaiting: 3, + secondAcked: 100, + expectedBlocked: true, + description: "should detect blocked state when waiting sessions increase", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Directly test the logic by simulating what isSemiSyncBlocked does. + // First call - check initial stats. + stats := semiSyncStats{ + waitingSessions: tt.firstWaiting, + ackedTrxs: tt.firstAcked, + } + + // Early return conditions from isSemiSyncBlocked. + if stats.waitingSessions == 0 { + require.False(t, tt.expectedBlocked, tt.description) + return + } + + // Second call - check follow-up stats. + followUpStats := semiSyncStats{ + waitingSessions: tt.secondWaiting, + ackedTrxs: tt.secondAcked, + } + + // Check if we're still blocked based on the actual logic in isSemiSyncBlocked. + // Returns false (not blocked) if: waitingSessions == 0 OR ackedTrxs increased. + isBlocked := !(followUpStats.waitingSessions == 0 || followUpStats.ackedTrxs > stats.ackedTrxs) + + require.Equal(t, tt.expectedBlocked, isBlocked, tt.description) + }) + } +} + +// TestGetSemiSyncStats tests the getSemiSyncStats helper function. +func TestGetSemiSyncStats(t *testing.T) { + defer utils.EnsureNoLeaks(t) + + tests := []struct { + name string + res *sqltypes.Result + expectedWaiting int64 + expectedAcked int64 + wantErr string + }{ + { + name: "valid source prefix", + res: sqltypes.MakeTestResult( + sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), + "Rpl_semi_sync_source_wait_sessions|3", + "Rpl_semi_sync_source_yes_tx|150"), + expectedWaiting: 3, + expectedAcked: 150, + }, + { + name: "valid master prefix", + res: sqltypes.MakeTestResult( + sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), + "Rpl_semi_sync_master_wait_sessions|5", + "Rpl_semi_sync_master_yes_tx|200"), + expectedWaiting: 5, + expectedAcked: 200, + }, + { + name: "zero values", + res: sqltypes.MakeTestResult( + sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), + "Rpl_semi_sync_source_wait_sessions|0", + "Rpl_semi_sync_source_yes_tx|0"), + expectedWaiting: 0, + expectedAcked: 0, + }, + { + name: "large values", + res: sqltypes.MakeTestResult( + sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), + "Rpl_semi_sync_source_wait_sessions|999999", + "Rpl_semi_sync_source_yes_tx|123456789"), + expectedWaiting: 999999, + expectedAcked: 123456789, + }, + { + name: "no rows returns empty stats", + res: &sqltypes.Result{}, + expectedWaiting: 0, + expectedAcked: 0, + }, + { + name: "wrong number of rows", + res: sqltypes.MakeTestResult( + sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), + "Rpl_semi_sync_source_wait_sessions|3"), + wantErr: "unexpected number of rows received, expected 2 but got 1", + }, + { + name: "invalid variable name", + res: sqltypes.MakeTestResult( + sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), + "invalid_variable|3", + "Rpl_semi_sync_source_yes_tx|150"), + wantErr: "unexpected results for semi-sync stats query", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + db, m := createFakeDBAndMonitor(t) + defer db.Close() + defer func() { + m.Close() + waitUntilWritingStopped(t, m) + }() + + db.AddQuery(fmt.Sprintf(semiSyncStatsQuery, m.actionTimeout.Milliseconds()), tt.res) + conn, err := m.appPool.Get(context.Background()) + require.NoError(t, err) + defer conn.Recycle() + + stats, err := m.getSemiSyncStats(conn) + if tt.wantErr != "" { + require.ErrorContains(t, err, tt.wantErr) + return + } + require.NoError(t, err) + require.Equal(t, tt.expectedWaiting, stats.waitingSessions) + require.Equal(t, tt.expectedAcked, stats.ackedTrxs) }) } } @@ -136,9 +425,13 @@ func TestMonitorClearAllData(t *testing.T) { defer db.Close() defer m.Close() db.SetNeverFail(true) + // ExecuteFetchMulti will execute each statement separately, so we need to add both queries. + db.AddQuery("SET SESSION lock_wait_timeout=5", &sqltypes.Result{}) + db.AddQuery("truncate table _vt.semisync_heartbeat", &sqltypes.Result{}) m.clearAllData() ql := db.QueryLog() - require.EqualValues(t, "truncate table _vt.semisync_heartbeat", ql) + require.Contains(t, ql, "set session lock_wait_timeout=5") + require.Contains(t, ql, "truncate table _vt.semisync_heartbeat") } // TestMonitorWaitMechanism tests that the wait mechanism works as intended. @@ -272,6 +565,9 @@ func TestMonitorAllWritesBlocked(t *testing.T) { defer m.Close() m.mu.Lock() m.inProgressWriteCount = tt.initVal + if m.inProgressWriteCount == tt.initVal { + m.isBlocked = true + } m.mu.Unlock() require.EqualValues(t, tt.expected, m.AllWritesBlocked()) }) @@ -280,21 +576,21 @@ func TestMonitorAllWritesBlocked(t *testing.T) { func TestMonitorWrite(t *testing.T) { tests := []struct { - initVal int - queryLog string + initVal int + shouldWrite bool }{ { - initVal: maxWritesPermitted - 2, - queryLog: "insert into _vt.semisync_heartbeat (ts) values (now())", + initVal: maxWritesPermitted - 2, + shouldWrite: true, }, { - initVal: maxWritesPermitted - 1, - queryLog: "insert into _vt.semisync_heartbeat (ts) values (now())", + initVal: maxWritesPermitted - 1, + shouldWrite: true, }, { - initVal: maxWritesPermitted, - queryLog: "", + initVal: maxWritesPermitted, + shouldWrite: false, }, { - initVal: 0, - queryLog: "insert into _vt.semisync_heartbeat (ts) values (now())", + initVal: 0, + shouldWrite: true, }, } for _, tt := range tests { @@ -303,6 +599,9 @@ func TestMonitorWrite(t *testing.T) { defer db.Close() defer m.Close() db.SetNeverFail(true) + // ExecuteFetchMulti will execute each statement separately, so we need to add both queries. + db.AddQuery("SET SESSION lock_wait_timeout=5", &sqltypes.Result{}) + db.AddQuery("insert into _vt.semisync_heartbeat (ts) values (now())", &sqltypes.Result{}) m.mu.Lock() m.inProgressWriteCount = tt.initVal m.writesBlockedGauge.Set(int64(tt.initVal)) @@ -312,19 +611,23 @@ func TestMonitorWrite(t *testing.T) { require.EqualValues(t, tt.initVal, m.inProgressWriteCount) require.EqualValues(t, tt.initVal, m.writesBlockedGauge.Get()) m.mu.Unlock() - require.EqualValues(t, tt.queryLog, db.QueryLog()) + queryLog := db.QueryLog() + if tt.shouldWrite { + require.Contains(t, queryLog, "set session lock_wait_timeout=5") + require.Contains(t, queryLog, "insert into _vt.semisync_heartbeat (ts) values (now())") + } else { + require.Equal(t, "", queryLog) + } }) } } // TestMonitorWriteBlocked tests the write function when the writes are blocked. func TestMonitorWriteBlocked(t *testing.T) { - initialVal := waitBetweenWrites - waitBetweenWrites = 250 * time.Millisecond - defer func() { - waitBetweenWrites = initialVal - }() + defer utils.EnsureNoLeaks(t) db, m := createFakeDBAndMonitor(t) + m.actionDelay = 10 * time.Millisecond + m.actionTimeout = 1 * time.Second defer db.Close() defer m.Close() @@ -333,11 +636,12 @@ func TestMonitorWriteBlocked(t *testing.T) { require.EqualValues(t, 0, m.inProgressWriteCount) m.mu.Unlock() - // Add a universal insert query pattern that would block until we make it unblock. - ch := make(chan int) - db.AddQueryPatternWithCallback("^INSERT INTO.*", sqltypes.MakeTestResult(nil), func(s string) { - <-ch - }) + // ExecuteFetchMulti will execute each statement separately, so we need to add SET query and INSERT query. + // Add them multiple times so the writes can execute. + for range maxWritesPermitted { + db.AddQuery("SET SESSION lock_wait_timeout=1", &sqltypes.Result{}) + db.AddQuery("INSERT INTO _vt.semisync_heartbeat (ts) VALUES (NOW())", &sqltypes.Result{}) + } // Do a write, which we expect to block. var writeFinished atomic.Bool @@ -345,24 +649,24 @@ func TestMonitorWriteBlocked(t *testing.T) { m.write() writeFinished.Store(true) }() - // We should see the number of writes blocked to increase. - require.Eventually(t, func() bool { - m.mu.Lock() - defer m.mu.Unlock() - return m.inProgressWriteCount == 1 - }, 2*time.Second, 100*time.Millisecond) - // Once the writers are unblocked, we expect to see a zero value again. - close(ch) + // We should see the number of writers increase briefly, before it completes. + require.Zero(t, m.errorCount.Get()) require.Eventually(t, func() bool { m.mu.Lock() defer m.mu.Unlock() - return m.inProgressWriteCount == 0 - }, 2*time.Second, 100*time.Millisecond) + return m.inProgressWriteCount > 0 + }, 2*time.Second, 5*time.Microsecond) + // Check that the writes finished successfully. require.Eventually(t, func() bool { return writeFinished.Load() }, 2*time.Second, 100*time.Millisecond) + + // After write completes, count should be back to zero. + m.mu.Lock() + defer m.mu.Unlock() + require.EqualValues(t, 0, m.inProgressWriteCount) } // TestIsWriting checks the transitions for the isWriting field. @@ -373,51 +677,55 @@ func TestIsWriting(t *testing.T) { // Check the initial value of the isWriting field. m.mu.Lock() - require.False(t, m.isWriting) + require.False(t, m.isWriting.Load()) m.mu.Unlock() // Clearing a false field does nothing. m.clearIsWriting() m.mu.Lock() - require.False(t, m.isWriting) + require.False(t, m.isWriting.Load()) m.mu.Unlock() // Check and set should set the field. set := m.checkAndSetIsWriting() require.True(t, set) m.mu.Lock() - require.True(t, m.isWriting) + require.True(t, m.isWriting.Load()) m.mu.Unlock() // Checking and setting shouldn't do anything. set = m.checkAndSetIsWriting() require.False(t, set) m.mu.Lock() - require.True(t, m.isWriting) + require.True(t, m.isWriting.Load()) m.mu.Unlock() // Clearing should now make the field false. m.clearIsWriting() m.mu.Lock() - require.False(t, m.isWriting) + require.False(t, m.isWriting.Load()) m.mu.Unlock() } func TestStartWrites(t *testing.T) { - initialVal := waitBetweenWrites - waitBetweenWrites = 250 * time.Millisecond - defer func() { - waitBetweenWrites = initialVal - }() + defer utils.EnsureNoLeaks(t) db, m := createFakeDBAndMonitor(t) + m.actionDelay = 10 * time.Millisecond + m.actionTimeout = 1 * time.Second defer db.Close() defer m.Close() - // Add a universal insert query pattern that would block until we make it unblock. - ch := make(chan int) - db.AddQueryPatternWithCallback("^INSERT INTO.*", sqltypes.MakeTestResult(nil), func(s string) { - <-ch - }) + // Set up semi-sync stats query to return blocked state (waiting sessions > 0, no progress). + // This is what isSemiSyncBlocked will check inside startWrites. + db.AddQuery(fmt.Sprintf(semiSyncStatsQuery, m.actionTimeout.Milliseconds()), sqltypes.MakeTestResult( + sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), + "Rpl_semi_sync_source_wait_sessions|2", + "Rpl_semi_sync_source_yes_tx|100")) + + // ExecuteFetchMulti will execute each statement separately. + // Use patterns for both SET and INSERT since they can be called multiple times. + db.AddQuery("SET SESSION lock_wait_timeout=1", &sqltypes.Result{}) + db.AddQuery("INSERT INTO _vt.semisync_heartbeat (ts) VALUES (NOW())", &sqltypes.Result{}) // If we aren't blocked, then start writes doesn't do anything. m.startWrites() @@ -426,65 +734,50 @@ func TestStartWrites(t *testing.T) { // Now we set the monitor to be blocked. m.setIsBlocked(true) - var writesFinished atomic.Bool - go func() { - m.startWrites() - writesFinished.Store(true) - }() - - // We should see the number of writes blocked to increase. - require.Eventually(t, func() bool { - m.mu.Lock() - defer m.mu.Unlock() - return m.inProgressWriteCount >= 1 - }, 2*time.Second, 100*time.Millisecond) - - // Once the writes have started, another call to startWrites shouldn't do anything + // Start writes and wait for them to complete. m.startWrites() - // We should continue to see the number of writes blocked increase. + // Check that some writes are in progress. require.Eventually(t, func() bool { m.mu.Lock() defer m.mu.Unlock() - return m.inProgressWriteCount >= 2 - }, 2*time.Second, 100*time.Millisecond) + return m.inProgressWriteCount > 0 + }, 2*time.Second, 5*time.Microsecond) - // Check that the writes are still going. - require.False(t, writesFinished.Load()) + // Verify the query log shows the writes were executed. + queryLog := db.QueryLog() + require.Contains(t, queryLog, "insert into _vt.semisync_heartbeat") - // Make the monitor unblocked. This should stop the writes eventually. + // Make the monitor unblocked. This should stop the writes. m.setIsBlocked(false) - close(ch) - - require.Eventually(t, func() bool { - return writesFinished.Load() - }, 2*time.Second, 100*time.Millisecond) // Check that no writes are in progress anymore. require.Eventually(t, func() bool { m.mu.Lock() defer m.mu.Unlock() return m.inProgressWriteCount == 0 - }, 2*time.Second, 100*time.Millisecond) + }, 5*time.Second, 100*time.Millisecond) } func TestCheckAndFixSemiSyncBlocked(t *testing.T) { - initialVal := waitBetweenWrites - waitBetweenWrites = 250 * time.Millisecond - defer func() { - waitBetweenWrites = initialVal - }() + defer utils.EnsureNoLeaks(t) db, m := createFakeDBAndMonitor(t) + m.actionDelay = 10 * time.Millisecond + m.actionTimeout = 1 * time.Second defer db.Close() defer m.Close() - // Initially everything is unblocked. - db.AddQuery(semiSyncWaitSessionsRead, sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_value", "varchar"), "0")) - // Add a universal insert query pattern that would block until we make it unblock. - ch := make(chan int) - db.AddQueryPatternWithCallback("^INSERT INTO.*", sqltypes.MakeTestResult(nil), func(s string) { - <-ch - }) + db.SetNeverFail(true) + // Initially everything is unblocked (zero waiting sessions). + db.AddQuery(fmt.Sprintf(semiSyncStatsQuery, m.actionTimeout.Milliseconds()), sqltypes.MakeTestResult( + sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), + "Rpl_semi_sync_source_wait_sessions|0", + "Rpl_semi_sync_source_yes_tx|10")) + + // ExecuteFetchMulti will execute each statement separately. + // Use patterns for both SET and INSERT since they can be called multiple times. + db.AddQuery("SET SESSION lock_wait_timeout=1", &sqltypes.Result{}) + db.AddQuery("INSERT INTO _vt.semisync_heartbeat (ts) VALUES (NOW())", &sqltypes.Result{}) // Check that the monitor thinks we are unblocked. m.checkAndFixSemiSyncBlocked() @@ -492,70 +785,130 @@ func TestCheckAndFixSemiSyncBlocked(t *testing.T) { require.False(t, m.isBlocked) m.mu.Unlock() - // Now we set the monitor to be blocked. - db.AddQuery(semiSyncWaitSessionsRead, sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_value", "varchar"), "2")) - m.checkAndFixSemiSyncBlocked() + // Now we set the monitor to be blocked (waiting sessions > 0, no progress). + db.AddQuery(fmt.Sprintf(semiSyncStatsQuery, m.actionTimeout.Milliseconds()), sqltypes.MakeTestResult( + sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), + "Rpl_semi_sync_source_wait_sessions|2", + "Rpl_semi_sync_source_yes_tx|10")) - m.mu.Lock() - require.True(t, m.isBlocked) - m.mu.Unlock() + // Manually set isBlocked and start writes like the monitor would do. + m.setIsBlocked(true) - // Checking again shouldn't make a difference. - m.checkAndFixSemiSyncBlocked() - m.mu.Lock() - require.True(t, m.isBlocked) - m.mu.Unlock() + // Start writes and wait for them to complete. + m.startWrites() - // Meanwhile writes should have started and should be getting blocked. + // Wait a bit to let writes execute require.Eventually(t, func() bool { m.mu.Lock() defer m.mu.Unlock() - return m.inProgressWriteCount >= 2 - }, 2*time.Second, 100*time.Millisecond) + return m.inProgressWriteCount == 0 + }, 2*time.Second, 5*time.Microsecond) - // Now we set the monitor to be unblocked. - db.AddQuery(semiSyncWaitSessionsRead, sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_value", "varchar"), "0")) - close(ch) - m.checkAndFixSemiSyncBlocked() + // Verify the query log shows the writes were executed. + queryLog := db.QueryLog() + require.Contains(t, queryLog, "insert into _vt.semisync_heartbeat") - // We expect the writes to clear out and also the monitor should think its unblocked. - m.mu.Lock() - require.False(t, m.isBlocked) - m.mu.Unlock() + // Now we set the monitor to be unblocked (waiting sessions = 0). + db.AddQuery(fmt.Sprintf(semiSyncStatsQuery, m.actionTimeout.Milliseconds()), sqltypes.MakeTestResult( + sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), + "Rpl_semi_sync_source_wait_sessions|0", + "Rpl_semi_sync_source_yes_tx|10")) + + // Make the monitor unblocked. This should stop the writes. + m.setIsBlocked(false) + + // Check that no writes are in progress anymore. require.Eventually(t, func() bool { m.mu.Lock() defer m.mu.Unlock() - return m.inProgressWriteCount == 0 && m.isWriting == false - }, 2*time.Second, 100*time.Millisecond) + return m.inProgressWriteCount == 0 + }, 10*time.Second, 100*time.Millisecond) +} + +// statefulQueryHandler is a custom query handler that can return different results +// based on an atomic boolean state. This allows tests to dynamically change query +// results without relying on precise query result counts. +type statefulQueryHandler struct { + db *fakesqldb.DB + semisyncBlocked atomic.Bool + blockedResult *sqltypes.Result + unblockedResult *sqltypes.Result + semiSyncStatsQuery string +} + +func (h *statefulQueryHandler) HandleQuery(c *mysql.Conn, query string, callback func(*sqltypes.Result) error) error { + if query == h.semiSyncStatsQuery { + if h.semisyncBlocked.Load() { + return callback(h.blockedResult) + } + return callback(h.unblockedResult) + } + // Fall back to default handler for all other queries (SET and INSERT patterns). + return h.db.HandleQuery(c, query, callback) } func TestWaitUntilSemiSyncUnblocked(t *testing.T) { - initialVal := waitBetweenWrites - waitBetweenWrites = 250 * time.Millisecond + defer utils.EnsureNoLeaks(t) + db := fakesqldb.New(t) + defer db.Close() + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "") + config := &tabletenv.TabletConfig{ + DB: dbc, + SemiSyncMonitor: tabletenv.SemiSyncMonitorConfig{ + Interval: 100 * time.Millisecond, + }, + } + m := NewMonitor(config, exporter) + m.actionDelay = 10 * time.Millisecond + m.actionTimeout = 1 * time.Second defer func() { - waitBetweenWrites = initialVal + m.Close() + waitUntilWritingStopped(t, m) }() - db, m := createFakeDBAndMonitor(t) - defer db.Close() - defer m.Close() db.SetNeverFail(true) - // Initially everything is unblocked. - db.AddQuery(semiSyncWaitSessionsRead, sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_value", "varchar"), "0")) + + // Set up a custom query handler that returns different results based on state + handler := &statefulQueryHandler{ + db: db, + semiSyncStatsQuery: fmt.Sprintf(semiSyncStatsQuery, m.actionTimeout.Milliseconds()), + blockedResult: sqltypes.MakeTestResult( + sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), + "Rpl_semi_sync_source_wait_sessions|3", + "Rpl_semi_sync_source_yes_tx|3"), + unblockedResult: sqltypes.MakeTestResult( + sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), + "Rpl_semi_sync_source_wait_sessions|0", + "Rpl_semi_sync_source_yes_tx|0"), + } + handler.semisyncBlocked.Store(false) // Initially unblocked + db.Handler = handler + + // ExecuteFetchMulti will execute each statement separately + // Use patterns for both SET and INSERT since they can be called multiple times + db.AddQuery("SET SESSION lock_wait_timeout=1", &sqltypes.Result{}) + db.AddQuery("INSERT INTO _vt.semisync_heartbeat (ts) VALUES (NOW())", &sqltypes.Result{}) + + // Open the monitor so the periodic timer runs. + m.Open() // When everything is unblocked, then this should return without blocking. err := m.WaitUntilSemiSyncUnblocked(context.Background()) require.NoError(t, err) - // Add a universal insert query pattern that would block until we make it unblock. - ch := make(chan int) - db.AddQueryPatternWithCallback("^INSERT INTO.*", sqltypes.MakeTestResult(nil), func(s string) { - <-ch - }) - // Now we set the monitor to be blocked. - db.AddQuery(semiSyncWaitSessionsRead, sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_value", "varchar"), "3")) + // Now we set the monitor to be blocked by changing the state. + handler.semisyncBlocked.Store(true) + + // Wait until the writes have started. + require.Eventually(t, func() bool { + m.mu.Lock() + defer m.mu.Unlock() + // Check if we have any in-progress writes, which indicates writing has started. + return m.inProgressWriteCount > 0 || m.isWriting.Load() + }, 5*time.Second, 5*time.Microsecond) - // wg is used to keep track of all the go routines. wg := sync.WaitGroup{} // Start a cancellable context and use that to wait. ctx, cancel := context.WithCancel(context.Background()) @@ -579,13 +932,6 @@ func TestWaitUntilSemiSyncUnblocked(t *testing.T) { require.NoError(t, err) }() - // Wait until the writes have started. - require.Eventually(t, func() bool { - m.mu.Lock() - defer m.mu.Unlock() - return m.isWriting - }, 2*time.Second, 100*time.Millisecond) - // Now we cancel the context. This should fail the first wait. cancel() // Since we cancel the context before the semi-sync has been unblocked, we expect a context timeout error. @@ -598,9 +944,9 @@ func TestWaitUntilSemiSyncUnblocked(t *testing.T) { require.EqualError(t, ctxErr, "context canceled") mu.Unlock() - // Now we set the monitor to be unblocked. - db.AddQuery(semiSyncWaitSessionsRead, sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_value", "varchar"), "0")) - close(ch) + // Now we set the monitor to be unblocked by changing the state + handler.semisyncBlocked.Store(false) + err = m.WaitUntilSemiSyncUnblocked(context.Background()) require.NoError(t, err) // This should unblock the second wait. @@ -609,7 +955,7 @@ func TestWaitUntilSemiSyncUnblocked(t *testing.T) { require.Eventually(t, func() bool { m.mu.Lock() defer m.mu.Unlock() - return !m.isWriting + return !m.isWriting.Load() }, 2*time.Second, 100*time.Millisecond) // Also verify that if the monitor is closed, we don't wait. @@ -636,10 +982,12 @@ func TestDeadlockOnClose(t *testing.T) { }, } m := NewMonitor(config, exporter) + m.actionDelay = 10 * time.Millisecond + m.actionTimeout = 1 * time.Second // Set up for semisync to be blocked db.SetNeverFail(true) - db.AddQuery(semiSyncWaitSessionsRead, sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_value", "varchar"), "1")) + db.AddQuery(fmt.Sprintf(semiSyncStatsQuery, m.actionTimeout.Milliseconds()), sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), "Rpl_semi_sync_source_wait_sessions|1", "Rpl_semi_sync_source_yes_tx|1")) // Open the monitor m.Open() @@ -649,7 +997,7 @@ func TestDeadlockOnClose(t *testing.T) { finishCh := make(chan int) go func() { count := 100 - for i := 0; i < count; i++ { + for range count { m.Close() m.Open() time.Sleep(20 * time.Millisecond) @@ -669,11 +1017,7 @@ func TestDeadlockOnClose(t *testing.T) { // TestSemiSyncMonitor tests the semi-sync monitor as a black box. // It only calls the exported methods to see they work as intended. func TestSemiSyncMonitor(t *testing.T) { - initialVal := waitBetweenWrites - waitBetweenWrites = 250 * time.Millisecond - defer func() { - waitBetweenWrites = initialVal - }() + defer utils.EnsureNoLeaks(t) db := fakesqldb.New(t) defer db.Close() params := db.ConnParams() @@ -682,15 +1026,39 @@ func TestSemiSyncMonitor(t *testing.T) { config := &tabletenv.TabletConfig{ DB: dbc, SemiSyncMonitor: tabletenv.SemiSyncMonitorConfig{ - Interval: 1 * time.Second, + Interval: 100 * time.Millisecond, }, } m := NewMonitor(config, exporter) - defer m.Close() + m.actionDelay = 10 * time.Millisecond + m.actionTimeout = 1 * time.Second + defer func() { + m.Close() + waitUntilWritingStopped(t, m) + }() db.SetNeverFail(true) - // Initially everything is unblocked. - db.AddQuery(semiSyncWaitSessionsRead, sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_value", "varchar"), "0")) + + // Set up a custom query handler that returns different results based on state. + handler := &statefulQueryHandler{ + db: db, + semiSyncStatsQuery: fmt.Sprintf(semiSyncStatsQuery, m.actionDelay.Milliseconds()), + blockedResult: sqltypes.MakeTestResult( + sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), + "Rpl_semi_sync_source_wait_sessions|1", + "Rpl_semi_sync_source_yes_tx|1"), + unblockedResult: sqltypes.MakeTestResult( + sqltypes.MakeTestFields("variable_name|variable_value", "varchar|varchar"), + "Rpl_semi_sync_source_wait_sessions|0", + "Rpl_semi_sync_source_yes_tx|0"), + } + handler.semisyncBlocked.Store(false) // Initially unblocked + db.Handler = handler + + // ExecuteFetchMulti will execute each statement separately + // Use patterns for both SET and INSERT since they can be called multiple times. + db.AddQuery("SET SESSION lock_wait_timeout=1", &sqltypes.Result{}) + db.AddQuery("INSERT INTO _vt.semisync_heartbeat (ts) VALUES (NOW())", &sqltypes.Result{}) // Open the monitor. m.Open() @@ -702,15 +1070,14 @@ func TestSemiSyncMonitor(t *testing.T) { err := m.WaitUntilSemiSyncUnblocked(ctx) require.NoError(t, err) - // Add a universal insert query pattern that would block until we make it unblock. - ch := make(chan int) - db.AddQueryPatternWithCallback("^INSERT INTO.*", sqltypes.MakeTestResult(nil), func(s string) { - <-ch - }) - // Now we set the monitor to be blocked. - db.AddQuery(semiSyncWaitSessionsRead, sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_value", "varchar"), "1")) + // Test that WaitUntilSemiSyncUnblocked works correctly when the monitor starts returning unblocked. + // We don't need to test the blocking behavior in detail since TestWaitUntilSemiSyncUnblocked covers that. + // This test just verifies the basic black-box behavior. + + // Set to blocked state. + handler.semisyncBlocked.Store(true) - // Start a go routine waiting for semi-sync being unblocked. + // Start a waiter. var waitFinished atomic.Bool go func() { err := m.WaitUntilSemiSyncUnblocked(context.Background()) @@ -718,51 +1085,12 @@ func TestSemiSyncMonitor(t *testing.T) { waitFinished.Store(true) }() - // Even if we wait a second, the wait shouldn't be over. - time.Sleep(1 * time.Second) - require.False(t, waitFinished.Load()) + // Now unblock and verify the wait completes. + handler.semisyncBlocked.Store(false) - // If we unblock the semi-sync, then the wait should finish. - db.AddQuery(semiSyncWaitSessionsRead, sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_value", "varchar"), "0")) - close(ch) require.Eventually(t, func() bool { return waitFinished.Load() - }, 2*time.Second, 100*time.Millisecond) - require.False(t, m.AllWritesBlocked()) - - // Add a universal insert query pattern that would block until we make it unblock. - ch = make(chan int) - db.AddQueryPatternWithCallback("^INSERT INTO.*", sqltypes.MakeTestResult(nil), func(s string) { - <-ch - }) - // We block the semi-sync again. - db.AddQuery(semiSyncWaitSessionsRead, sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_value", "varchar"), "1")) - - // Start another go routine, also waiting for semi-sync being unblocked. - waitFinished.Store(false) - go func() { - err := m.WaitUntilSemiSyncUnblocked(context.Background()) - require.NoError(t, err) - waitFinished.Store(true) - }() - - // Since the writes are now blocking, eventually all the writes should block. - require.Eventually(t, func() bool { - return m.AllWritesBlocked() - }, 10*time.Second, 100*time.Millisecond) - - // The wait should still not have ended. - require.False(t, waitFinished.Load()) - - // Now we unblock the writes and semi-sync. - close(ch) - db.AddQuery(semiSyncWaitSessionsRead, sqltypes.MakeTestResult(sqltypes.MakeTestFields("variable_value", "varchar"), "0")) - - // The wait should now finish. - require.Eventually(t, func() bool { - return waitFinished.Load() - }, 2*time.Second, 100*time.Millisecond) - require.False(t, m.AllWritesBlocked()) + }, 5*time.Second, 100*time.Millisecond) // Close the monitor. m.Close() @@ -770,6 +1098,31 @@ func TestSemiSyncMonitor(t *testing.T) { require.Eventually(t, func() bool { m.mu.Lock() defer m.mu.Unlock() - return !m.isWriting + return !m.isWriting.Load() }, 2*time.Second, 100*time.Millisecond) } + +// waitUntilWritingStopped is a utility functions that waits until all the go-routines of a semi-sync monitor +// have stopped. This is useful to prevent data-race errors. After a monitor has been closed, it stops writing +// in the next check of stillBlocked. +func waitUntilWritingStopped(t *testing.T, m *Monitor) { + t.Helper() + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + tick := time.NewTicker(100 * time.Millisecond) + defer tick.Stop() + + for { + select { + case <-ctx.Done(): + t.Fatalf("Timed out waiting for writing to stop: %v", ctx.Err()) + case <-tick.C: + m.mu.Lock() + if !m.isWriting.Load() { + m.mu.Unlock() + return + } + m.mu.Unlock() + } + } +} From 50d8e96de6071e4659e6dbf154e2108463aec172 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Tue, 18 Nov 2025 20:22:39 +0100 Subject: [PATCH 003/112] [release-22.0] Bump js-yaml from 4.1.0 to 4.1.1 in /web/vtadmin (#18908) (#18910) Signed-off-by: dependabot[bot] Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/vtadmin/package-lock.json | 306 ++++++++++++++++++++++++++++++---- 1 file changed, 278 insertions(+), 28 deletions(-) diff --git a/web/vtadmin/package-lock.json b/web/vtadmin/package-lock.json index dcaf7ed30f6..9389ca92e36 100644 --- a/web/vtadmin/package-lock.json +++ b/web/vtadmin/package-lock.json @@ -123,6 +123,7 @@ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -712,6 +713,7 @@ "integrity": "sha512-B+O2DnPc0iG+YXFqOxv2WNuNU97ToWjOomUQ78DouOENWUaM5sVrmet9mcomUGQFwpJd//gvUagXBSdzO1fRKg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -1520,6 +1522,7 @@ "integrity": "sha512-s5XwpQYCqGerXl+Pu6VDL3x0j2d82eiV77UJ8a2mDHAW7j9SWRqQ2y1fNo1Z74CdcYipl5Z41zvjj4Nfzq36rw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "@babel/helper-module-imports": "^7.25.9", @@ -2244,6 +2247,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": "^14 || ^16 || >=18" }, @@ -2266,6 +2270,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": "^14 || ^16 || >=18" } @@ -3868,6 +3873,26 @@ "@parcel/watcher-win32-x64": "2.5.0" } }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.0.tgz", + "integrity": "sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/@parcel/watcher-darwin-arm64": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.0.tgz", @@ -3888,6 +3913,226 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.0.tgz", + "integrity": "sha512-9rhlwd78saKf18fT869/poydQK8YqlU26TMiNg7AIu7eBp9adqbJZqmdFOsbZ5cnLp5XvRo9wcFmNHgHdWaGYA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.0.tgz", + "integrity": "sha512-syvfhZzyM8kErg3VF0xpV8dixJ+RzbUaaGaeb7uDuz0D3FK97/mZ5AJQ3XNnDsXX7KkFNtyQyFrXZzQIcN49Tw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.0.tgz", + "integrity": "sha512-0VQY1K35DQET3dVYWpOaPFecqOT9dbuCfzjxoQyif1Wc574t3kOSkKevULddcR9znz1TcklCE7Ht6NIxjvTqLA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.0.tgz", + "integrity": "sha512-6uHywSIzz8+vi2lAzFeltnYbdHsDm3iIB57d4g5oaB9vKwjb6N6dRIgZMujw4nm5r6v9/BQH0noq6DzHrqr2pA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.0.tgz", + "integrity": "sha512-BfNjXwZKxBy4WibDb/LDCriWSKLz+jJRL3cM/DllnHH5QUyoiUNEp3GmL80ZqxeumoADfCCP19+qiYiC8gUBjA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.0.tgz", + "integrity": "sha512-S1qARKOphxfiBEkwLUbHjCY9BWPdWnW9j7f7Hb2jPplu8UZ3nes7zpPOW9bkLbHRvWM0WDTsjdOTUgW0xLBN1Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.0.tgz", + "integrity": "sha512-d9AOkusyXARkFD66S6zlGXyzx5RvY+chTP9Jp0ypSTC9d4lzyRs9ovGf/80VCxjKddcUvnsGwCHWuF2EoPgWjw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.0.tgz", + "integrity": "sha512-iqOC+GoTDoFyk/VYSFHwjHhYrk8bljW6zOhPuhi5t9ulqiYq1togGJB5e3PwYVFFfeVgc6pbz3JdQyDoBszVaA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.0.tgz", + "integrity": "sha512-twtft1d+JRNkM5YbmexfcH/N4znDtjgysFaV9zvZmmJezQsKpkfLYJ+JFV3uygugK6AtIM2oADPkB2AdhBrNig==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.0.tgz", + "integrity": "sha512-+rgpsNRKwo8A53elqbbHXdOMtY/tAtTzManTWShB5Kk54N8Q9mzNWV7tV+IbGueCbcj826MfWGU3mprWtuf1TA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.0.tgz", + "integrity": "sha512-lPrxve92zEHdgeff3aiu4gDOIt4u7sJYha6wbdEZDCDUhtjTsOMiaJzG5lMY4GkWH8p0fMmO2Ppq5G5XXG+DQw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -3904,32 +4149,28 @@ "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", "dev": true, - "license": "BSD-3-Clause", - "peer": true + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/base64": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", "dev": true, - "license": "BSD-3-Clause", - "peer": true + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/codegen": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", "dev": true, - "license": "BSD-3-Clause", - "peer": true + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", "dev": true, - "license": "BSD-3-Clause", - "peer": true + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/fetch": { "version": "1.1.0", @@ -3937,7 +4178,6 @@ "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -3948,40 +4188,35 @@ "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", "dev": true, - "license": "BSD-3-Clause", - "peer": true + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", "dev": true, - "license": "BSD-3-Clause", - "peer": true + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", "dev": true, - "license": "BSD-3-Clause", - "peer": true + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", "dev": true, - "license": "BSD-3-Clause", - "peer": true + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", "dev": true, - "license": "BSD-3-Clause", - "peer": true + "license": "BSD-3-Clause" }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-beta.43", @@ -4893,8 +5128,7 @@ "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@types/babel__core": { "version": "7.20.5", @@ -5358,6 +5592,7 @@ "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/linkify-it": "^5", "@types/mdurl": "^2" @@ -5382,6 +5617,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.1.tgz", "integrity": "sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg==", "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -5411,6 +5647,7 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz", "integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==", "license": "MIT", + "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -5589,6 +5826,7 @@ "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "5.62.0", "@typescript-eslint/types": "5.62.0", @@ -5927,6 +6165,7 @@ "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -6684,6 +6923,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001688", "electron-to-chromium": "^1.5.73", @@ -7826,6 +8066,7 @@ "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", "license": "ISC", + "peer": true, "engines": { "node": ">=12" } @@ -8662,6 +8903,7 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -10960,9 +11202,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", "dependencies": { @@ -11028,6 +11270,7 @@ "integrity": "sha512-sCpFmK2jv+1sjff4u7fzft+pUh2KSUbUrEHYHyfSIbGTIcmnjyp83qg6qLwdJ/I3LpTXx33ACxeRL7Lsyc6lGQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "abab": "^2.0.6", "acorn": "^8.8.2", @@ -11294,8 +11537,7 @@ "resolved": "https://registry.npmjs.org/long/-/long-5.2.4.tgz", "integrity": "sha512-qtzLbJE8hq7VabR3mISmVGtoXP8KGc2Z/AT8OuqlYD7JTR3oqrgwdjnk07wpj1twXxYmgDXgoKVWUG/fReSzHg==", "dev": true, - "license": "Apache-2.0", - "peer": true + "license": "Apache-2.0" }, "node_modules/loose-envify": { "version": "1.4.0", @@ -11368,6 +11610,7 @@ "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", @@ -15182,6 +15425,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -15976,6 +16220,7 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "license": "MIT", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -16022,7 +16267,6 @@ "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -16038,7 +16282,6 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -16358,6 +16601,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -16383,6 +16627,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -17065,6 +17310,7 @@ "integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -17225,6 +17471,7 @@ "resolved": "https://registry.npmjs.org/sass/-/sass-1.83.4.tgz", "integrity": "sha512-B1bozCeNQiOgDcLd33e2Cs2U60wZwjUUXzh900ZyQF5qUasvMdDZYbQ566LJu7cqR+sAHlAfO6RMkaID5s6qpA==", "license": "MIT", + "peer": true, "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.0.2", @@ -18014,6 +18261,7 @@ "integrity": "sha512-ErlzR/T3hhbV+a925/gbfc3f3Fep9/bnspMiJPorfGEmcBbXdS+oo6LrVtoUZ/w9fqD6o6k7PtUlCOsCRdjX/A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@csstools/selector-specificity": "^2.0.2", "balanced-match": "^2.0.0", @@ -18834,6 +19082,7 @@ "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -19066,6 +19315,7 @@ "integrity": "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", From d7c515648d85e724080e6e6ee997c7f32c5dbbf0 Mon Sep 17 00:00:00 2001 From: vitess-go-upgrade-bot <139342327+vitess-bot@users.noreply.github.com> Date: Wed, 19 Nov 2025 22:30:42 +0100 Subject: [PATCH 004/112] [release-22.0] Upgrade the Golang version to `go1.24.10` (#18897) Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Signed-off-by: Matt Lord Co-authored-by: frouioui <35779988+frouioui@users.noreply.github.com> Co-authored-by: Matt Lord --- .../upgrade_downgrade_test_backups_e2e.yml | 2 +- .../upgrade_downgrade_test_backups_manual.yml | 2 +- .../upgrade_downgrade_test_onlineddl_flow.yml | 2 +- ...e_downgrade_test_query_serving_queries.yml | 2 +- ...downgrade_test_query_serving_queries_2.yml | 2 +- ...de_downgrade_test_query_serving_schema.yml | 2 +- ...rade_downgrade_test_reparent_old_vtctl.yml | 2 +- ...e_downgrade_test_reparent_old_vttablet.yml | 2 +- .../upgrade_downgrade_test_semi_sync.yml | 2 +- Makefile | 2 +- build.env | 2 +- docker/bootstrap/CHANGELOG.md | 6 +- docker/bootstrap/Dockerfile.common | 2 +- docker/lite/Dockerfile | 2 +- docker/lite/Dockerfile.mysql84 | 2 +- docker/lite/Dockerfile.percona80 | 2 +- docker/vttestserver/Dockerfile.mysql80 | 2 +- docker/vttestserver/Dockerfile.mysql84 | 2 +- go.mod | 2 +- test.go | 2 +- test/templates/dockerfile.tpl | 2 +- web/vtadmin/package-lock.json | 60 ++++++++----------- 22 files changed, 50 insertions(+), 56 deletions(-) diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml index 3e447c90889..a7e3470bdac 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml @@ -66,7 +66,7 @@ jobs: if: steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: - go-version: 1.24.9 + go-version: 1.24.10 - name: Set up python if: steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual.yml b/.github/workflows/upgrade_downgrade_test_backups_manual.yml index 9b8a455735b..1924b29e346 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_manual.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_manual.yml @@ -70,7 +70,7 @@ jobs: if: steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: - go-version: 1.24.9 + go-version: 1.24.10 - name: Set up python if: steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml b/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml index 6bf54b26716..d761baa1d1d 100644 --- a/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml +++ b/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml @@ -77,7 +77,7 @@ jobs: if: steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: - go-version: 1.24.9 + go-version: 1.24.10 - name: Set up python if: steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml index a7793d4bcc4..24276f775df 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml @@ -70,7 +70,7 @@ jobs: if: steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: - go-version: 1.24.9 + go-version: 1.24.10 - name: Set up python if: steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml index cddfb84b53d..0fe3324aaec 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml @@ -70,7 +70,7 @@ jobs: if: steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: - go-version: 1.24.9 + go-version: 1.24.10 - name: Set up python if: steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml index 480e64118ec..ecef80ea242 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml @@ -70,7 +70,7 @@ jobs: if: steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: - go-version: 1.24.9 + go-version: 1.24.10 - name: Set up python if: steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml b/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml index a0728bb8ede..6d319154c42 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml @@ -70,7 +70,7 @@ jobs: if: steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: - go-version: 1.24.9 + go-version: 1.24.10 - name: Set up python if: steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml b/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml index 03c7fa98305..28bba9b7fab 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml @@ -70,7 +70,7 @@ jobs: if: steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: - go-version: 1.24.9 + go-version: 1.24.10 - name: Set up python if: steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_semi_sync.yml b/.github/workflows/upgrade_downgrade_test_semi_sync.yml index 57db71b67c0..127bce0d8dc 100644 --- a/.github/workflows/upgrade_downgrade_test_semi_sync.yml +++ b/.github/workflows/upgrade_downgrade_test_semi_sync.yml @@ -66,7 +66,7 @@ jobs: if: steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: - go-version: 1.24.9 + go-version: 1.24.10 - name: Set up python if: steps.changes.outputs.end_to_end == 'true' diff --git a/Makefile b/Makefile index 6c4bbc0e8a4..1ddba949b1e 100644 --- a/Makefile +++ b/Makefile @@ -286,7 +286,7 @@ $(PROTO_GO_OUTS): minimaltools install_protoc-gen-go proto/*.proto # This rule builds the bootstrap images for all flavors. DOCKER_IMAGES_FOR_TEST = mysql80 mysql84 percona80 DOCKER_IMAGES = common $(DOCKER_IMAGES_FOR_TEST) -BOOTSTRAP_VERSION=43.4 +BOOTSTRAP_VERSION=43.5 ensure_bootstrap_version: find docker/ -type f -exec sed -i "s/^\(ARG bootstrap_version\)=.*/\1=${BOOTSTRAP_VERSION}/" {} \; sed -i 's/\(^.*flag.String(\"bootstrap-version\",\) *\"[^\"]\+\"/\1 \"${BOOTSTRAP_VERSION}\"/' test.go diff --git a/build.env b/build.env index 5fc619c5c3a..05998eb420f 100755 --- a/build.env +++ b/build.env @@ -17,7 +17,7 @@ source ./tools/shell_functions.inc go version >/dev/null 2>&1 || fail "Go is not installed or is not in \$PATH. See https://vitess.io/contributing/build-from-source for install instructions." -goversion_min 1.24.9 || echo "Go version reported: `go version`. Version 1.24.9+ recommended. See https://vitess.io/contributing/build-from-source for install instructions." +goversion_min 1.24.10 || echo "Go version reported: `go version`. Version 1.24.10+ recommended. See https://vitess.io/contributing/build-from-source for install instructions." mkdir -p dist mkdir -p bin diff --git a/docker/bootstrap/CHANGELOG.md b/docker/bootstrap/CHANGELOG.md index eda93b5f787..2275c4a5163 100644 --- a/docker/bootstrap/CHANGELOG.md +++ b/docker/bootstrap/CHANGELOG.md @@ -190,4 +190,8 @@ List of changes between bootstrap image versions. ## [43.4] - 2025-10-14 ### Changes -- Update build to golang 1.24.9 \ No newline at end of file +- Update build to golang 1.24.9 + +## [43.5] - 2025-11-12 +### Changes +- Update build to golang 1.24.10 \ No newline at end of file diff --git a/docker/bootstrap/Dockerfile.common b/docker/bootstrap/Dockerfile.common index 462fcbb9d5c..e112119f836 100644 --- a/docker/bootstrap/Dockerfile.common +++ b/docker/bootstrap/Dockerfile.common @@ -1,4 +1,4 @@ -FROM --platform=linux/amd64 golang:1.24.9-bookworm +FROM --platform=linux/amd64 golang:1.24.10-bookworm # Install Vitess build dependencies RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ diff --git a/docker/lite/Dockerfile b/docker/lite/Dockerfile index a65f325a5eb..074097ddb2e 100644 --- a/docker/lite/Dockerfile +++ b/docker/lite/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.24.9-bookworm AS builder +FROM --platform=linux/amd64 golang:1.24.10-bookworm AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER diff --git a/docker/lite/Dockerfile.mysql84 b/docker/lite/Dockerfile.mysql84 index f2773a27b91..ca7c0913534 100644 --- a/docker/lite/Dockerfile.mysql84 +++ b/docker/lite/Dockerfile.mysql84 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.24.9-bookworm AS builder +FROM --platform=linux/amd64 golang:1.24.10-bookworm AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER diff --git a/docker/lite/Dockerfile.percona80 b/docker/lite/Dockerfile.percona80 index 28e754e3c5a..46a4cb80a3e 100644 --- a/docker/lite/Dockerfile.percona80 +++ b/docker/lite/Dockerfile.percona80 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.24.9-bookworm AS builder +FROM --platform=linux/amd64 golang:1.24.10-bookworm AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER diff --git a/docker/vttestserver/Dockerfile.mysql80 b/docker/vttestserver/Dockerfile.mysql80 index 6af81a304cd..2e25dc6f0bc 100644 --- a/docker/vttestserver/Dockerfile.mysql80 +++ b/docker/vttestserver/Dockerfile.mysql80 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.24.9-bookworm AS builder +FROM --platform=linux/amd64 golang:1.24.10-bookworm AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER diff --git a/docker/vttestserver/Dockerfile.mysql84 b/docker/vttestserver/Dockerfile.mysql84 index 6c7ff974067..6fe1326147a 100644 --- a/docker/vttestserver/Dockerfile.mysql84 +++ b/docker/vttestserver/Dockerfile.mysql84 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.24.9-bookworm AS builder +FROM --platform=linux/amd64 golang:1.24.10-bookworm AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER diff --git a/go.mod b/go.mod index 81d049b16ee..6313963225b 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module vitess.io/vitess -go 1.24.9 +go 1.24.10 require ( cloud.google.com/go/storage v1.51.0 diff --git a/test.go b/test.go index b9c73804862..a61861890ae 100755 --- a/test.go +++ b/test.go @@ -77,7 +77,7 @@ For example: // Flags var ( flavor = flag.String("flavor", "mysql80", "comma-separated bootstrap flavor(s) to run against (when using Docker mode). Available flavors: all,"+flavors) - bootstrapVersion = flag.String("bootstrap-version", "43.4", "the version identifier to use for the docker images") + bootstrapVersion = flag.String("bootstrap-version", "43.5", "the version identifier to use for the docker images") runCount = flag.Int("runs", 1, "run each test this many times") retryMax = flag.Int("retry", 3, "max number of retries, to detect flaky tests") logPass = flag.Bool("log-pass", false, "log test output even if it passes") diff --git a/test/templates/dockerfile.tpl b/test/templates/dockerfile.tpl index 813f7f9420a..3f0afe39e1b 100644 --- a/test/templates/dockerfile.tpl +++ b/test/templates/dockerfile.tpl @@ -1,4 +1,4 @@ -ARG bootstrap_version=43.4 +ARG bootstrap_version=43.5 ARG image="vitess/bootstrap:${bootstrap_version}-{{.Platform}}" FROM "${image}" diff --git a/web/vtadmin/package-lock.json b/web/vtadmin/package-lock.json index 9389ca92e36..05a8472cad6 100644 --- a/web/vtadmin/package-lock.json +++ b/web/vtadmin/package-lock.json @@ -123,7 +123,6 @@ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -713,7 +712,6 @@ "integrity": "sha512-B+O2DnPc0iG+YXFqOxv2WNuNU97ToWjOomUQ78DouOENWUaM5sVrmet9mcomUGQFwpJd//gvUagXBSdzO1fRKg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -1522,7 +1520,6 @@ "integrity": "sha512-s5XwpQYCqGerXl+Pu6VDL3x0j2d82eiV77UJ8a2mDHAW7j9SWRqQ2y1fNo1Z74CdcYipl5Z41zvjj4Nfzq36rw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "@babel/helper-module-imports": "^7.25.9", @@ -2247,7 +2244,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": "^14 || ^16 || >=18" }, @@ -2270,7 +2266,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": "^14 || ^16 || >=18" } @@ -4149,28 +4144,32 @@ "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "peer": true }, "node_modules/@protobufjs/base64": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "peer": true }, "node_modules/@protobufjs/codegen": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "peer": true }, "node_modules/@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "peer": true }, "node_modules/@protobufjs/fetch": { "version": "1.1.0", @@ -4178,6 +4177,7 @@ "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", "dev": true, "license": "BSD-3-Clause", + "peer": true, "dependencies": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -4188,35 +4188,40 @@ "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "peer": true }, "node_modules/@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "peer": true }, "node_modules/@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "peer": true }, "node_modules/@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "peer": true }, "node_modules/@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "peer": true }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-beta.43", @@ -5128,7 +5133,8 @@ "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/babel__core": { "version": "7.20.5", @@ -5592,7 +5598,6 @@ "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/linkify-it": "^5", "@types/mdurl": "^2" @@ -5617,7 +5622,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.1.tgz", "integrity": "sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg==", "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -5647,7 +5651,6 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz", "integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==", "license": "MIT", - "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -5826,7 +5829,6 @@ "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "5.62.0", "@typescript-eslint/types": "5.62.0", @@ -6165,7 +6167,6 @@ "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -6923,7 +6924,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001688", "electron-to-chromium": "^1.5.73", @@ -8066,7 +8066,6 @@ "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", "license": "ISC", - "peer": true, "engines": { "node": ">=12" } @@ -8903,7 +8902,6 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -11270,7 +11268,6 @@ "integrity": "sha512-sCpFmK2jv+1sjff4u7fzft+pUh2KSUbUrEHYHyfSIbGTIcmnjyp83qg6qLwdJ/I3LpTXx33ACxeRL7Lsyc6lGQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "abab": "^2.0.6", "acorn": "^8.8.2", @@ -11537,7 +11534,8 @@ "resolved": "https://registry.npmjs.org/long/-/long-5.2.4.tgz", "integrity": "sha512-qtzLbJE8hq7VabR3mISmVGtoXP8KGc2Z/AT8OuqlYD7JTR3oqrgwdjnk07wpj1twXxYmgDXgoKVWUG/fReSzHg==", "dev": true, - "license": "Apache-2.0" + "license": "Apache-2.0", + "peer": true }, "node_modules/loose-envify": { "version": "1.4.0", @@ -11610,7 +11608,6 @@ "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", @@ -15425,7 +15422,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -16220,7 +16216,6 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -16267,6 +16262,7 @@ "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -16282,6 +16278,7 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=10" }, @@ -16601,7 +16598,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -16627,7 +16623,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -17310,7 +17305,6 @@ "integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -17471,7 +17465,6 @@ "resolved": "https://registry.npmjs.org/sass/-/sass-1.83.4.tgz", "integrity": "sha512-B1bozCeNQiOgDcLd33e2Cs2U60wZwjUUXzh900ZyQF5qUasvMdDZYbQ566LJu7cqR+sAHlAfO6RMkaID5s6qpA==", "license": "MIT", - "peer": true, "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.0.2", @@ -18261,7 +18254,6 @@ "integrity": "sha512-ErlzR/T3hhbV+a925/gbfc3f3Fep9/bnspMiJPorfGEmcBbXdS+oo6LrVtoUZ/w9fqD6o6k7PtUlCOsCRdjX/A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@csstools/selector-specificity": "^2.0.2", "balanced-match": "^2.0.0", @@ -19082,7 +19074,6 @@ "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -19315,7 +19306,6 @@ "integrity": "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", From cf02e5f94921eba8c3f5ab326fe380739dab9f4a Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Thu, 20 Nov 2025 15:22:41 +0000 Subject: [PATCH 005/112] [release-22.0] `vtbench`: add `--db-credentials-*` flags (#18913) (#18921) Signed-off-by: Tim Vaillancourt Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- go/flags/endtoend/vtbench.txt | 11 +++++++++++ go/vt/dbconfigs/credentials.go | 1 + 2 files changed, 12 insertions(+) diff --git a/go/flags/endtoend/vtbench.txt b/go/flags/endtoend/vtbench.txt index 7b0d72af429..616f873c294 100644 --- a/go/flags/endtoend/vtbench.txt +++ b/go/flags/endtoend/vtbench.txt @@ -50,6 +50,17 @@ Flags: --config-type string Config file type (omit to infer config type from file extension). --count int Number of queries per thread (default 1000) --db string Database name to use when connecting / running the queries (e.g. @replica, keyspace, keyspace/shard etc) + --db-credentials-file string db credentials file; send SIGHUP to reload this file + --db-credentials-server string db credentials server type ('file' - file implementation; 'vault' - HashiCorp Vault implementation) (default "file") + --db-credentials-vault-addr string URL to Vault server + --db-credentials-vault-path string Vault path to credentials JSON blob, e.g.: secret/data/prod/dbcreds + --db-credentials-vault-role-mountpoint string Vault AppRole mountpoint; can also be passed using VAULT_MOUNTPOINT environment variable (default "approle") + --db-credentials-vault-role-secretidfile string Path to file containing Vault AppRole secret_id; can also be passed using VAULT_SECRETID environment variable + --db-credentials-vault-roleid string Vault AppRole id; can also be passed using VAULT_ROLEID environment variable + --db-credentials-vault-timeout duration Timeout for vault API operations (default 10s) + --db-credentials-vault-tls-ca string Path to CA PEM for validating Vault server certificate + --db-credentials-vault-tokenfile string Path to file containing Vault auth token; token can also be passed using VAULT_TOKEN environment variable + --db-credentials-vault-ttl duration How long to cache DB credentials from the Vault server (default 30m0s) --deadline duration Maximum duration for the test run (default 5 minutes) (default 5m0s) --grpc_auth_static_client_creds string When using grpc_static_auth in the server, this file provides the credentials to use to authenticate with server. --grpc_compression string Which protocol to use for compressing gRPC. Default: nothing. Supported: snappy diff --git a/go/vt/dbconfigs/credentials.go b/go/vt/dbconfigs/credentials.go index f7082738c5e..ecc094b9cc0 100644 --- a/go/vt/dbconfigs/credentials.go +++ b/go/vt/dbconfigs/credentials.go @@ -60,6 +60,7 @@ var ( "mysqlctl", "mysqlctld", "vtbackup", + "vtbench", "vtcombo", "vttablet", } From bff37253b236f2a54ed892f0cc207eae0a97a4b7 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Sat, 22 Nov 2025 07:24:54 +0700 Subject: [PATCH 006/112] [release-22.0] Properly Strip Keyspace Table Qualifiers in FK Constraints (#18926) (#18934) Signed-off-by: Matt Lord Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Matt Lord --- go/test/endtoend/vtgate/foreignkey/fk_test.go | 42 +++++++- go/vt/vtgate/planbuilder/ddl.go | 2 + .../planbuilder/testdata/ddl_cases.json | 100 ++++++++++++++++++ 3 files changed, 143 insertions(+), 1 deletion(-) diff --git a/go/test/endtoend/vtgate/foreignkey/fk_test.go b/go/test/endtoend/vtgate/foreignkey/fk_test.go index bdbd0f1ad84..b30cb0308d3 100644 --- a/go/test/endtoend/vtgate/foreignkey/fk_test.go +++ b/go/test/endtoend/vtgate/foreignkey/fk_test.go @@ -30,9 +30,10 @@ import ( "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/utils" "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/vtgate/vtgateconn" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" - "vitess.io/vitess/go/vt/vtgate/vtgateconn" ) // TestInsertWithFK tests that insertions work as expected when foreign key management is enabled in Vitess. @@ -1504,3 +1505,42 @@ create table temp2(id bigint auto_increment primary key, col varchar(20) not nul mcmp.Exec(`insert into temp1(col) values('a') `) mcmp.ExecAllowAndCompareError(`insert into temp1(col) values('d') `, utils.CompareOptions{}) } + +// TestForeignKeyWithKeyspaceQualifier tests that CREATE TABLE with foreign key references +// that include keyspace qualifiers work correctly. This addresses bug #18889 where keyspace +// names were not being stripped before being sent to MySQL, causing failures because MySQL +// expects database names (vt_) not keyspace names. +func TestForeignKeyWithKeyspaceQualifier(t *testing.T) { + mcmp, closer := start(t) + defer closer() + + utils.Exec(t, mcmp.VtConn, `use uks`) + + // Create the parent table. + utils.Exec(t, mcmp.VtConn, `create table fk_parent(id bigint primary key)`) + + // Create the child table with keyspace-qualified foreign key reference. + utils.Exec(t, mcmp.VtConn, `create table fk_child(id bigint primary key, parent_id bigint, foreign key (parent_id) references uks.fk_parent(id))`) + + // Verify that the foreign key constraint works. + utils.Exec(t, mcmp.VtConn, `insert into fk_parent(id) values (1), (2)`) + utils.Exec(t, mcmp.VtConn, `insert into fk_child(id, parent_id) values (100, 1)`) + + // This should fail due to FK constraint. + _, err := utils.ExecAllowError(t, mcmp.VtConn, `insert into fk_child(id, parent_id) values (101, 999)`) + assert.ErrorContains(t, err, "Cannot add or update a child row: a foreign key constraint fails") + + // Test ALTER TABLE with keyspace-qualified foreign key. + utils.Exec(t, mcmp.VtConn, `create table fk_child2(id bigint primary key, parent_id bigint)`) + utils.Exec(t, mcmp.VtConn, `alter table fk_child2 add foreign key (parent_id) references uks.fk_parent(id)`) + + // Verify the constraint works for the altered table. + utils.Exec(t, mcmp.VtConn, `insert into fk_child2(id, parent_id) values (200, 2)`) + _, err = utils.ExecAllowError(t, mcmp.VtConn, `insert into fk_child2(id, parent_id) values (201, 888)`) + assert.ErrorContains(t, err, "Cannot add or update a child row: a foreign key constraint fails") + + // Clean up. + utils.Exec(t, mcmp.VtConn, `drop table fk_child`) + utils.Exec(t, mcmp.VtConn, `drop table fk_child2`) + utils.Exec(t, mcmp.VtConn, `drop table fk_parent`) +} diff --git a/go/vt/vtgate/planbuilder/ddl.go b/go/vt/vtgate/planbuilder/ddl.go index 4804011f240..b670e0e28dc 100644 --- a/go/vt/vtgate/planbuilder/ddl.go +++ b/go/vt/vtgate/planbuilder/ddl.go @@ -109,6 +109,8 @@ func buildDDLPlans(ctx context.Context, sql string, ddlStatement sqlparser.DDLSt if err != nil { return nil, nil, err } + // Remove keyspace qualifiers from all table references (including foreign key references). + sqlparser.RemoveSpecificKeyspace(ddlStatement, keyspace.Name) err = checkFKError(vschema, ddlStatement, keyspace) case *sqlparser.CreateView: destination, keyspace, err = buildCreateViewCommon(ctx, vschema, reservedVars, cfg, ddl.Select, ddl) diff --git a/go/vt/vtgate/planbuilder/testdata/ddl_cases.json b/go/vt/vtgate/planbuilder/testdata/ddl_cases.json index 3b84004ca99..b51de04ff47 100644 --- a/go/vt/vtgate/planbuilder/testdata/ddl_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/ddl_cases.json @@ -683,5 +683,105 @@ "main.function_default" ] } + }, + { + "comment": "create table with foreign key reference without keyspace qualifier", + "query": "create table t1(id bigint, t2_id bigint, primary key(id), foreign key (t2_id) references t2(id))", + "plan": { + "Type": "DirectDDL", + "QueryType": "DDL", + "Original": "create table t1(id bigint, t2_id bigint, primary key(id), foreign key (t2_id) references t2(id))", + "Instructions": { + "OperatorType": "DDL", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "Query": "create table t1 (\n\tid bigint,\n\tt2_id bigint,\n\tprimary key (id),\n\tforeign key (t2_id) references t2 (id)\n)" + }, + "TablesUsed": [ + "main.t1" + ] + } + }, + { + "comment": "create table with foreign key reference with keyspace qualifier", + "query": "create table user.t1(id bigint, t2_id bigint, primary key(id), foreign key (t2_id) references user.t2(id))", + "plan": { + "Type": "DirectDDL", + "QueryType": "DDL", + "Original": "create table user.t1(id bigint, t2_id bigint, primary key(id), foreign key (t2_id) references user.t2(id))", + "Instructions": { + "OperatorType": "DDL", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "Query": "create table t1 (\n\tid bigint,\n\tt2_id bigint,\n\tprimary key (id),\n\tforeign key (t2_id) references t2 (id)\n)" + }, + "TablesUsed": [ + "user.t1" + ] + } + }, + { + "comment": "create table with multiple foreign keys with keyspace qualifiers", + "query": "create table user.orders(order_id bigint, customer_id bigint, product_id bigint, primary key(order_id), foreign key (customer_id) references user.customers(id), foreign key (product_id) references user.products(id))", + "plan": { + "Type": "DirectDDL", + "QueryType": "DDL", + "Original": "create table user.orders(order_id bigint, customer_id bigint, product_id bigint, primary key(order_id), foreign key (customer_id) references user.customers(id), foreign key (product_id) references user.products(id))", + "Instructions": { + "OperatorType": "DDL", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "Query": "create table orders (\n\torder_id bigint,\n\tcustomer_id bigint,\n\tproduct_id bigint,\n\tprimary key (order_id),\n\tforeign key (customer_id) references customers (id),\n\tforeign key (product_id) references products (id)\n)" + }, + "TablesUsed": [ + "user.orders" + ] + } + }, + { + "comment": "alter table add foreign key with keyspace qualifier", + "query": "alter table user.t1 add foreign key (t2_id) references user.t2(id)", + "plan": { + "Type": "DirectDDL", + "QueryType": "DDL", + "Original": "alter table user.t1 add foreign key (t2_id) references user.t2(id)", + "Instructions": { + "OperatorType": "DDL", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "Query": "alter table t1 add foreign key (t2_id) references t2 (id)" + }, + "TablesUsed": [ + "user.t1" + ] + } + }, + { + "comment": "create table with foreign key with ON DELETE and ON UPDATE clauses and keyspace qualifier", + "query": "create table user.employees(emp_id bigint, dept_id bigint, primary key(emp_id), foreign key (dept_id) references user.departments(dept_id) on delete set null on update cascade)", + "plan": { + "Type": "DirectDDL", + "QueryType": "DDL", + "Original": "create table user.employees(emp_id bigint, dept_id bigint, primary key(emp_id), foreign key (dept_id) references user.departments(dept_id) on delete set null on update cascade)", + "Instructions": { + "OperatorType": "DDL", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "Query": "create table employees (\n\temp_id bigint,\n\tdept_id bigint,\n\tprimary key (emp_id),\n\tforeign key (dept_id) references departments (dept_id) on delete set null on update cascade\n)" + }, + "TablesUsed": [ + "user.employees" + ] + } } ] From a349b132c6f948ce6eef9e941238f848a4f4932c Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Sun, 23 Nov 2025 21:19:53 -0500 Subject: [PATCH 007/112] [release-22.0] Stop using Equinix Metal self hosted runners (#18942) (#18943) Signed-off-by: Matt Lord Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- .github/workflows/vtop_example.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/vtop_example.yml b/.github/workflows/vtop_example.yml index 49eba9909bd..feb347a886f 100644 --- a/.github/workflows/vtop_example.yml +++ b/.github/workflows/vtop_example.yml @@ -14,7 +14,7 @@ concurrency: jobs: build: name: VTop Example - runs-on: self-hosted + runs-on: oracle-vm-8cpu-32gb-x86-64 steps: - name: Skip CI @@ -60,6 +60,12 @@ jobs: if: steps.changes.outputs.end_to_end == 'true' uses: ./.github/actions/tune-os + - name: Setup MySQL + if: steps.changes.outputs.end_to_end == 'true' + uses: ./.github/actions/setup-mysql + with: + flavor: mysql-8.4 + - name: Get dependencies if: steps.changes.outputs.end_to_end == 'true' run: | @@ -83,4 +89,4 @@ jobs: timeout-minutes: 60 run: | source build.env - go run test.go -docker=false -skip-build -print-log -follow -retry=1 -timeout=60m vtop_example \ No newline at end of file + go run test.go -docker=false -skip-build -print-log -follow -retry=1 -timeout=60m vtop_example From 2bb2897ac26ac7a101096b589c31bdb26f38873c Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Fri, 28 Nov 2025 18:06:28 +0100 Subject: [PATCH 008/112] [release-22.0] Drop dependency on `npm`, bump version of `glob`. (#18931) (#18957) Signed-off-by: Arthur Schreiber Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- web/vtadmin/package-lock.json | 2768 +-------------------------------- web/vtadmin/package.json | 1 - 2 files changed, 3 insertions(+), 2766 deletions(-) diff --git a/web/vtadmin/package-lock.json b/web/vtadmin/package-lock.json index 05a8472cad6..339e08d229d 100644 --- a/web/vtadmin/package-lock.json +++ b/web/vtadmin/package-lock.json @@ -53,7 +53,6 @@ "i": "^0.3.7", "jsdom": "^21.1.1", "msw": "^2.5.2", - "npm": "^10.9.2", "postcss": "^8.4.31", "prettier": "^2.2.1", "protobufjs-cli": "^1.1.3", @@ -12159,167 +12158,6 @@ "node": ">=0.10.0" } }, - "node_modules/npm": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/npm/-/npm-10.9.2.tgz", - "integrity": "sha512-iriPEPIkoMYUy3F6f3wwSZAU93E0Eg6cHwIR6jzzOXWSy+SD/rOODEs74cVONHKSx2obXtuUoyidVEhISrisgQ==", - "bundleDependencies": [ - "@isaacs/string-locale-compare", - "@npmcli/arborist", - "@npmcli/config", - "@npmcli/fs", - "@npmcli/map-workspaces", - "@npmcli/package-json", - "@npmcli/promise-spawn", - "@npmcli/redact", - "@npmcli/run-script", - "@sigstore/tuf", - "abbrev", - "archy", - "cacache", - "chalk", - "ci-info", - "cli-columns", - "fastest-levenshtein", - "fs-minipass", - "glob", - "graceful-fs", - "hosted-git-info", - "ini", - "init-package-json", - "is-cidr", - "json-parse-even-better-errors", - "libnpmaccess", - "libnpmdiff", - "libnpmexec", - "libnpmfund", - "libnpmhook", - "libnpmorg", - "libnpmpack", - "libnpmpublish", - "libnpmsearch", - "libnpmteam", - "libnpmversion", - "make-fetch-happen", - "minimatch", - "minipass", - "minipass-pipeline", - "ms", - "node-gyp", - "nopt", - "normalize-package-data", - "npm-audit-report", - "npm-install-checks", - "npm-package-arg", - "npm-pick-manifest", - "npm-profile", - "npm-registry-fetch", - "npm-user-validate", - "p-map", - "pacote", - "parse-conflict-json", - "proc-log", - "qrcode-terminal", - "read", - "semver", - "spdx-expression-parse", - "ssri", - "supports-color", - "tar", - "text-table", - "tiny-relative-date", - "treeverse", - "validate-npm-package-name", - "which", - "write-file-atomic" - ], - "dev": true, - "license": "Artistic-2.0", - "workspaces": [ - "docs", - "smoke-tests", - "mock-globals", - "mock-registry", - "workspaces/*" - ], - "dependencies": { - "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^8.0.0", - "@npmcli/config": "^9.0.0", - "@npmcli/fs": "^4.0.0", - "@npmcli/map-workspaces": "^4.0.2", - "@npmcli/package-json": "^6.1.0", - "@npmcli/promise-spawn": "^8.0.2", - "@npmcli/redact": "^3.0.0", - "@npmcli/run-script": "^9.0.1", - "@sigstore/tuf": "^3.0.0", - "abbrev": "^3.0.0", - "archy": "~1.0.0", - "cacache": "^19.0.1", - "chalk": "^5.3.0", - "ci-info": "^4.1.0", - "cli-columns": "^4.0.0", - "fastest-levenshtein": "^1.0.16", - "fs-minipass": "^3.0.3", - "glob": "^10.4.5", - "graceful-fs": "^4.2.11", - "hosted-git-info": "^8.0.2", - "ini": "^5.0.0", - "init-package-json": "^7.0.2", - "is-cidr": "^5.1.0", - "json-parse-even-better-errors": "^4.0.0", - "libnpmaccess": "^9.0.0", - "libnpmdiff": "^7.0.0", - "libnpmexec": "^9.0.0", - "libnpmfund": "^6.0.0", - "libnpmhook": "^11.0.0", - "libnpmorg": "^7.0.0", - "libnpmpack": "^8.0.0", - "libnpmpublish": "^10.0.1", - "libnpmsearch": "^8.0.0", - "libnpmteam": "^7.0.0", - "libnpmversion": "^7.0.0", - "make-fetch-happen": "^14.0.3", - "minimatch": "^9.0.5", - "minipass": "^7.1.1", - "minipass-pipeline": "^1.2.4", - "ms": "^2.1.2", - "node-gyp": "^11.0.0", - "nopt": "^8.0.0", - "normalize-package-data": "^7.0.0", - "npm-audit-report": "^6.0.0", - "npm-install-checks": "^7.1.1", - "npm-package-arg": "^12.0.0", - "npm-pick-manifest": "^10.0.0", - "npm-profile": "^11.0.1", - "npm-registry-fetch": "^18.0.2", - "npm-user-validate": "^3.0.0", - "p-map": "^4.0.0", - "pacote": "^19.0.1", - "parse-conflict-json": "^4.0.0", - "proc-log": "^5.0.0", - "qrcode-terminal": "^0.12.0", - "read": "^4.0.0", - "semver": "^7.6.3", - "spdx-expression-parse": "^4.0.0", - "ssri": "^12.0.0", - "supports-color": "^9.4.0", - "tar": "^6.2.1", - "text-table": "~0.2.0", - "tiny-relative-date": "^1.3.0", - "treeverse": "^3.0.0", - "validate-npm-package-name": "^6.0.0", - "which": "^5.0.0", - "write-file-atomic": "^6.0.0" - }, - "bin": { - "npm": "bin/npm-cli.js", - "npx": "bin/npx-cli.js" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -12333,2606 +12171,6 @@ "node": ">=8" } }, - "node_modules/npm/node_modules/@isaacs/cliui": { - "version": "8.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/npm/node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/npm/node_modules/@isaacs/fs-minipass": { - "version": "4.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.4" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/npm/node_modules/@isaacs/string-locale-compare": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/@npmcli/agent": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "agent-base": "^7.1.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.1", - "lru-cache": "^10.0.1", - "socks-proxy-agent": "^8.0.3" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/@npmcli/arborist": { - "version": "8.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/fs": "^4.0.0", - "@npmcli/installed-package-contents": "^3.0.0", - "@npmcli/map-workspaces": "^4.0.1", - "@npmcli/metavuln-calculator": "^8.0.0", - "@npmcli/name-from-folder": "^3.0.0", - "@npmcli/node-gyp": "^4.0.0", - "@npmcli/package-json": "^6.0.1", - "@npmcli/query": "^4.0.0", - "@npmcli/redact": "^3.0.0", - "@npmcli/run-script": "^9.0.1", - "bin-links": "^5.0.0", - "cacache": "^19.0.1", - "common-ancestor-path": "^1.0.1", - "hosted-git-info": "^8.0.0", - "json-parse-even-better-errors": "^4.0.0", - "json-stringify-nice": "^1.1.4", - "lru-cache": "^10.2.2", - "minimatch": "^9.0.4", - "nopt": "^8.0.0", - "npm-install-checks": "^7.1.0", - "npm-package-arg": "^12.0.0", - "npm-pick-manifest": "^10.0.0", - "npm-registry-fetch": "^18.0.1", - "pacote": "^19.0.0", - "parse-conflict-json": "^4.0.0", - "proc-log": "^5.0.0", - "proggy": "^3.0.0", - "promise-all-reject-late": "^1.0.0", - "promise-call-limit": "^3.0.1", - "read-package-json-fast": "^4.0.0", - "semver": "^7.3.7", - "ssri": "^12.0.0", - "treeverse": "^3.0.0", - "walk-up-path": "^3.0.1" - }, - "bin": { - "arborist": "bin/index.js" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/@npmcli/config": { - "version": "9.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/map-workspaces": "^4.0.1", - "@npmcli/package-json": "^6.0.1", - "ci-info": "^4.0.0", - "ini": "^5.0.0", - "nopt": "^8.0.0", - "proc-log": "^5.0.0", - "semver": "^7.3.5", - "walk-up-path": "^3.0.1" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/@npmcli/fs": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/@npmcli/git": { - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/promise-spawn": "^8.0.0", - "ini": "^5.0.0", - "lru-cache": "^10.0.1", - "npm-pick-manifest": "^10.0.0", - "proc-log": "^5.0.0", - "promise-inflight": "^1.0.1", - "promise-retry": "^2.0.1", - "semver": "^7.3.5", - "which": "^5.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/@npmcli/installed-package-contents": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-bundled": "^4.0.0", - "npm-normalize-package-bin": "^4.0.0" - }, - "bin": { - "installed-package-contents": "bin/index.js" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/@npmcli/map-workspaces": { - "version": "4.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/name-from-folder": "^3.0.0", - "@npmcli/package-json": "^6.0.0", - "glob": "^10.2.2", - "minimatch": "^9.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { - "version": "8.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "cacache": "^19.0.0", - "json-parse-even-better-errors": "^4.0.0", - "pacote": "^20.0.0", - "proc-log": "^5.0.0", - "semver": "^7.3.5" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/@npmcli/metavuln-calculator/node_modules/pacote": { - "version": "20.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/git": "^6.0.0", - "@npmcli/installed-package-contents": "^3.0.0", - "@npmcli/package-json": "^6.0.0", - "@npmcli/promise-spawn": "^8.0.0", - "@npmcli/run-script": "^9.0.0", - "cacache": "^19.0.0", - "fs-minipass": "^3.0.0", - "minipass": "^7.0.2", - "npm-package-arg": "^12.0.0", - "npm-packlist": "^9.0.0", - "npm-pick-manifest": "^10.0.0", - "npm-registry-fetch": "^18.0.0", - "proc-log": "^5.0.0", - "promise-retry": "^2.0.1", - "sigstore": "^3.0.0", - "ssri": "^12.0.0", - "tar": "^6.1.11" - }, - "bin": { - "pacote": "bin/index.js" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/@npmcli/name-from-folder": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/@npmcli/node-gyp": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/@npmcli/package-json": { - "version": "6.1.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/git": "^6.0.0", - "glob": "^10.2.2", - "hosted-git-info": "^8.0.0", - "json-parse-even-better-errors": "^4.0.0", - "normalize-package-data": "^7.0.0", - "proc-log": "^5.0.0", - "semver": "^7.5.3" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/@npmcli/promise-spawn": { - "version": "8.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "which": "^5.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/@npmcli/query": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "postcss-selector-parser": "^6.1.2" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/@npmcli/redact": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/@npmcli/run-script": { - "version": "9.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/node-gyp": "^4.0.0", - "@npmcli/package-json": "^6.0.0", - "@npmcli/promise-spawn": "^8.0.0", - "node-gyp": "^11.0.0", - "proc-log": "^5.0.0", - "which": "^5.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/npm/node_modules/@sigstore/protobuf-specs": { - "version": "0.3.2", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/tuf": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/protobuf-specs": "^0.3.2", - "tuf-js": "^3.0.1" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/@tufjs/canonical-json": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/abbrev": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/agent-base": { - "version": "7.1.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/npm/node_modules/aggregate-error": { - "version": "3.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/ansi-styles": { - "version": "6.2.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/npm/node_modules/aproba": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/archy": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/balanced-match": { - "version": "1.0.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/bin-links": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "cmd-shim": "^7.0.0", - "npm-normalize-package-bin": "^4.0.0", - "proc-log": "^5.0.0", - "read-cmd-shim": "^5.0.0", - "write-file-atomic": "^6.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/binary-extensions": { - "version": "2.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/brace-expansion": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/npm/node_modules/cacache": { - "version": "19.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/fs": "^4.0.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^10.0.1", - "minipass": "^7.0.3", - "minipass-collect": "^2.0.1", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^7.0.2", - "ssri": "^12.0.0", - "tar": "^7.4.3", - "unique-filename": "^4.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/cacache/node_modules/chownr": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/npm/node_modules/cacache/node_modules/minizlib": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.0.4", - "rimraf": "^5.0.5" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/npm/node_modules/cacache/node_modules/mkdirp": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/cacache/node_modules/p-map": { - "version": "7.0.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/cacache/node_modules/tar": { - "version": "7.4.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.0.1", - "mkdirp": "^3.0.1", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/npm/node_modules/cacache/node_modules/yallist": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/npm/node_modules/chalk": { - "version": "5.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/npm/node_modules/chownr": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/ci-info": { - "version": "4.1.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/cidr-regex": { - "version": "4.1.1", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "ip-regex": "^5.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/npm/node_modules/clean-stack": { - "version": "2.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/npm/node_modules/cli-columns": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/npm/node_modules/cmd-shim": { - "version": "7.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/color-convert": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/npm/node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/common-ancestor-path": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/cross-spawn": { - "version": "7.0.6", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/cross-spawn/node_modules/which": { - "version": "2.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/cssesc": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm/node_modules/debug": { - "version": "4.3.7", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/npm/node_modules/diff": { - "version": "5.2.0", - "dev": true, - "inBundle": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/npm/node_modules/eastasianwidth": { - "version": "0.2.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/encoding": { - "version": "0.1.13", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, - "node_modules/npm/node_modules/env-paths": { - "version": "2.2.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/npm/node_modules/err-code": { - "version": "2.0.3", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/exponential-backoff": { - "version": "3.1.1", - "dev": true, - "inBundle": true, - "license": "Apache-2.0" - }, - "node_modules/npm/node_modules/fastest-levenshtein": { - "version": "1.0.16", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 4.9.1" - } - }, - "node_modules/npm/node_modules/foreground-child": { - "version": "3.3.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/fs-minipass": { - "version": "3.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/glob": { - "version": "10.4.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/graceful-fs": { - "version": "4.2.11", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/hosted-git-info": { - "version": "8.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^10.0.1" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/http-cache-semantics": { - "version": "4.1.1", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause" - }, - "node_modules/npm/node_modules/http-proxy-agent": { - "version": "7.0.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/npm/node_modules/https-proxy-agent": { - "version": "7.0.5", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/npm/node_modules/iconv-lite": { - "version": "0.6.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm/node_modules/ignore-walk": { - "version": "7.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minimatch": "^9.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/imurmurhash": { - "version": "0.1.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/npm/node_modules/indent-string": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/ini": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/init-package-json": { - "version": "7.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/package-json": "^6.0.0", - "npm-package-arg": "^12.0.0", - "promzard": "^2.0.0", - "read": "^4.0.0", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "^6.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/ip-address": { - "version": "9.0.5", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/npm/node_modules/ip-regex": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/is-cidr": { - "version": "5.1.0", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "cidr-regex": "^4.1.1" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/npm/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/isexe": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/jackspeak": { - "version": "3.4.3", - "dev": true, - "inBundle": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/npm/node_modules/jsbn": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/json-parse-even-better-errors": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/json-stringify-nice": { - "version": "1.1.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/jsonparse": { - "version": "1.3.1", - "dev": true, - "engines": [ - "node >= 0.2.0" - ], - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/just-diff": { - "version": "6.0.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/just-diff-apply": { - "version": "5.5.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/libnpmaccess": { - "version": "9.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-package-arg": "^12.0.0", - "npm-registry-fetch": "^18.0.1" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/libnpmdiff": { - "version": "7.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^8.0.0", - "@npmcli/installed-package-contents": "^3.0.0", - "binary-extensions": "^2.3.0", - "diff": "^5.1.0", - "minimatch": "^9.0.4", - "npm-package-arg": "^12.0.0", - "pacote": "^19.0.0", - "tar": "^6.2.1" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/libnpmexec": { - "version": "9.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^8.0.0", - "@npmcli/run-script": "^9.0.1", - "ci-info": "^4.0.0", - "npm-package-arg": "^12.0.0", - "pacote": "^19.0.0", - "proc-log": "^5.0.0", - "read": "^4.0.0", - "read-package-json-fast": "^4.0.0", - "semver": "^7.3.7", - "walk-up-path": "^3.0.1" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/libnpmfund": { - "version": "6.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^8.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/libnpmhook": { - "version": "11.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^18.0.1" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/libnpmorg": { - "version": "7.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^18.0.1" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/libnpmpack": { - "version": "8.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^8.0.0", - "@npmcli/run-script": "^9.0.1", - "npm-package-arg": "^12.0.0", - "pacote": "^19.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/libnpmpublish": { - "version": "10.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "ci-info": "^4.0.0", - "normalize-package-data": "^7.0.0", - "npm-package-arg": "^12.0.0", - "npm-registry-fetch": "^18.0.1", - "proc-log": "^5.0.0", - "semver": "^7.3.7", - "sigstore": "^3.0.0", - "ssri": "^12.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/libnpmsearch": { - "version": "8.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-registry-fetch": "^18.0.1" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/libnpmteam": { - "version": "7.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^18.0.1" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/libnpmversion": { - "version": "7.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/git": "^6.0.1", - "@npmcli/run-script": "^9.0.1", - "json-parse-even-better-errors": "^4.0.0", - "proc-log": "^5.0.0", - "semver": "^7.3.7" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/lru-cache": { - "version": "10.4.3", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/make-fetch-happen": { - "version": "14.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/agent": "^3.0.0", - "cacache": "^19.0.1", - "http-cache-semantics": "^4.1.1", - "minipass": "^7.0.2", - "minipass-fetch": "^4.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^1.0.0", - "proc-log": "^5.0.0", - "promise-retry": "^2.0.1", - "ssri": "^12.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/make-fetch-happen/node_modules/negotiator": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/npm/node_modules/minimatch": { - "version": "9.0.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/minipass": { - "version": "7.1.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/npm/node_modules/minipass-collect": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/npm/node_modules/minipass-fetch": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", - "minizlib": "^3.0.1" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/npm/node_modules/minipass-fetch/node_modules/minizlib": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.0.4", - "rimraf": "^5.0.5" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/npm/node_modules/minipass-flush": { - "version": "1.0.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-pipeline": { - "version": "1.2.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-sized": { - "version": "1.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-sized/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minizlib": { - "version": "2.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/mkdirp": { - "version": "1.0.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/ms": { - "version": "2.1.3", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/mute-stream": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/node-gyp": { - "version": "11.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "env-paths": "^2.2.0", - "exponential-backoff": "^3.1.1", - "glob": "^10.3.10", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^14.0.3", - "nopt": "^8.0.0", - "proc-log": "^5.0.0", - "semver": "^7.3.5", - "tar": "^7.4.3", - "which": "^5.0.0" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/chownr": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/minizlib": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.0.4", - "rimraf": "^5.0.5" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/mkdirp": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/tar": { - "version": "7.4.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.0.1", - "mkdirp": "^3.0.1", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/npm/node_modules/node-gyp/node_modules/yallist": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/npm/node_modules/nopt": { - "version": "8.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "abbrev": "^2.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/nopt/node_modules/abbrev": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/normalize-package-data": { - "version": "7.0.0", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^8.0.0", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/npm-audit-report": { - "version": "6.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/npm-bundled": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-normalize-package-bin": "^4.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/npm-install-checks": { - "version": "7.1.1", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "semver": "^7.1.1" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/npm-normalize-package-bin": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/npm-package-arg": { - "version": "12.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "hosted-git-info": "^8.0.0", - "proc-log": "^5.0.0", - "semver": "^7.3.5", - "validate-npm-package-name": "^6.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/npm-packlist": { - "version": "9.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "ignore-walk": "^7.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/npm-pick-manifest": { - "version": "10.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-install-checks": "^7.1.0", - "npm-normalize-package-bin": "^4.0.0", - "npm-package-arg": "^12.0.0", - "semver": "^7.3.5" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/npm-profile": { - "version": "11.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-registry-fetch": "^18.0.0", - "proc-log": "^5.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/npm-registry-fetch": { - "version": "18.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/redact": "^3.0.0", - "jsonparse": "^1.3.1", - "make-fetch-happen": "^14.0.0", - "minipass": "^7.0.2", - "minipass-fetch": "^4.0.0", - "minizlib": "^3.0.1", - "npm-package-arg": "^12.0.0", - "proc-log": "^5.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/npm-registry-fetch/node_modules/minizlib": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.0.4", - "rimraf": "^5.0.5" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/npm/node_modules/npm-user-validate": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/p-map": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/package-json-from-dist": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "BlueOak-1.0.0" - }, - "node_modules/npm/node_modules/pacote": { - "version": "19.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/git": "^6.0.0", - "@npmcli/installed-package-contents": "^3.0.0", - "@npmcli/package-json": "^6.0.0", - "@npmcli/promise-spawn": "^8.0.0", - "@npmcli/run-script": "^9.0.0", - "cacache": "^19.0.0", - "fs-minipass": "^3.0.0", - "minipass": "^7.0.2", - "npm-package-arg": "^12.0.0", - "npm-packlist": "^9.0.0", - "npm-pick-manifest": "^10.0.0", - "npm-registry-fetch": "^18.0.0", - "proc-log": "^5.0.0", - "promise-retry": "^2.0.1", - "sigstore": "^3.0.0", - "ssri": "^12.0.0", - "tar": "^6.1.11" - }, - "bin": { - "pacote": "bin/index.js" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/parse-conflict-json": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "json-parse-even-better-errors": "^4.0.0", - "just-diff": "^6.0.0", - "just-diff-apply": "^5.2.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/path-key": { - "version": "3.1.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/path-scurry": { - "version": "1.11.1", - "dev": true, - "inBundle": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/postcss-selector-parser": { - "version": "6.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm/node_modules/proc-log": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/proggy": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/promise-all-reject-late": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/promise-call-limit": { - "version": "3.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/promise-inflight": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/promise-retry": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/promzard": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "read": "^4.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/qrcode-terminal": { - "version": "0.12.0", - "dev": true, - "inBundle": true, - "bin": { - "qrcode-terminal": "bin/qrcode-terminal.js" - } - }, - "node_modules/npm/node_modules/read": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "mute-stream": "^2.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/read-cmd-shim": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/read-package-json-fast": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "json-parse-even-better-errors": "^4.0.0", - "npm-normalize-package-bin": "^4.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/retry": { - "version": "0.12.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/npm/node_modules/rimraf": { - "version": "5.0.10", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "glob": "^10.3.7" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/safer-buffer": { - "version": "2.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true - }, - "node_modules/npm/node_modules/semver": { - "version": "7.6.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/shebang-command": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/shebang-regex": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/signal-exit": { - "version": "4.1.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/sigstore": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^3.0.0", - "@sigstore/core": "^2.0.0", - "@sigstore/protobuf-specs": "^0.3.2", - "@sigstore/sign": "^3.0.0", - "@sigstore/tuf": "^3.0.0", - "@sigstore/verify": "^2.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/bundle": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/protobuf-specs": "^0.3.2" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/core": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/sign": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^3.0.0", - "@sigstore/core": "^2.0.0", - "@sigstore/protobuf-specs": "^0.3.2", - "make-fetch-happen": "^14.0.1", - "proc-log": "^5.0.0", - "promise-retry": "^2.0.1" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/verify": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^3.0.0", - "@sigstore/core": "^2.0.0", - "@sigstore/protobuf-specs": "^0.3.2" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/smart-buffer": { - "version": "4.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/npm/node_modules/socks": { - "version": "2.8.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ip-address": "^9.0.5", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/npm/node_modules/socks-proxy-agent": { - "version": "8.0.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.1", - "debug": "^4.3.4", - "socks": "^2.8.3" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/npm/node_modules/spdx-correct": { - "version": "3.2.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/npm/node_modules/spdx-correct/node_modules/spdx-expression-parse": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/npm/node_modules/spdx-exceptions": { - "version": "2.5.0", - "dev": true, - "inBundle": true, - "license": "CC-BY-3.0" - }, - "node_modules/npm/node_modules/spdx-expression-parse": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/npm/node_modules/spdx-license-ids": { - "version": "3.0.20", - "dev": true, - "inBundle": true, - "license": "CC0-1.0" - }, - "node_modules/npm/node_modules/sprintf-js": { - "version": "1.1.3", - "dev": true, - "inBundle": true, - "license": "BSD-3-Clause" - }, - "node_modules/npm/node_modules/ssri": { - "version": "12.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/supports-color": { - "version": "9.4.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/npm/node_modules/tar": { - "version": "6.2.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/tar/node_modules/fs-minipass": { - "version": "2.1.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/tar/node_modules/minipass": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/text-table": { - "version": "0.2.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/tiny-relative-date": { - "version": "1.3.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/treeverse": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/tuf-js": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@tufjs/models": "3.0.1", - "debug": "^4.3.6", - "make-fetch-happen": "^14.0.1" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/tuf-js/node_modules/@tufjs/models": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@tufjs/canonical-json": "2.0.0", - "minimatch": "^9.0.5" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/unique-filename": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "unique-slug": "^5.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/unique-slug": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/util-deprecate": { - "version": "1.0.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/validate-npm-package-license": { - "version": "3.0.4", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/npm/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/npm/node_modules/validate-npm-package-name": { - "version": "6.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/walk-up-path": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/which": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/which/node_modules/isexe": { - "version": "3.1.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=16" - } - }, - "node_modules/npm/node_modules/wrap-ansi": { - "version": "8.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/npm/node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/npm/node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "9.2.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": { - "version": "5.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/npm/node_modules/write-file-atomic": { - "version": "6.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, "node_modules/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -18473,9 +15711,9 @@ } }, "node_modules/sucrase/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "dev": true, "license": "ISC", "dependencies": { diff --git a/web/vtadmin/package.json b/web/vtadmin/package.json index 0b8be570f18..db6b0bec4dc 100644 --- a/web/vtadmin/package.json +++ b/web/vtadmin/package.json @@ -90,7 +90,6 @@ "i": "^0.3.7", "jsdom": "^21.1.1", "msw": "^2.5.2", - "npm": "^10.9.2", "postcss": "^8.4.31", "prettier": "^2.2.1", "protobufjs-cli": "^1.1.3", From 51d20dee946465ab52ae35ac2f57a52e9aa665d5 Mon Sep 17 00:00:00 2001 From: vitess-go-upgrade-bot <139342327+vitess-bot@users.noreply.github.com> Date: Sun, 30 Nov 2025 14:22:50 +0100 Subject: [PATCH 009/112] [release-22.0] Don't hardcode the go version to use for upgrade/downgrade tests. (#18920) (#18955) Signed-off-by: Arthur Schreiber Co-authored-by: Arthur Schreiber --- .../upgrade_downgrade_test_backups_e2e.yml | 28 +++++++----- ...owngrade_test_backups_e2e_next_release.yml | 28 +++++++----- .../upgrade_downgrade_test_backups_manual.yml | 44 +++++++++++-------- ...grade_test_backups_manual_next_release.yml | 44 +++++++++++-------- .../upgrade_downgrade_test_onlineddl_flow.yml | 36 ++++++++++----- ...e_downgrade_test_query_serving_queries.yml | 20 ++++----- ...downgrade_test_query_serving_queries_2.yml | 36 +++++++-------- ...t_query_serving_queries_2_next_release.yml | 27 +++++++----- ...est_query_serving_queries_next_release.yml | 27 +++++++----- ...de_downgrade_test_query_serving_schema.yml | 27 +++++++----- ...test_query_serving_schema_next_release.yml | 27 +++++++----- ...rade_downgrade_test_reparent_new_vtctl.yml | 27 +++++++----- ...e_downgrade_test_reparent_new_vttablet.yml | 27 +++++++----- ...rade_downgrade_test_reparent_old_vtctl.yml | 27 +++++++----- ...e_downgrade_test_reparent_old_vttablet.yml | 27 +++++++----- .../upgrade_downgrade_test_semi_sync.yml | 43 ++++++++++-------- 16 files changed, 285 insertions(+), 210 deletions(-) diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml index a7e3470bdac..698c52a834c 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml @@ -62,20 +62,14 @@ jobs: - 'bootstrap.sh' - '.github/workflows/upgrade_downgrade_test_backups_e2e.yml' - - name: Set up Go + - name: Tune the OS if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version: 1.24.10 + uses: ./.github/actions/tune-os - name: Set up python if: steps.changes.outputs.end_to_end == 'true' uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - name: Setup MySQL if: steps.changes.outputs.end_to_end == 'true' uses: ./.github/actions/setup-mysql @@ -92,10 +86,6 @@ jobs: sudo apt-get install -y make unzip g++ etcd-client etcd-server curl git wget grep sudo service etcd stop - go mod download - - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb sudo apt-get install -y gnupg2 @@ -112,6 +102,13 @@ jobs: ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }} persist-credentials: 'false' + - name: Set up Go + if: steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for the last release if: steps.changes.outputs.end_to_end == 'true' run: | @@ -134,6 +131,13 @@ jobs: with: persist-credentials: 'false' + - name: Set up Go + if: steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for this commit if: steps.changes.outputs.end_to_end == 'true' run: | diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml index e98f996461e..bf51101fd69 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml @@ -64,20 +64,14 @@ jobs: - 'bootstrap.sh' - '.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml' - - name: Set up Go + - name: Tune the OS if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod + uses: ./.github/actions/tune-os - name: Set up python if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - name: Tune the OS - if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - name: Setup MySQL if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' uses: ./.github/actions/setup-mysql @@ -94,10 +88,6 @@ jobs: sudo apt-get install -y make unzip g++ etcd-client etcd-server curl git wget grep sudo service etcd stop - go mod download - - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb sudo apt-get install -y gnupg2 @@ -114,6 +104,13 @@ jobs: ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }} persist-credentials: 'false' + - name: Set up Go + if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for the next release if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' run: | @@ -136,6 +133,13 @@ jobs: with: persist-credentials: 'false' + - name: Set up Go + if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for this commit if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' run: | diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual.yml b/.github/workflows/upgrade_downgrade_test_backups_manual.yml index 1924b29e346..f45941ac7b0 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_manual.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_manual.yml @@ -37,13 +37,6 @@ jobs: fetch-depth: 0 persist-credentials: 'false' - - name: Set output with latest release branch - id: output-previous-release-ref - run: | - previous_release_ref=$(./tools/get_previous_release.sh ${{github.base_ref}} ${{github.ref}}) - echo $previous_release_ref - echo "previous_release_ref=${previous_release_ref}" >> $GITHUB_OUTPUT - - name: Check for changes in relevant files uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 id: changes @@ -66,20 +59,22 @@ jobs: - '.github/workflows/upgrade_downgrade_test_backups_manual.yml' - 'examples/**' - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version: 1.24.10 - - - name: Set up python + - name: Set output with latest release branch if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 + id: output-previous-release-ref + run: | + previous_release_ref=$(./tools/get_previous_release.sh ${{github.base_ref}} ${{github.ref}}) + echo $previous_release_ref + echo "previous_release_ref=${previous_release_ref}" >> $GITHUB_OUTPUT - name: Tune the OS if: steps.changes.outputs.end_to_end == 'true' uses: ./.github/actions/tune-os + - name: Set up python + if: steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 + - name: Setup MySQL if: steps.changes.outputs.end_to_end == 'true' uses: ./.github/actions/setup-mysql @@ -97,9 +92,6 @@ jobs: sudo service etcd stop - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb sudo apt-get install -y gnupg2 sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb @@ -115,6 +107,13 @@ jobs: ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }} persist-credentials: 'false' + - name: Set up Go + if: steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for the last release if: steps.changes.outputs.end_to_end == 'true' run: | @@ -137,6 +136,13 @@ jobs: with: persist-credentials: 'false' + - name: Set up Go + if: steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for this commit if: steps.changes.outputs.end_to_end == 'true' run: | @@ -278,7 +284,7 @@ jobs: echo "select count(sku) from corder;" | mysql 2>&1| grep 6 - name: Stop the Vitess cluster - if: always() && steps.changes.outputs.end_to_end == 'true' + if: steps.changes.outputs.end_to_end == 'true' && !cancelled() run: | source build.env ; cd examples/local ./401_teardown.sh || true diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml b/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml index a40df43a271..0f100171b47 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml @@ -37,13 +37,6 @@ jobs: fetch-depth: 0 persist-credentials: 'false' - - name: Set output with latest release branch - id: output-next-release-ref - run: | - next_release_ref=$(./tools/get_next_release.sh ${{github.base_ref}} ${{github.ref}}) - echo $next_release_ref - echo "next_release_ref=${next_release_ref}" >> $GITHUB_OUTPUT - - name: Check for changes in relevant files if: steps.output-next-release-ref.outputs.next_release_ref != '' uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 @@ -67,20 +60,22 @@ jobs: - '.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml' - 'examples/**' - - name: Set up Go + - name: Set output with latest release branch + id: output-next-release-ref + if: steps.changes.outputs.end_to_end == 'true' + run: | + next_release_ref=$(./tools/get_next_release.sh ${{github.base_ref}} ${{github.ref}}) + echo $next_release_ref + echo "next_release_ref=${next_release_ref}" >> $GITHUB_OUTPUT + + - name: Tune the OS if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod + uses: ./.github/actions/tune-os - name: Set up python if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - name: Tune the OS - if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - name: Setup MySQL if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' uses: ./.github/actions/setup-mysql @@ -98,9 +93,6 @@ jobs: sudo service etcd stop - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb sudo apt-get install -y gnupg2 sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb @@ -116,6 +108,13 @@ jobs: ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }} persist-credentials: 'false' + - name: Set up Go + if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for the next release if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' run: | @@ -138,6 +137,13 @@ jobs: with: persist-credentials: 'false' + - name: Set up Go + if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for this commit if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' run: | @@ -279,7 +285,7 @@ jobs: echo "select count(sku) from corder;" | mysql 2>&1| grep 6 - name: Stop the Vitess cluster - if: always() && steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' + if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' && !cancelled() run: | source build.env ; cd examples/local ./401_teardown.sh || true diff --git a/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml b/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml index d761baa1d1d..d3ffcf8de1c 100644 --- a/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml +++ b/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml @@ -60,6 +60,7 @@ jobs: - '.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml' - name: Set output with latest release branch + if: steps.changes.outputs.end_to_end == 'true' id: output-previous-release-ref run: | previous_release_ref=$(./tools/get_previous_release.sh ${{github.base_ref}} ${{github.ref}}) @@ -67,26 +68,21 @@ jobs: echo "previous_release_ref=${previous_release_ref}" >> $GITHUB_OUTPUT - name: Set output with next release branch + if: steps.changes.outputs.end_to_end == 'true' id: output-next-release-ref run: | next_release_ref=$(./tools/get_next_release.sh ${{github.base_ref}} ${{github.ref}}) echo $next_release_ref echo "next_release_ref=${next_release_ref}" >> $GITHUB_OUTPUT - - name: Set up Go + - name: Tune the OS if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version: 1.24.10 + uses: ./.github/actions/tune-os - name: Set up python if: steps.changes.outputs.end_to_end == 'true' uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - name: Setup MySQL if: steps.changes.outputs.end_to_end == 'true' uses: ./.github/actions/setup-mysql @@ -103,9 +99,6 @@ jobs: sudo service etcd stop - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - # Checkout to the last release of Vitess - name: Check out last version's code (${{ steps.output-previous-release-ref.outputs.previous_release_ref }}) if: steps.changes.outputs.end_to_end == 'true' @@ -114,6 +107,13 @@ jobs: ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }} persist-credentials: 'false' + - name: Set up Go + if: steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for the last release if: steps.changes.outputs.end_to_end == 'true' run: | @@ -138,6 +138,13 @@ jobs: ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }} persist-credentials: 'false' + - name: Set up Go + if: steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for the next release if: steps.changes.outputs.end_to_end == 'true' run: | @@ -161,6 +168,13 @@ jobs: with: persist-credentials: 'false' + - name: Set up Go + if: steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for this commit if: steps.changes.outputs.end_to_end == 'true' run: | diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml index 24276f775df..3e536e324de 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml @@ -66,20 +66,14 @@ jobs: - 'bootstrap.sh' - '.github/workflows/upgrade_downgrade_test_query_serving_queries.yml' - - name: Set up Go + - name: Tune the OS if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version: 1.24.10 + uses: ./.github/actions/tune-os - name: Set up python if: steps.changes.outputs.end_to_end == 'true' uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - name: Setup MySQL if: steps.changes.outputs.end_to_end == 'true' uses: ./.github/actions/setup-mysql @@ -96,9 +90,6 @@ jobs: sudo service etcd stop - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - # Build current commit's binaries - name: Get dependencies for this commit if: steps.changes.outputs.end_to_end == 'true' @@ -123,6 +114,13 @@ jobs: ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }} persist-credentials: 'false' + - name: Set up Go + if: steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for the last release if: steps.changes.outputs.end_to_end == 'true' run: | diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml index 0fe3324aaec..e0d2d5a07d5 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml @@ -18,7 +18,6 @@ permissions: read-all # (vtgate, vttablet, etc) built on different versions. jobs: - upgrade_downgrade_test: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Query Serving (Queries - 2) @@ -38,13 +37,6 @@ jobs: fetch-depth: 0 persist-credentials: 'false' - - name: Set output with latest release branch - id: output-previous-release-ref - run: | - previous_release_ref=$(./tools/get_previous_release.sh ${{github.base_ref}} ${{github.ref}}) - echo $previous_release_ref - echo "previous_release_ref=${previous_release_ref}" >> $GITHUB_OUTPUT - - name: Check for changes in relevant files uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 id: changes @@ -66,20 +58,22 @@ jobs: - 'bootstrap.sh' - '.github/workflows/upgrade_downgrade_test_query_serving_queries.yml' - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version: 1.24.10 - - - name: Set up python + - name: Set output with latest release branch if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 + id: output-previous-release-ref + run: | + previous_release_ref=$(./tools/get_previous_release.sh ${{github.base_ref}} ${{github.ref}}) + echo $previous_release_ref + echo "previous_release_ref=${previous_release_ref}" >> $GITHUB_OUTPUT - name: Tune the OS if: steps.changes.outputs.end_to_end == 'true' uses: ./.github/actions/tune-os + - name: Set up python + if: steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 + - name: Setup MySQL if: steps.changes.outputs.end_to_end == 'true' uses: ./.github/actions/setup-mysql @@ -96,9 +90,6 @@ jobs: sudo service etcd stop - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - # Build current commit's binaries - name: Get dependencies for this commit if: steps.changes.outputs.end_to_end == 'true' @@ -123,6 +114,13 @@ jobs: ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }} persist-credentials: 'false' + - name: Set up Go + if: steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for the last release if: steps.changes.outputs.end_to_end == 'true' run: | diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml index ac3e6ec31dc..aacfaf41f55 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml @@ -67,20 +67,14 @@ jobs: - 'bootstrap.sh' - '.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml' - - name: Set up Go + - name: Tune the OS if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod + uses: ./.github/actions/tune-os - name: Set up python if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - name: Tune the OS - if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - name: Setup MySQL if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' uses: ./.github/actions/setup-mysql @@ -97,9 +91,6 @@ jobs: sudo service etcd stop - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - # Checkout to the next release of Vitess - name: Check out other version's code (${{ steps.output-next-release-ref.outputs.next_release_ref }}) if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' @@ -108,6 +99,13 @@ jobs: ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }} persist-credentials: 'false' + - name: Set up Go + if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for the next release if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' run: | @@ -130,6 +128,13 @@ jobs: with: persist-credentials: 'false' + - name: Set up Go + if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for this commit if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' run: | diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml index f1c844b9248..06312eafd37 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml @@ -67,20 +67,14 @@ jobs: - 'bootstrap.sh' - '.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml' - - name: Set up Go + - name: Tune the OS if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod + uses: ./.github/actions/tune-os - name: Set up python if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - name: Tune the OS - if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - name: Setup MySQL if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' uses: ./.github/actions/setup-mysql @@ -97,9 +91,6 @@ jobs: sudo service etcd stop - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - # Checkout to the next release of Vitess - name: Check out other version's code (${{ steps.output-next-release-ref.outputs.next_release_ref }}) if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' @@ -108,6 +99,13 @@ jobs: ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }} persist-credentials: 'false' + - name: Set up Go + if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for the next release if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' run: | @@ -130,6 +128,13 @@ jobs: with: persist-credentials: 'false' + - name: Set up Go + if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for this commit if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' run: | diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml index ecef80ea242..2e174484524 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml @@ -66,20 +66,14 @@ jobs: - 'bootstrap.sh' - '.github/workflows/upgrade_downgrade_test_query_serving_schema.yml' - - name: Set up Go + - name: Tune the OS if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version: 1.24.10 + uses: ./.github/actions/tune-os - name: Set up python if: steps.changes.outputs.end_to_end == 'true' uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - name: Setup MySQL if: steps.changes.outputs.end_to_end == 'true' uses: ./.github/actions/setup-mysql @@ -96,9 +90,6 @@ jobs: sudo service etcd stop - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - # Checkout to the last release of Vitess - name: Check out other version's code (${{ steps.output-previous-release-ref.outputs.previous_release_ref }}) if: steps.changes.outputs.end_to_end == 'true' @@ -107,6 +98,13 @@ jobs: ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }} persist-credentials: 'false' + - name: Set up Go + if: steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for the last release if: steps.changes.outputs.end_to_end == 'true' run: | @@ -129,6 +127,13 @@ jobs: with: persist-credentials: 'false' + - name: Set up Go + if: steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for this commit if: steps.changes.outputs.end_to_end == 'true' run: | diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml index 5375a8d582e..8d7d89d4a34 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml @@ -67,20 +67,14 @@ jobs: - 'bootstrap.sh' - '.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml' - - name: Set up Go + - name: Tune the OS if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod + uses: ./.github/actions/tune-os - name: Set up python if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - name: Tune the OS - if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - name: Setup MySQL if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' uses: ./.github/actions/setup-mysql @@ -97,9 +91,6 @@ jobs: sudo service etcd stop - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - # Checkout to the next release of Vitess - name: Check out other version's code (${{ steps.output-next-release-ref.outputs.next_release_ref }}) if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' @@ -108,6 +99,13 @@ jobs: ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }} persist-credentials: 'false' + - name: Set up Go + if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for the next release if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' run: | @@ -130,6 +128,13 @@ jobs: with: persist-credentials: 'false' + - name: Set up Go + if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for this commit if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' run: | diff --git a/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml b/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml index 82e0d0a3264..bfb66b5220c 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml @@ -67,20 +67,14 @@ jobs: - 'bootstrap.sh' - '.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml' - - name: Set up Go + - name: Tune the OS if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod + uses: ./.github/actions/tune-os - name: Set up python if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - name: Tune the OS - if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - name: Setup MySQL if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' uses: ./.github/actions/setup-mysql @@ -97,9 +91,6 @@ jobs: sudo service etcd stop - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - # Checkout to the next release of Vitess - name: Check out other version's code (${{ steps.output-next-release-ref.outputs.next_release_ref }}) if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' @@ -108,6 +99,13 @@ jobs: ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }} persist-credentials: 'false' + - name: Set up Go + if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for the next release if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' run: | @@ -130,6 +128,13 @@ jobs: with: persist-credentials: 'false' + - name: Set up Go + if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for this commit if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' run: | diff --git a/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml b/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml index 397597ffa50..0a7690d1630 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml @@ -67,20 +67,14 @@ jobs: - 'bootstrap.sh' - '.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml' - - name: Set up Go + - name: Tune the OS if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod + uses: ./.github/actions/tune-os - name: Set up python if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - name: Tune the OS - if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - name: Setup MySQL if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' uses: ./.github/actions/setup-mysql @@ -97,9 +91,6 @@ jobs: sudo service etcd stop - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb sudo apt-get install -y gnupg2 sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb @@ -115,6 +106,13 @@ jobs: ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }} persist-credentials: 'false' + - name: Set up Go + if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for the next release if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' run: | @@ -137,6 +135,13 @@ jobs: with: persist-credentials: 'false' + - name: Set up Go + if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for this commit if: steps.output-next-release-ref.outputs.next_release_ref != '' && steps.changes.outputs.end_to_end == 'true' run: | diff --git a/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml b/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml index 6d319154c42..7b57f1fee78 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml @@ -66,20 +66,14 @@ jobs: - 'bootstrap.sh' - '.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml' - - name: Set up Go + - name: Tune the OS if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version: 1.24.10 + uses: ./.github/actions/tune-os - name: Set up python if: steps.changes.outputs.end_to_end == 'true' uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - name: Setup MySQL if: steps.changes.outputs.end_to_end == 'true' uses: ./.github/actions/setup-mysql @@ -96,9 +90,6 @@ jobs: sudo service etcd stop - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - # Checkout to the last release of Vitess - name: Check out other version's code (${{ steps.output-previous-release-ref.outputs.previous_release_ref }}) if: steps.changes.outputs.end_to_end == 'true' @@ -107,6 +98,13 @@ jobs: ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }} persist-credentials: 'false' + - name: Set up Go + if: steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for the last release if: steps.changes.outputs.end_to_end == 'true' run: | @@ -129,6 +127,13 @@ jobs: with: persist-credentials: 'false' + - name: Set up Go + if: steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for this commit if: steps.changes.outputs.end_to_end == 'true' run: | diff --git a/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml b/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml index 28bba9b7fab..10bd5b65b84 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml @@ -66,20 +66,14 @@ jobs: - 'bootstrap.sh' - '.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml' - - name: Set up Go + - name: Tune the OS if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version: 1.24.10 + uses: ./.github/actions/tune-os - name: Set up python if: steps.changes.outputs.end_to_end == 'true' uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - name: Setup MySQL if: steps.changes.outputs.end_to_end == 'true' uses: ./.github/actions/setup-mysql @@ -96,9 +90,6 @@ jobs: sudo service etcd stop - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - # Checkout to the last release of Vitess - name: Check out other version's code (${{ steps.output-previous-release-ref.outputs.previous_release_ref }}) if: steps.changes.outputs.end_to_end == 'true' @@ -107,6 +98,13 @@ jobs: ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }} persist-credentials: 'false' + - name: Set up Go + if: steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for the last release if: steps.changes.outputs.end_to_end == 'true' run: | @@ -129,6 +127,13 @@ jobs: with: persist-credentials: 'false' + - name: Set up Go + if: steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for this commit if: steps.changes.outputs.end_to_end == 'true' run: | diff --git a/.github/workflows/upgrade_downgrade_test_semi_sync.yml b/.github/workflows/upgrade_downgrade_test_semi_sync.yml index 127bce0d8dc..01417975ce9 100644 --- a/.github/workflows/upgrade_downgrade_test_semi_sync.yml +++ b/.github/workflows/upgrade_downgrade_test_semi_sync.yml @@ -34,13 +34,6 @@ jobs: fetch-depth: 0 persist-credentials: 'false' - - name: Set output with latest release branch - id: output-previous-release-ref - run: | - previous_release_ref=$(./tools/get_previous_release.sh ${{github.base_ref}} ${{github.ref}}) - echo $previous_release_ref - echo "previous_release_ref=${previous_release_ref}" >> $GITHUB_OUTPUT - - name: Check for changes in relevant files uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 id: changes @@ -62,20 +55,22 @@ jobs: - 'bootstrap.sh' - '.github/workflows/upgrade_downgrade_test_semi_sync.yml' - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version: 1.24.10 - - - name: Set up python + - name: Set output with latest release branch + id: output-previous-release-ref if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 + run: | + previous_release_ref=$(./tools/get_previous_release.sh ${{github.base_ref}} ${{github.ref}}) + echo $previous_release_ref + echo "previous_release_ref=${previous_release_ref}" >> $GITHUB_OUTPUT - name: Tune the OS if: steps.changes.outputs.end_to_end == 'true' uses: ./.github/actions/tune-os + - name: Set up python + if: steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 + - name: Setup MySQL if: steps.changes.outputs.end_to_end == 'true' uses: ./.github/actions/setup-mysql @@ -92,10 +87,6 @@ jobs: sudo apt-get install -y make unzip g++ etcd-client etcd-server curl git wget grep sudo service etcd stop - go mod download - - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb sudo apt-get install -y gnupg2 @@ -112,6 +103,13 @@ jobs: ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }} persist-credentials: 'false' + - name: Set up Go + if: steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for the last release if: steps.changes.outputs.end_to_end == 'true' run: | @@ -134,6 +132,13 @@ jobs: with: persist-credentials: 'false' + - name: Set up Go + if: steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version-file: go.mod + cache: false + - name: Get dependencies for this commit if: steps.changes.outputs.end_to_end == 'true' run: | From 931a89cc4eec8ae15dd18166bdba4ebfa9a0d611 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 23:50:44 +0000 Subject: [PATCH 010/112] [release-22.0] connpool: fix connection leak during idle connection reopen (#18967) (#18970) Signed-off-by: Arthur Schreiber Co-authored-by: Arthur Schreiber --- go/pools/smartconnpool/pool.go | 24 ++++++-- go/pools/smartconnpool/pool_test.go | 85 +++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 4 deletions(-) diff --git a/go/pools/smartconnpool/pool.go b/go/pools/smartconnpool/pool.go index e227f3a9038..be8d3e05fee 100644 --- a/go/pools/smartconnpool/pool.go +++ b/go/pools/smartconnpool/pool.go @@ -460,9 +460,13 @@ func (pool *ConnPool[C]) pop(stack *connStack[C]) *Pooled[C] { // to expire this connection (even if it's still visible to them), so it's // safe to return it for conn, ok := stack.Pop(); ok; conn, ok = stack.Pop() { - if conn.timeUsed.borrow() { - return conn + if !conn.timeUsed.borrow() { + // Ignore the connection that couldn't be borrowed; + // it's being closed by the idle worker and replaced by a new connection. + continue } + + return conn } return nil } @@ -787,11 +791,23 @@ func (pool *ConnPool[C]) closeIdleResources(now time.Time) { for conn := s.Peek(); conn != nil; conn = conn.next.Load() { if conn.timeUsed.expired(mono, timeout) { pool.Metrics.idleClosed.Add(1) + conn.Close() + pool.closedConn() + // Using context.Background() is fine since MySQL connection already enforces // a connect timeout via the `db_connect_timeout_ms` config param. - if err := pool.connReopen(context.Background(), conn, mono); err != nil { - pool.closedConn() + c, err := pool.getNew(context.Background()) + if err != nil { + // If we couldn't open a new connection, just continue + continue + } + + // opening a new connection might have raced with other goroutines, + // so it's possible that we got back `nil` here + if c != nil { + // Return the new connection to the pool + pool.tryReturnConn(c) } } } diff --git a/go/pools/smartconnpool/pool_test.go b/go/pools/smartconnpool/pool_test.go index a165bc4db20..5d738140742 100644 --- a/go/pools/smartconnpool/pool_test.go +++ b/go/pools/smartconnpool/pool_test.go @@ -1322,3 +1322,88 @@ func TestCloseDuringWaitForConn(t *testing.T) { require.EqualValues(t, 0, state.open.Load()) } } + +// TestIdleTimeoutConnectionLeak checks for leaked connections after idle timeout +func TestIdleTimeoutConnectionLeak(t *testing.T) { + var state TestState + + // Slow connection creation to ensure idle timeout happens during reopening + state.chaos.delayConnect = 300 * time.Millisecond + + p := NewPool(&Config[*TestConn]{ + Capacity: 2, + IdleTimeout: 50 * time.Millisecond, + LogWait: state.LogWait, + }).Open(newConnector(&state), nil) + + getCtx, cancel := context.WithTimeout(t.Context(), 500*time.Millisecond) + defer cancel() + + // Get and return two connections + conn1, err := p.Get(getCtx, nil) + require.NoError(t, err) + + conn2, err := p.Get(getCtx, nil) + require.NoError(t, err) + + p.put(conn1) + p.put(conn2) + + // At this point: Active=2, InUse=0, Available=2 + require.EqualValues(t, 2, p.Active()) + require.EqualValues(t, 0, p.InUse()) + require.EqualValues(t, 2, p.Available()) + + // Wait for idle timeout to kick in and start expiring connections + require.EventuallyWithT(t, func(c *assert.CollectT) { + // Check the actual number of currently open connections + assert.Equal(c, int64(2), state.open.Load()) + // Check the total number of closed connections + assert.Equal(c, int64(1), state.close.Load()) + }, 100*time.Millisecond, 10*time.Millisecond) + + // At this point, the idle timeout worker has expired the connections + // and is trying to reopen them (which takes 300ms due to delayConnect) + + // Try to get connections while they're being reopened + // This should trigger the bug where connections get discarded + for i := 0; i < 2; i++ { + getCtx, cancel := context.WithTimeout(t.Context(), 50*time.Millisecond) + defer cancel() + + conn, err := p.Get(getCtx, nil) + require.NoError(t, err) + + p.put(conn) + } + + // Wait a moment for all reopening to complete + require.EventuallyWithT(t, func(c *assert.CollectT) { + // Check the actual number of currently open connections + require.Equal(c, int64(2), state.open.Load()) + // Check the total number of closed connections + require.Equal(c, int64(2), state.close.Load()) + }, 400*time.Millisecond, 10*time.Millisecond) + + // Check the pool state + assert.Equal(t, int64(2), p.Active()) + assert.Equal(t, int64(0), p.InUse()) + assert.Equal(t, int64(2), p.Available()) + assert.Equal(t, int64(2), p.Metrics.IdleClosed()) + + // Try to close the pool - if there are leaked connections, this will timeout + closeCtx, cancel := context.WithTimeout(t.Context(), 500*time.Millisecond) + defer cancel() + + err = p.CloseWithContext(closeCtx) + require.NoError(t, err) + + // Pool should be completely closed now + assert.Equal(t, int64(0), p.Active()) + assert.Equal(t, int64(0), p.InUse()) + assert.Equal(t, int64(0), p.Available()) + assert.Equal(t, int64(2), p.Metrics.IdleClosed()) + + assert.Equal(t, int64(0), state.open.Load()) + assert.Equal(t, int64(4), state.close.Load()) +} From d634143676250cf015166a49a24e2790325bcb23 Mon Sep 17 00:00:00 2001 From: Tim Vaillancourt Date: Wed, 3 Dec 2025 11:12:25 +0100 Subject: [PATCH 011/112] =?UTF-8?q?[release-22.0]=20Potential=20fix=20for?= =?UTF-8?q?=20code=20scanning=20alert=20no.=203944:=20Database=20query=20b?= =?UTF-8?q?uilt=20=E2=80=A6=20(#18962)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Vaillancourt --- go/vt/vtadmin/api.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/go/vt/vtadmin/api.go b/go/vt/vtadmin/api.go index 6ed5762f96e..29c3043dd60 100644 --- a/go/vt/vtadmin/api.go +++ b/go/vt/vtadmin/api.go @@ -2657,11 +2657,14 @@ func (api *API) VExplain(ctx context.Context, req *vtadminpb.VExplainRequest) (* return nil, err } - if _, ok := stmt.(*sqlparser.VExplainStmt); !ok { + vexplainStmt, ok := stmt.(*sqlparser.VExplainStmt) + if !ok { return nil, vterrors.VT09017("Invalid VExplain statement") } - response, err := c.DB.VExplain(ctx, req.GetSql(), stmt.(*sqlparser.VExplainStmt)) + // Canonicalize the SQL using the AST, to prevent use of raw user input. + canonicalQuery := sqlparser.String(vexplainStmt) + response, err := c.DB.VExplain(ctx, canonicalQuery, vexplainStmt) if err != nil { return nil, err From 4b4ff40cb96a5622b787512fc45a345c21bb2546 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Wed, 3 Dec 2025 13:30:15 +0100 Subject: [PATCH 012/112] [release-22.0] vdiff: do not sort by table name in summary, it is not necessary (#18972) (#18977) Signed-off-by: Nick Van Wiggeren Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- .../command/vreplication/vdiff/vdiff.go | 2 +- go/vt/vtctl/workflow/vdiff.go | 16 +++++++++++ go/vt/vtctl/workflow/vdiff_test.go | 27 +++++++++++++++++++ go/vt/vttablet/tabletmanager/vdiff/schema.go | 2 +- 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/go/cmd/vtctldclient/command/vreplication/vdiff/vdiff.go b/go/cmd/vtctldclient/command/vreplication/vdiff/vdiff.go index 94147fd3550..f980dcf699e 100644 --- a/go/cmd/vtctldclient/command/vreplication/vdiff/vdiff.go +++ b/go/cmd/vtctldclient/command/vreplication/vdiff/vdiff.go @@ -438,7 +438,7 @@ HasMismatch: {{.HasMismatch}} StartedAt: {{.StartedAt}} {{if (eq .State "started")}}Progress: {{printf "%.2f" .Progress.Percentage}}%{{if .Progress.ETA}}, ETA: {{.Progress.ETA}}{{end}}{{end}} {{if .CompletedAt}}CompletedAt: {{.CompletedAt}}{{end}} -{{range $table := .TableSummaryMap}} +{{range $table := .SortedTableSummaries}} Table {{$table.TableName}}: State: {{$table.State}} ProcessedRows: {{$table.RowsCompared}} diff --git a/go/vt/vtctl/workflow/vdiff.go b/go/vt/vtctl/workflow/vdiff.go index 30953868b0b..ab5d50c1489 100644 --- a/go/vt/vtctl/workflow/vdiff.go +++ b/go/vt/vtctl/workflow/vdiff.go @@ -69,6 +69,22 @@ type Summary struct { Progress *vdiff.ProgressReport `json:"Progress,omitempty"` } +// SortedTableSummaries returns the table summaries sorted alphabetically by table name. +// This is used by text templates to display tables in a consistent order. +func (s *Summary) SortedTableSummaries() []TableSummary { + names := make([]string, 0, len(s.TableSummaryMap)) + for name := range s.TableSummaryMap { + names = append(names, name) + } + sort.Strings(names) + + result := make([]TableSummary, 0, len(names)) + for _, name := range names { + result = append(result, s.TableSummaryMap[name]) + } + return result +} + // BuildSummary generates a summary from a vdiff show response. func BuildSummary(keyspace, workflow, uuid string, resp *vtctldatapb.VDiffShowResponse, verbose bool) (*Summary, error) { summary := &Summary{ diff --git a/go/vt/vtctl/workflow/vdiff_test.go b/go/vt/vtctl/workflow/vdiff_test.go index 0da4a3ef480..9c2c5cca77a 100644 --- a/go/vt/vtctl/workflow/vdiff_test.go +++ b/go/vt/vtctl/workflow/vdiff_test.go @@ -34,6 +34,33 @@ import ( vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" ) +func TestSortedTableSummaries(t *testing.T) { + summary := &Summary{ + TableSummaryMap: map[string]TableSummary{ + "zebra": {TableName: "zebra"}, + "apple": {TableName: "apple"}, + "mango": {TableName: "mango"}, + }, + } + + sorted := summary.SortedTableSummaries() + + require.Len(t, sorted, 3) + require.Equal(t, "apple", sorted[0].TableName) + require.Equal(t, "mango", sorted[1].TableName) + require.Equal(t, "zebra", sorted[2].TableName) +} + +func TestSortedTableSummariesEmpty(t *testing.T) { + summary := &Summary{ + TableSummaryMap: map[string]TableSummary{}, + } + + sorted := summary.SortedTableSummaries() + + require.Len(t, sorted, 0) +} + func TestBuildProgressReport(t *testing.T) { now := time.Now() type args struct { diff --git a/go/vt/vttablet/tabletmanager/vdiff/schema.go b/go/vt/vttablet/tabletmanager/vdiff/schema.go index 9fef975e1e0..bb238cb8a7a 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/schema.go +++ b/go/vt/vttablet/tabletmanager/vdiff/schema.go @@ -40,7 +40,7 @@ const ( vd.started_at as started_at, vdt.rows_compared as rows_compared, vd.completed_at as completed_at, IF(vdt.mismatch = 1, 1, 0) as has_mismatch, vdt.report as report from _vt.vdiff as vd left join _vt.vdiff_table as vdt on (vd.id = vdt.vdiff_id) - where vd.id = %a order by table_name` + where vd.id = %a` // sqlUpdateVDiffState has a penultimate placeholder for any additional columns you want to update, e.g. `, foo = 1`. // It also truncates the error if needed to ensure that we can save the state when the error text is very long. sqlUpdateVDiffState = "update _vt.vdiff set state = %s, last_error = left(%s, 1024) %s where id = %d" From 79ea2e68b2342105ee6e1cf00098fe455956d490 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Thu, 4 Dec 2025 15:55:21 -0500 Subject: [PATCH 013/112] [release-22.0] VDiff: Handle the case where a workflow's table has been dropped on the source (#18985) (#18988) Signed-off-by: Matt Lord Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- .../tabletmanager/vdiff/table_differ.go | 7 ++++ .../tabletmanager/vdiff/table_differ_test.go | 32 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/go/vt/vttablet/tabletmanager/vdiff/table_differ.go b/go/vt/vttablet/tabletmanager/vdiff/table_differ.go index f62bd734fb8..f63fced008d 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/table_differ.go +++ b/go/vt/vttablet/tabletmanager/vdiff/table_differ.go @@ -944,6 +944,13 @@ func (td *tableDiffer) getSourcePKCols() error { return vterrors.Wrapf(err, "failed to get the schema for table %s from source tablet %s", td.table.Name, topoproto.TabletAliasString(sourceTablet.Tablet.Alias)) } + if len(sourceSchema.TableDefinitions) == 0 { + // The table no longer exists on the source. Any rows that exist on the target will be + // reported as extra rows. + log.Warningf("The %s table was not found on source tablet %s during VDiff for the %s workflow; any rows on the target will be reported as extra", + td.table.Name, topoproto.TabletAliasString(sourceTablet.Tablet.Alias), td.wd.ct.workflow) + return nil + } sourceTable := sourceSchema.TableDefinitions[0] if len(sourceTable.PrimaryKeyColumns) == 0 { // We use the columns from a PKE if there is one. diff --git a/go/vt/vttablet/tabletmanager/vdiff/table_differ_test.go b/go/vt/vttablet/tabletmanager/vdiff/table_differ_test.go index 03ba218cd66..2ed23168235 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/table_differ_test.go +++ b/go/vt/vttablet/tabletmanager/vdiff/table_differ_test.go @@ -129,3 +129,35 @@ func TestUpdateTableProgress(t *testing.T) { }) } } + +func TestGetSourcePKCols_TableDroppedOnSource(t *testing.T) { + tvde := newTestVDiffEnv(t) + defer tvde.close() + + ct := tvde.createController(t, 1) + + table := &tabletmanagerdatapb.TableDefinition{ + Name: "dropped_table", + Columns: []string{"c1", "c2"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2", "int64|varchar"), + } + + tvde.tmc.schema = &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{}, + } + + td := &tableDiffer{ + wd: &workflowDiffer{ + ct: ct, + }, + table: table, + tablePlan: &tablePlan{ + table: table, + }, + } + + err := td.getSourcePKCols() + require.NoError(t, err) + require.Nil(t, td.tablePlan.sourcePkCols) +} From cdb878fac2c732f1682fa999d2d232b18a0d8c38 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Fri, 5 Dec 2025 11:56:16 +0100 Subject: [PATCH 014/112] [release-22.0] CI: Improve reliability of codecov workflow with larger runner (#18992) (#18994) Signed-off-by: Matt Lord Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- .github/workflows/codecov.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 7815ec3c377..6778d44eed9 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -16,7 +16,7 @@ permissions: read-all jobs: test: name: Code Coverage - runs-on: ubuntu-24.04 + runs-on: oracle-vm-8cpu-32gb-x86-64 steps: - name: Check out code From 4fe6b22ecf8cda16f5122877a3702cd360dd33de Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Thu, 11 Dec 2025 11:21:10 +0000 Subject: [PATCH 015/112] [release-22.0] Change connection pool idle expiration logic (#19004) (#19013) Signed-off-by: Arthur Schreiber Co-authored-by: Arthur Schreiber Co-authored-by: Arthur Schreiber --- go/pools/smartconnpool/pool.go | 87 ++++++++++++++++++------- go/pools/smartconnpool/pool_test.go | 98 +++++++++++++++++++++++++++-- 2 files changed, 156 insertions(+), 29 deletions(-) diff --git a/go/pools/smartconnpool/pool.go b/go/pools/smartconnpool/pool.go index be8d3e05fee..cca706bc1c2 100644 --- a/go/pools/smartconnpool/pool.go +++ b/go/pools/smartconnpool/pool.go @@ -781,35 +781,74 @@ func (pool *ConnPool[C]) closeIdleResources(now time.Time) { mono := monotonicFromTime(now) closeInStack := func(s *connStack[C]) { - // Do a read-only best effort iteration of all the connection in this - // stack and atomically attempt to mark them as expired. - // Any connections that are marked as expired are _not_ removed from - // the stack; it's generally unsafe to remove nodes from the stack - // besides the head. When clients pop from the stack, they'll immediately - // notice the expired connection and ignore it. - // see: timestamp.expired - for conn := s.Peek(); conn != nil; conn = conn.next.Load() { - if conn.timeUsed.expired(mono, timeout) { - pool.Metrics.idleClosed.Add(1) + conn, ok := s.Pop() + if !ok { + // Early return to skip allocating slices when the stack is empty + return + } - conn.Close() - pool.closedConn() + activeConnections := pool.Active() + + // Only expire up to ~half of the active connections at a time. This should + // prevent us from closing too many connections in one go which could lead to + // a lot of `.Get` calls being added to the waitlist if there's a sudden spike + // coming in _after_ connections were popped off the stack but _before_ being + // returned back to the pool. This is unlikely to happen, but better safe than sorry. + // + // We always expire at least one connection per stack per iteration to ensure + // that idle connections are eventually closed even in small pools. + // + // We will expire any additional connections in the next iteration of the idle closer. + expiredConnections := make([]*Pooled[C], 0, max(activeConnections/2, 1)) + validConnections := make([]*Pooled[C], 0, activeConnections) + + // Pop out connections from the stack until we get a `nil` connection + for ok { + if conn.timeUsed.expired(mono, timeout) { + expiredConnections = append(expiredConnections, conn) - // Using context.Background() is fine since MySQL connection already enforces - // a connect timeout via the `db_connect_timeout_ms` config param. - c, err := pool.getNew(context.Background()) - if err != nil { - // If we couldn't open a new connection, just continue - continue + if len(expiredConnections) == cap(expiredConnections) { + // We have collected enough connections for this iteration to expire + break } + } else { + validConnections = append(validConnections, conn) + } - // opening a new connection might have raced with other goroutines, - // so it's possible that we got back `nil` here - if c != nil { - // Return the new connection to the pool - pool.tryReturnConn(c) - } + conn, ok = s.Pop() + } + + // Return all the valid connections back to waiters or the stack + // + // The order here is not important - because we can't guarantee to + // restore the order we got the connections out of the stack anyway. + // + // If we return the connections in the order popped off the stack: + // * waiters will get the newest connection first + // * stack will have the oldest connections at the top of the stack. + // + // If we return the connections in reverse order: + // * waiters will get the oldest connection first + // * stack will have the newest connections at the top of the stack. + // + // Neither of these is better or worse than the other. + for _, conn := range validConnections { + pool.tryReturnConn(conn) + } + + // Close all the expired connections and open new ones to replace them + for _, conn := range expiredConnections { + pool.Metrics.idleClosed.Add(1) + + conn.Close() + + err := pool.connReopen(context.Background(), conn, mono) + if err != nil { + pool.closedConn() + continue } + + pool.tryReturnConn(conn) } } diff --git a/go/pools/smartconnpool/pool_test.go b/go/pools/smartconnpool/pool_test.go index 5d738140742..54103ee0279 100644 --- a/go/pools/smartconnpool/pool_test.go +++ b/go/pools/smartconnpool/pool_test.go @@ -1367,16 +1367,25 @@ func TestIdleTimeoutConnectionLeak(t *testing.T) { // Try to get connections while they're being reopened // This should trigger the bug where connections get discarded + wg := sync.WaitGroup{} + for i := 0; i < 2; i++ { - getCtx, cancel := context.WithTimeout(t.Context(), 50*time.Millisecond) - defer cancel() + wg.Add(1) + go func() { + defer wg.Done() - conn, err := p.Get(getCtx, nil) - require.NoError(t, err) + getCtx, cancel := context.WithTimeout(t.Context(), 300*time.Millisecond) + defer cancel() - p.put(conn) + conn, err := p.Get(getCtx, nil) + require.NoError(t, err) + + p.put(conn) + }() } + wg.Wait() + // Wait a moment for all reopening to complete require.EventuallyWithT(t, func(c *assert.CollectT) { // Check the actual number of currently open connections @@ -1407,3 +1416,82 @@ func TestIdleTimeoutConnectionLeak(t *testing.T) { assert.Equal(t, int64(0), state.open.Load()) assert.Equal(t, int64(4), state.close.Load()) } + +func TestIdleTimeoutDoesntLeaveLingeringConnection(t *testing.T) { + var state TestState + + ctx := context.Background() + p := NewPool(&Config[*TestConn]{ + Capacity: 10, + IdleTimeout: 50 * time.Millisecond, + LogWait: state.LogWait, + }).Open(newConnector(&state), nil) + + defer p.Close() + + var conns []*Pooled[*TestConn] + for i := 0; i < 10; i++ { + conn, err := p.Get(ctx, nil) + require.NoError(t, err) + conns = append(conns, conn) + } + + for _, conn := range conns { + p.put(conn) + } + + require.EqualValues(t, 10, p.Active()) + require.EqualValues(t, 10, p.Available()) + + // Wait a bit for the idle timeout worker to refresh connections + assert.Eventually(t, func() bool { + return p.Metrics.IdleClosed() > 10 + }, 500*time.Millisecond, 10*time.Millisecond, "Expected at least 10 connections to be closed by idle timeout") + + // Verify that new connections were created to replace the closed ones + require.EqualValues(t, 10, p.Active()) + require.EqualValues(t, 10, p.Available()) + + // Count how many connections in the stack are closed + totalInStack := 0 + for conn := p.clean.Peek(); conn != nil; conn = conn.next.Load() { + totalInStack++ + } + + require.LessOrEqual(t, totalInStack, 10) +} + +func BenchmarkPoolCleanupIdleConnectionsPerformanceNoIdleConnections(b *testing.B) { + var state TestState + + capacity := 1000 + + p := NewPool(&Config[*TestConn]{ + Capacity: int64(capacity), + IdleTimeout: 30 * time.Second, + LogWait: state.LogWait, + }).Open(newConnector(&state), nil) + defer p.Close() + + // Fill the pool + connections := make([]*Pooled[*TestConn], 0, capacity) + for range capacity { + conn, err := p.Get(context.Background(), nil) + if err != nil { + b.Fatal(err) + } + + connections = append(connections, conn) + } + + // Return all connections to the pool + for _, conn := range connections { + conn.Recycle() + } + + b.ResetTimer() + + for b.Loop() { + p.closeIdleResources(time.Now()) + } +} From d5b5f0840ab9351b94639bb4e536d7fd7f417b4d Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Mon, 15 Dec 2025 11:03:51 -0500 Subject: [PATCH 016/112] [release-22.0] `ci`: use `etcd` v3.5.25, add retries (#19015) (#19021) Signed-off-by: Tim Vaillancourt Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Tim Vaillancourt --- .github/workflows/codecov.yml | 4 ++-- .github/workflows/unit_race.yml | 4 ++-- .github/workflows/unit_race_evalengine.yml | 4 ++-- .../workflows/unit_test_evalengine_mysql57.yml | 4 ++-- .../workflows/unit_test_evalengine_mysql80.yml | 4 ++-- .../workflows/unit_test_evalengine_mysql84.yml | 4 ++-- .github/workflows/unit_test_mysql57.yml | 4 ++-- .github/workflows/unit_test_mysql80.yml | 4 ++-- .github/workflows/unit_test_mysql84.yml | 4 ++-- build.env | 2 +- docker/mini/install_mini_dependencies.sh | 2 +- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- test/templates/unit_test.tpl | 4 ++-- 14 files changed, 34 insertions(+), 34 deletions(-) diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 6778d44eed9..69bfef8ce77 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -66,8 +66,8 @@ jobs: sudo apt-get install -y make unzip g++ curl git wget ant openjdk-11-jdk mkdir -p dist bin - curl -s -L https://github.com/coreos/etcd/releases/download/v3.5.17/etcd-v3.5.17-linux-amd64.tar.gz | tar -zxC dist - mv dist/etcd-v3.5.17-linux-amd64/{etcd,etcdctl} bin/ + curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist + mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/ go mod download go install golang.org/x/tools/cmd/goimports@latest diff --git a/.github/workflows/unit_race.yml b/.github/workflows/unit_race.yml index e6d68e34aec..22560c236b5 100644 --- a/.github/workflows/unit_race.yml +++ b/.github/workflows/unit_race.yml @@ -85,8 +85,8 @@ jobs: sudo apt-get -qq install -y make unzip g++ curl git wget ant openjdk-11-jdk mkdir -p dist bin - curl -s -L https://github.com/coreos/etcd/releases/download/v3.5.17/etcd-v3.5.17-linux-amd64.tar.gz | tar -zxC dist - mv dist/etcd-v3.5.17-linux-amd64/{etcd,etcdctl} bin/ + curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist + mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/ go mod download go install golang.org/x/tools/cmd/goimports@latest diff --git a/.github/workflows/unit_race_evalengine.yml b/.github/workflows/unit_race_evalengine.yml index c48073f7a78..803595c22cf 100644 --- a/.github/workflows/unit_race_evalengine.yml +++ b/.github/workflows/unit_race_evalengine.yml @@ -85,8 +85,8 @@ jobs: sudo apt-get -qq install -y make unzip g++ curl git wget ant openjdk-11-jdk mkdir -p dist bin - curl -s -L https://github.com/coreos/etcd/releases/download/v3.5.17/etcd-v3.5.17-linux-amd64.tar.gz | tar -zxC dist - mv dist/etcd-v3.5.17-linux-amd64/{etcd,etcdctl} bin/ + curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist + mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/ go mod download go install golang.org/x/tools/cmd/goimports@latest diff --git a/.github/workflows/unit_test_evalengine_mysql57.yml b/.github/workflows/unit_test_evalengine_mysql57.yml index a100c3a5485..021ee59839d 100644 --- a/.github/workflows/unit_test_evalengine_mysql57.yml +++ b/.github/workflows/unit_test_evalengine_mysql57.yml @@ -85,8 +85,8 @@ jobs: sudo apt-get install -y make unzip g++ curl git wget ant openjdk-11-jdk mkdir -p dist bin - curl -s -L https://github.com/coreos/etcd/releases/download/v3.5.17/etcd-v3.5.17-linux-amd64.tar.gz | tar -zxC dist - mv dist/etcd-v3.5.17-linux-amd64/{etcd,etcdctl} bin/ + curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist + mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/ go mod download go install golang.org/x/tools/cmd/goimports@latest diff --git a/.github/workflows/unit_test_evalengine_mysql80.yml b/.github/workflows/unit_test_evalengine_mysql80.yml index 217c8634b0e..e73e593975f 100644 --- a/.github/workflows/unit_test_evalengine_mysql80.yml +++ b/.github/workflows/unit_test_evalengine_mysql80.yml @@ -85,8 +85,8 @@ jobs: sudo apt-get install -y make unzip g++ curl git wget ant openjdk-11-jdk mkdir -p dist bin - curl -s -L https://github.com/coreos/etcd/releases/download/v3.5.17/etcd-v3.5.17-linux-amd64.tar.gz | tar -zxC dist - mv dist/etcd-v3.5.17-linux-amd64/{etcd,etcdctl} bin/ + curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist + mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/ go mod download go install golang.org/x/tools/cmd/goimports@latest diff --git a/.github/workflows/unit_test_evalengine_mysql84.yml b/.github/workflows/unit_test_evalengine_mysql84.yml index 960ddb05878..fd1dca75ef9 100644 --- a/.github/workflows/unit_test_evalengine_mysql84.yml +++ b/.github/workflows/unit_test_evalengine_mysql84.yml @@ -85,8 +85,8 @@ jobs: sudo apt-get install -y make unzip g++ curl git wget ant openjdk-11-jdk mkdir -p dist bin - curl -s -L https://github.com/coreos/etcd/releases/download/v3.5.17/etcd-v3.5.17-linux-amd64.tar.gz | tar -zxC dist - mv dist/etcd-v3.5.17-linux-amd64/{etcd,etcdctl} bin/ + curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist + mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/ go mod download go install golang.org/x/tools/cmd/goimports@latest diff --git a/.github/workflows/unit_test_mysql57.yml b/.github/workflows/unit_test_mysql57.yml index a5d7b5c9f9c..d4480b4b441 100644 --- a/.github/workflows/unit_test_mysql57.yml +++ b/.github/workflows/unit_test_mysql57.yml @@ -85,8 +85,8 @@ jobs: sudo apt-get install -y make unzip g++ curl git wget ant openjdk-11-jdk mkdir -p dist bin - curl -s -L https://github.com/coreos/etcd/releases/download/v3.5.17/etcd-v3.5.17-linux-amd64.tar.gz | tar -zxC dist - mv dist/etcd-v3.5.17-linux-amd64/{etcd,etcdctl} bin/ + curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist + mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/ go mod download go install golang.org/x/tools/cmd/goimports@latest diff --git a/.github/workflows/unit_test_mysql80.yml b/.github/workflows/unit_test_mysql80.yml index 9d0cb30355a..12c635976f7 100644 --- a/.github/workflows/unit_test_mysql80.yml +++ b/.github/workflows/unit_test_mysql80.yml @@ -85,8 +85,8 @@ jobs: sudo apt-get install -y make unzip g++ curl git wget ant openjdk-11-jdk mkdir -p dist bin - curl -s -L https://github.com/coreos/etcd/releases/download/v3.5.17/etcd-v3.5.17-linux-amd64.tar.gz | tar -zxC dist - mv dist/etcd-v3.5.17-linux-amd64/{etcd,etcdctl} bin/ + curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist + mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/ go mod download go install golang.org/x/tools/cmd/goimports@latest diff --git a/.github/workflows/unit_test_mysql84.yml b/.github/workflows/unit_test_mysql84.yml index 56ea2e3035a..69c6550b38d 100644 --- a/.github/workflows/unit_test_mysql84.yml +++ b/.github/workflows/unit_test_mysql84.yml @@ -85,8 +85,8 @@ jobs: sudo apt-get install -y make unzip g++ curl git wget ant openjdk-11-jdk mkdir -p dist bin - curl -s -L https://github.com/coreos/etcd/releases/download/v3.5.17/etcd-v3.5.17-linux-amd64.tar.gz | tar -zxC dist - mv dist/etcd-v3.5.17-linux-amd64/{etcd,etcdctl} bin/ + curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist + mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/ go mod download go install golang.org/x/tools/cmd/goimports@latest diff --git a/build.env b/build.env index 05998eb420f..140c27f5cb9 100755 --- a/build.env +++ b/build.env @@ -29,7 +29,7 @@ export VTDATAROOT="${VTDATAROOT:-${VTROOT}/vtdataroot}" export PATH="$PWD/bin:$PATH" export PROTOC_VER=21.3 export ZK_VER=${ZK_VERSION:-3.8.0} -export ETCD_VER=v3.5.17 +export ETCD_VER=v3.5.25 export CONSUL_VER=1.11.4 export TOXIPROXY_VER=v2.7.0 diff --git a/docker/mini/install_mini_dependencies.sh b/docker/mini/install_mini_dependencies.sh index 754249b7d49..f4eaf8c2e88 100755 --- a/docker/mini/install_mini_dependencies.sh +++ b/docker/mini/install_mini_dependencies.sh @@ -8,7 +8,7 @@ set -euo pipefail # Install etcd -ETCD_VER=v3.5.17 +ETCD_VER=v3.5.25 DOWNLOAD_URL=https://storage.googleapis.com/etcd curl -k -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz diff --git a/go.mod b/go.mod index 6313963225b..4df3b1013dd 100644 --- a/go.mod +++ b/go.mod @@ -62,9 +62,9 @@ require ( github.com/uber/jaeger-lib v2.4.1+incompatible // indirect github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 github.com/z-division/go-zookeeper v1.0.0 - go.etcd.io/etcd/api/v3 v3.5.19 - go.etcd.io/etcd/client/pkg/v3 v3.5.19 - go.etcd.io/etcd/client/v3 v3.5.19 + go.etcd.io/etcd/api/v3 v3.5.25 + go.etcd.io/etcd/client/pkg/v3 v3.5.25 + go.etcd.io/etcd/client/v3 v3.5.25 go.uber.org/mock v0.5.0 golang.org/x/crypto v0.36.0 // indirect golang.org/x/mod v0.24.0 // indirect @@ -77,7 +77,7 @@ require ( golang.org/x/tools v0.31.0 google.golang.org/api v0.226.0 google.golang.org/genproto v0.0.0-20250313205543-e70fdf4c4cb4 // indirect - google.golang.org/grpc v1.71.0 + google.golang.org/grpc v1.71.1 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 google.golang.org/grpc/examples v0.0.0-20250204041003-947e2a4be2ba google.golang.org/protobuf v1.36.5 diff --git a/go.sum b/go.sum index 2285363010f..fcb9f3c158b 100644 --- a/go.sum +++ b/go.sum @@ -558,12 +558,12 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/z-division/go-zookeeper v1.0.0 h1:ULsCj0nP6+U1liDFWe+2oEF6o4amixoDcDlwEUghVUY= github.com/z-division/go-zookeeper v1.0.0/go.mod h1:6X4UioQXpvyezJJl4J9NHAJKsoffCwy5wCaaTktXjOA= -go.etcd.io/etcd/api/v3 v3.5.19 h1:w3L6sQZGsWPuBxRQ4m6pPP3bVUtV8rjW033EGwlr0jw= -go.etcd.io/etcd/api/v3 v3.5.19/go.mod h1:QqKGViq4KTgOG43dr/uH0vmGWIaoJY3ggFi6ZH0TH/U= -go.etcd.io/etcd/client/pkg/v3 v3.5.19 h1:9VsyGhg0WQGjDWWlDI4VuaS9PZJGNbPkaHEIuLwtixk= -go.etcd.io/etcd/client/pkg/v3 v3.5.19/go.mod h1:qaOi1k4ZA9lVLejXNvyPABrVEe7VymMF2433yyRQ7O0= -go.etcd.io/etcd/client/v3 v3.5.19 h1:+4byIz6ti3QC28W0zB0cEZWwhpVHXdrKovyycJh1KNo= -go.etcd.io/etcd/client/v3 v3.5.19/go.mod h1:FNzyinmMIl0oVsty1zA3hFeUrxXI/JpEnz4sG+POzjU= +go.etcd.io/etcd/api/v3 v3.5.25 h1:8w6i1wcFJhW6eWiEr9yJeptEiv42vyR/ArIX7PF8580= +go.etcd.io/etcd/api/v3 v3.5.25/go.mod h1:ZIZh7LPgjzvjycAVgMJnx9WGkAMERMR8VOP+u9Ov2SY= +go.etcd.io/etcd/client/pkg/v3 v3.5.25 h1:MtOZRHk3GAUAPc9Sfpj+s7bWGgbjJ6hjiwMjQ2DSMUY= +go.etcd.io/etcd/client/pkg/v3 v3.5.25/go.mod h1:WTiGlZqg2WSdqjF8xRycqyHZTx2YmyqGcdTwKgQtJBk= +go.etcd.io/etcd/client/v3 v3.5.25 h1:Secqbl/DeksaY8Tg+984FDdRR8XWnxgXksjPrSFm5Lc= +go.etcd.io/etcd/client/v3 v3.5.25/go.mod h1:6QqI2Y9iqtIaUTS55285OyZqpF1QLCghATMEx1mhS0I= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/contrib/detectors/gcp v1.35.0 h1:bGvFt68+KTiAKFlacHW6AhA56GF2rS0bdD3aJYEnmzA= @@ -741,8 +741,8 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg= -google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= +google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI= +google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 h1:F29+wU6Ee6qgu9TddPgooOdaqsxTMunOoj8KA5yuS5A= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1/go.mod h1:5KF+wpkbTSbGcR9zteSqZV6fqFOWBl4Yde8En8MryZA= google.golang.org/grpc/examples v0.0.0-20250204041003-947e2a4be2ba h1:w92RAwwmP8PEc4O6JrGzSoUrL/eE53n2wIG7NAcedM8= diff --git a/test/templates/unit_test.tpl b/test/templates/unit_test.tpl index 3b3ec466a6e..2b2de08416e 100644 --- a/test/templates/unit_test.tpl +++ b/test/templates/unit_test.tpl @@ -98,8 +98,8 @@ jobs: sudo apt-get install -y make unzip g++ curl git wget ant openjdk-11-jdk mkdir -p dist bin - curl -s -L https://github.com/coreos/etcd/releases/download/v3.5.17/etcd-v3.5.17-linux-amd64.tar.gz | tar -zxC dist - mv dist/etcd-v3.5.17-linux-amd64/{etcd,etcdctl} bin/ + curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist + mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/ go mod download go install golang.org/x/tools/cmd/goimports@latest From 263ef1b22b5dc3d443d649d33afec7c5bbd00a29 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Mon, 22 Dec 2025 16:03:55 +0100 Subject: [PATCH 017/112] [release-22.0] Bump org.apache.logging.log4j:log4j-core from 2.24.1 to 2.25.3 in /java (#19063) (#19065) Signed-off-by: dependabot[bot] Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- java/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/pom.xml b/java/pom.xml index 74c2fa37bf2..544d8fa7e78 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -75,7 +75,7 @@ 3.25.5 3.25.5 3.0.0 - 2.24.1 + 2.25.3 From cf51305fff67b584ab97ac79a3ce7d0a8aff09a1 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 13:49:29 -0500 Subject: [PATCH 018/112] [release-22.0] Skip flaky `TestRedial` test (#19106) (#19107) Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- go/vt/vtadmin/vtctldclient/proxy_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/go/vt/vtadmin/vtctldclient/proxy_test.go b/go/vt/vtadmin/vtctldclient/proxy_test.go index 520ab48ab1d..c164839ec50 100644 --- a/go/vt/vtadmin/vtctldclient/proxy_test.go +++ b/go/vt/vtadmin/vtctldclient/proxy_test.go @@ -123,6 +123,8 @@ func (d *testdisco) DiscoverVtctldAddrs(ctx context.Context, tags []string) ([]s // TestRedial tests that vtadmin-api is able to recover from a lost connection to // a vtctld by rediscovering and redialing a new one. func TestRedial(t *testing.T) { + t.Skip("flaky test, gRPC reconnection timing is unreliable") + // Initialize vtctld #1 listener1, server1, err := initVtctldServer() require.NoError(t, err) From 80ad2df263a9842972177831d2a04934d92ad051 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 12:05:49 -0800 Subject: [PATCH 019/112] [release-22.0] binlog_json: fix opaque value parsing to read variable-length (#19102) (#19109) Signed-off-by: Nick Van Wiggeren Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- go/mysql/binlog/binlog_json.go | 35 ++++++++++++++--- go/mysql/binlog/binlog_json_test.go | 60 +++++++++++++++++++++++------ 2 files changed, 77 insertions(+), 18 deletions(-) diff --git a/go/mysql/binlog/binlog_json.go b/go/mysql/binlog/binlog_json.go index 51b4fef0ef8..f647a4f130e 100644 --- a/go/mysql/binlog/binlog_json.go +++ b/go/mysql/binlog/binlog_json.go @@ -449,11 +449,25 @@ func binparserLiteral(_ jsonDataType, data []byte, pos int) (node *json.Value, e // other types are stored as catch-all opaque types: documentation on these is scarce. // we currently know about (and support) date/time/datetime/decimal. func binparserOpaque(_ jsonDataType, data []byte, pos int) (node *json.Value, err error) { - dataType := data[pos] - start := 3 // account for length of stored value - end := start + 8 // all currently supported opaque data types are 8 bytes in size + if pos >= len(data) { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "opaque JSON field value missing type at position %d", pos) + } + typePos := pos + dataType := data[typePos] + pos = typePos + 1 + if pos >= len(data) { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "opaque JSON field value missing length at position %d", typePos) + } + length, start := readVariableLength(data, pos) + end := start + length + if start > len(data) || end > len(data) { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "opaque JSON field value length %d exceeds available bytes", length) + } switch dataType { case TypeDate: + if length < 8 { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "opaque date length %d is too short", length) + } raw := binary.LittleEndian.Uint64(data[start:end]) value := raw >> 24 yearMonth := (value >> 22) & 0x01ffff // 17 bits starting at 22nd @@ -463,6 +477,9 @@ func binparserOpaque(_ jsonDataType, data []byte, pos int) (node *json.Value, er dateString := fmt.Sprintf("%04d-%02d-%02d", year, month, day) node = json.NewDate(dateString) case TypeTime2, TypeTime: + if length < 8 { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "opaque time length %d is too short", length) + } raw := binary.LittleEndian.Uint64(data[start:end]) value := raw >> 24 hour := (value >> 12) & 0x03ff // 10 bits starting at 12th @@ -472,6 +489,9 @@ func binparserOpaque(_ jsonDataType, data []byte, pos int) (node *json.Value, er timeString := fmt.Sprintf("%02d:%02d:%02d.%06d", hour, minute, second, microSeconds) node = json.NewTime(timeString) case TypeDateTime2, TypeDateTime, TypeTimestamp2, TypeTimestamp: + if length < 8 { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "opaque datetime length %d is too short", length) + } raw := binary.LittleEndian.Uint64(data[start:end]) value := raw >> 24 yearMonth := (value >> 22) & 0x01ffff // 17 bits starting at 22nd @@ -485,6 +505,9 @@ func binparserOpaque(_ jsonDataType, data []byte, pos int) (node *json.Value, er timeString := fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d.%06d", year, month, day, hour, minute, second, microSeconds) node = json.NewDateTime(timeString) case TypeDecimal, TypeNewDecimal: + if length < 2 { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "opaque decimal length %d is too short", length) + } decimalData := data[start:end] precision := decimalData[0] scale := decimalData[1] @@ -495,11 +518,11 @@ func binparserOpaque(_ jsonDataType, data []byte, pos int) (node *json.Value, er } node = json.NewNumber(val.ToString(), json.NumberTypeDecimal) case TypeVarchar, TypeVarString, TypeString, TypeBlob, TypeTinyBlob, TypeMediumBlob, TypeLongBlob: - node = json.NewBlob(string(data[pos+1:])) + node = json.NewBlob(string(data[start:end])) case TypeBit: - node = json.NewBit(string(data[pos+1:])) + node = json.NewBit(string(data[start:end])) default: - node = json.NewOpaqueValue(string(data[pos+1:])) + node = json.NewOpaqueValue(string(data[start:end])) } return node, nil } diff --git a/go/mysql/binlog/binlog_json_test.go b/go/mysql/binlog/binlog_json_test.go index 5652b58567e..59cfffcbab9 100644 --- a/go/mysql/binlog/binlog_json_test.go +++ b/go/mysql/binlog/binlog_json_test.go @@ -232,19 +232,24 @@ func TestBinaryJSON(t *testing.T) { expected: json.NewNumber("123456789.1234", json.NumberTypeDecimal), }, { - name: `bit literal [2 202 254]`, + name: `small decimal "1.99"`, + data: []byte{15, 246, 4, 3, 2, 0x81, 0x63}, + expected: json.NewNumber("1.99", json.NumberTypeDecimal), + }, + { + name: `bit literal 0xCAFE`, data: []byte{15, 16, 2, 202, 254}, - expected: json.NewBit(string([]byte{2, 202, 254})), + expected: json.NewBit(string([]byte{202, 254})), }, { - name: `opaque string [2 202 254]`, + name: `opaque string 0xCAFE`, data: []byte{15, 15, 2, 202, 254}, - expected: json.NewBlob(string([]byte{2, 202, 254})), + expected: json.NewBlob(string([]byte{202, 254})), }, { - name: `opaque blob [2 202 254]`, + name: `opaque blob 0xCAFE`, data: []byte{15, 252, 2, 202, 254}, - expected: json.NewBlob(string([]byte{2, 202, 254})), + expected: json.NewBlob(string([]byte{202, 254})), }, } for _, tc := range testcases { @@ -256,6 +261,36 @@ func TestBinaryJSON(t *testing.T) { } } +func TestBinaryJSONOpaqueErrors(t *testing.T) { + testcases := []struct { + name string + data []byte + expectedErr string + }{ + { + name: "opaque length exceeds payload", + data: []byte{15, 252, 2, 202}, + expectedErr: "opaque JSON field value length 2 exceeds available bytes", + }, + { + name: "opaque date too short", + data: []byte{15, 10, 4, 0, 0, 0, 0}, + expectedErr: "opaque date length 4 is too short", + }, + { + name: "opaque decimal too short", + data: []byte{15, 246, 1, 0x01}, + expectedErr: "opaque decimal length 1 is too short", + }, + } + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + _, err := ParseBinaryJSON(tc.data) + require.ErrorContains(t, err, tc.expectedErr) + }) + } +} + func TestMarshalJSONToSQL(t *testing.T) { testcases := []struct { name string @@ -443,19 +478,20 @@ func TestMarshalJSONToSQL(t *testing.T) { expected: `CAST(123456789.1234 as JSON)`, }, { - name: `bit literal [2 202 254]`, + // 0xCAFE = 51966 = binary 1100101011111110 (16 bits) + name: `bit literal 0xCAFE`, data: []byte{15, 16, 2, 202, 254}, - expected: `CAST(b'101100101011111110' as JSON)`, + expected: `CAST(b'1100101011111110' as JSON)`, }, { - name: `opaque string [2 202 254]`, + name: `opaque string 0xCAFE`, data: []byte{15, 15, 2, 202, 254}, - expected: `CAST(x'02CAFE' as JSON)`, + expected: `CAST(x'CAFE' as JSON)`, }, { - name: `opaque blob [2 202 254]`, + name: `opaque blob 0xCAFE`, data: []byte{15, 252, 2, 202, 254}, - expected: `CAST(x'02CAFE' as JSON)`, + expected: `CAST(x'CAFE' as JSON)`, }, } for _, tc := range testcases { From bb4d0b1ba19ffe2fa7f691a738ff5600d6ec0a4c Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Sat, 10 Jan 2026 01:20:46 +0000 Subject: [PATCH 020/112] [release-22.0] vschema revert: initialize as nil so that nil checks do not pass later (#19114) (#19117) Signed-off-by: Nick Van Wiggeren Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- go/vt/vtctl/workflow/materializer_test.go | 205 ++++++++++++++++++++++ go/vt/vtctl/workflow/server.go | 15 +- 2 files changed, 213 insertions(+), 7 deletions(-) diff --git a/go/vt/vtctl/workflow/materializer_test.go b/go/vt/vtctl/workflow/materializer_test.go index c28beb933e8..e16a6ab2515 100644 --- a/go/vt/vtctl/workflow/materializer_test.go +++ b/go/vt/vtctl/workflow/materializer_test.go @@ -20,6 +20,7 @@ import ( "context" "errors" "fmt" + "path" "slices" "strings" "testing" @@ -1014,6 +1015,210 @@ func TestMoveTablesNoRoutingRules(t *testing.T) { require.Zerof(t, len(rr.Rules), "routing rules should be empty, found %+v", rr.Rules) } +func TestMoveTablesCreateShardedVSchemaRollback(t *testing.T) { + ms := &vtctldatapb.MaterializeSettings{ + Workflow: "workflow", + SourceKeyspace: "sourceks", + TargetKeyspace: "targetks", + TableSettings: []*vtctldatapb.TableMaterializeSettings{{ + TargetTable: "t1", + SourceExpression: "select * from t1", + }}, + } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + env := newTestMaterializerEnv(t, ctx, ms, []string{"-"}, []string{"-"}) + defer env.close() + + targetVSchema := &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "hash": { + Type: "hash", + }, + }, + Tables: map[string]*vschemapb.Table{ + "t1": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Name: "hash", + Column: "id", + }}, + }, + }, + } + err := env.ws.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: ms.TargetKeyspace, + Keyspace: targetVSchema, + }) + require.NoError(t, err) + + env.tmc.expectFetchAsAllPrivsQuery(startingTargetTabletUID, getNonEmptyTable, &sqltypes.Result{}) + + sourceDeleteQuery := fmt.Sprintf(sqlDeleteWorkflow, encodeString("vt_sourceks"), encodeString(ReverseWorkflowName(ms.Workflow))) + targetDeleteQuery := fmt.Sprintf(sqlDeleteWorkflow, encodeString("vt_targetks"), encodeString(ms.Workflow)) + env.tmc.expectVRQuery(startingSourceTabletUID, sourceDeleteQuery, &sqltypes.Result{}) + env.tmc.expectVRQuery(startingTargetTabletUID, targetDeleteQuery, &sqltypes.Result{}) + + readCalls := 0 + env.tmc.readVReplicationWorkflow = func(ctx context.Context, tablet *topodatapb.Tablet, request *tabletmanagerdatapb.ReadVReplicationWorkflowRequest) (*tabletmanagerdatapb.ReadVReplicationWorkflowResponse, error) { + readCalls++ + if readCalls == 1 { + return &tabletmanagerdatapb.ReadVReplicationWorkflowResponse{ + Workflow: request.Workflow, + WorkflowType: binlogdatapb.VReplicationWorkflowType_MoveTables, + Streams: []*tabletmanagerdatapb.ReadVReplicationWorkflowResponse_Stream{ + { + Id: 1, + Bls: &binlogdatapb.BinlogSource{ + Keyspace: ms.SourceKeyspace, + Shard: "-", + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select * from t1", + }}, + }, + }, + }, + }, + }, nil + } + return nil, errors.New("read vreplication failed") + } + + _, err = env.ws.MoveTablesCreate(ctx, &vtctldatapb.MoveTablesCreateRequest{ + Workflow: ms.Workflow, + SourceKeyspace: ms.SourceKeyspace, + TargetKeyspace: ms.TargetKeyspace, + IncludeTables: []string{"t1"}, + }) + require.ErrorContains(t, err, "read vreplication failed") + + got, err := env.ws.ts.GetVSchema(ctx, ms.TargetKeyspace) + require.NoError(t, err) + require.True(t, proto.Equal(got.Keyspace, targetVSchema), "got: %v, want: %v", got.Keyspace, targetVSchema) +} + +func TestMoveTablesCreateUnshardedVSchemaRollback(t *testing.T) { + ms := &vtctldatapb.MaterializeSettings{ + Workflow: "workflow", + SourceKeyspace: "sourceks", + TargetKeyspace: "targetks", + TableSettings: []*vtctldatapb.TableMaterializeSettings{{ + TargetTable: "t1", + SourceExpression: "select * from t1", + }}, + } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + env := newTestMaterializerEnv(t, ctx, ms, []string{"-"}, []string{"-"}) + defer env.close() + + originalVSchema := &vschemapb.Keyspace{ + Tables: map[string]*vschemapb.Table{ + "t0": {}, + }, + } + err := env.ws.ts.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: ms.TargetKeyspace, + Keyspace: originalVSchema, + }) + require.NoError(t, err) + + env.tmc.expectFetchAsAllPrivsQuery(startingTargetTabletUID, getNonEmptyTable, &sqltypes.Result{}) + + sourceDeleteQuery := fmt.Sprintf(sqlDeleteWorkflow, encodeString("vt_sourceks"), encodeString(ReverseWorkflowName(ms.Workflow))) + targetDeleteQuery := fmt.Sprintf(sqlDeleteWorkflow, encodeString("vt_targetks"), encodeString(ms.Workflow)) + env.tmc.expectVRQuery(startingSourceTabletUID, sourceDeleteQuery, &sqltypes.Result{}) + env.tmc.expectVRQuery(startingTargetTabletUID, targetDeleteQuery, &sqltypes.Result{}) + + conn, err := env.ws.ts.ConnForCell(ctx, topo.GlobalCell) + require.NoError(t, err) + current, changes, err := conn.Watch(ctx, path.Join(topo.KeyspacesPath, ms.TargetKeyspace, topo.VSchemaFile)) + require.NoError(t, err) + initialVersion := "" + if current != nil && current.Version != nil { + initialVersion = current.Version.String() + } + + failCh := make(chan struct{}) + readCalls := 0 + env.tmc.readVReplicationWorkflow = func(ctx context.Context, tablet *topodatapb.Tablet, request *tabletmanagerdatapb.ReadVReplicationWorkflowRequest) (*tabletmanagerdatapb.ReadVReplicationWorkflowResponse, error) { + readCalls++ + if readCalls == 1 { + return &tabletmanagerdatapb.ReadVReplicationWorkflowResponse{ + Workflow: request.Workflow, + WorkflowType: binlogdatapb.VReplicationWorkflowType_MoveTables, + Streams: []*tabletmanagerdatapb.ReadVReplicationWorkflowResponse_Stream{ + { + Id: 1, + Bls: &binlogdatapb.BinlogSource{ + Keyspace: ms.SourceKeyspace, + Shard: "-", + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select * from t1", + }}, + }, + }, + }, + }, + }, nil + } + <-failCh + return nil, errors.New("read vreplication failed") + } + + errCh := make(chan error, 1) + go func() { + _, err := env.ws.MoveTablesCreate(ctx, &vtctldatapb.MoveTablesCreateRequest{ + Workflow: ms.Workflow, + SourceKeyspace: ms.SourceKeyspace, + TargetKeyspace: ms.TargetKeyspace, + IncludeTables: []string{"t1"}, + }) + errCh <- err + }() + + updatedVersion := "" + assert.Eventually(t, func() bool { + select { + case wd := <-changes: + if wd == nil || wd.Err != nil || wd.Contents == nil { + return false + } + ks := &vschemapb.Keyspace{} + if err := ks.UnmarshalVT(wd.Contents); err != nil { + return false + } + if ks.Tables["t1"] == nil { + return false + } + if wd.Version != nil { + updatedVersion = wd.Version.String() + } + return true + default: + return false + } + }, 5*time.Second, 50*time.Millisecond) + require.NotEmpty(t, updatedVersion) + if initialVersion != "" { + require.NotEqual(t, initialVersion, updatedVersion) + } + + close(failCh) + err = <-errCh + require.ErrorContains(t, err, "read vreplication failed") + + got, err := env.ws.ts.GetVSchema(ctx, ms.TargetKeyspace) + require.NoError(t, err) + require.True(t, proto.Equal(got.Keyspace, originalVSchema), "got: %v, want: %v", got.Keyspace, originalVSchema) +} + func TestCreateLookupVindexFull(t *testing.T) { ms := &vtctldatapb.MaterializeSettings{ Workflow: "lookup", diff --git a/go/vt/vtctl/workflow/server.go b/go/vt/vtctl/workflow/server.go index e37a6bf1504..8d8ade19b83 100644 --- a/go/vt/vtctl/workflow/server.go +++ b/go/vt/vtctl/workflow/server.go @@ -897,9 +897,7 @@ func (s *Server) moveTablesCreate(ctx context.Context, req *vtctldatapb.MoveTabl s.Logger().Infof("Successfully opened external topo: %+v", externalTopo) } - origVSchema := &topo.KeyspaceVSchemaInfo{ // If we need to rollback a failed create - Name: targetKeyspace, - } + var origVSchema *topo.KeyspaceVSchemaInfo // If we need to rollback a failed create vschema, err := s.ts.GetVSchema(ctx, targetKeyspace) if err != nil { return nil, err @@ -957,9 +955,11 @@ func (s *Server) moveTablesCreate(ctx context.Context, req *vtctldatapb.MoveTabl if !vschema.Sharded { // Save the original in case we need to restore it for a late failure in // the defer(). We do NOT want to clone the version field as we will - // intentionally be going back in time. So we only clone the internal - // vschemapb.Keyspace field. - origVSchema.Keyspace = vschema.Keyspace.CloneVT() + // intentionally be going back in time. + origVSchema = &topo.KeyspaceVSchemaInfo{ + Name: targetKeyspace, + Keyspace: vschema.Keyspace.CloneVT(), + } if err := s.addTablesToVSchema(ctx, sourceKeyspace, vschema.Keyspace, tables, externalTopo == nil); err != nil { return nil, err } @@ -1061,7 +1061,8 @@ func (s *Server) moveTablesCreate(ctx context.Context, req *vtctldatapb.MoveTabl if cerr := s.dropArtifacts(ctx, false, &switcher{s: s, ts: ts}); cerr != nil { err = vterrors.Wrapf(err, "failed to cleanup workflow artifacts: %v", cerr) } - if origVSchema == nil { // There's no previous version to restore + if vschema.Sharded || origVSchema == nil { + // We don't modify the vschema for sharded keyspaces, so there's nothing to restore. return } if cerr := s.ts.SaveVSchema(ctx, origVSchema); cerr != nil { From c510d1d5b1642f8d293644f9c6021609cb55dae1 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Mon, 12 Jan 2026 16:11:11 -0500 Subject: [PATCH 021/112] [release-22.0] Fix `ReloadSchema` incorrectly using `DisableBinlogs` value in `grpctmclient` (#19085) (#19129) Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- go/test/endtoend/backup/vtctlbackup/backup_utils.go | 6 +++--- go/vt/vttablet/grpctmclient/client.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go/test/endtoend/backup/vtctlbackup/backup_utils.go b/go/test/endtoend/backup/vtctlbackup/backup_utils.go index e92ba516ff3..05deb36bb02 100644 --- a/go/test/endtoend/backup/vtctlbackup/backup_utils.go +++ b/go/test/endtoend/backup/vtctlbackup/backup_utils.go @@ -131,7 +131,7 @@ func LaunchCluster(setupType int, streamMode string, stripes int, cDetails *Comp return 1, err } newInitDBFile = path.Join(localCluster.TmpDirectory, "init_db_with_passwords.sql") - err = os.WriteFile(newInitDBFile, []byte(sql), 0666) + err = os.WriteFile(newInitDBFile, []byte(sql), 0o666) if err != nil { return 1, err } @@ -543,10 +543,10 @@ func primaryBackup(t *testing.T) { _, err = primary.VttabletProcess.QueryTablet("DROP TABLE vt_insert_test", keyspaceName, true) require.NoError(t, err) + + restartPrimaryAndReplica(t) } -// Test a primary and replica from the same backup. -// // Check that a replica and primary both restored from the same backup // can replicate successfully. func primaryReplicaSameBackup(t *testing.T) { diff --git a/go/vt/vttablet/grpctmclient/client.go b/go/vt/vttablet/grpctmclient/client.go index f6d154570eb..f531d88ed15 100644 --- a/go/vt/vttablet/grpctmclient/client.go +++ b/go/vt/vttablet/grpctmclient/client.go @@ -577,7 +577,7 @@ func (client *Client) ExecuteFetchAsDba(ctx context.Context, tablet *topodatapb. DbName: topoproto.TabletDbName(tablet), MaxRows: req.MaxRows, DisableBinlogs: req.DisableBinlogs, - ReloadSchema: req.DisableBinlogs, + ReloadSchema: req.ReloadSchema, DisableForeignKeyChecks: req.DisableForeignKeyChecks, }) if err != nil { @@ -613,7 +613,7 @@ func (client *Client) ExecuteMultiFetchAsDba(ctx context.Context, tablet *topoda DbName: topoproto.TabletDbName(tablet), MaxRows: req.MaxRows, DisableBinlogs: req.DisableBinlogs, - ReloadSchema: req.DisableBinlogs, + ReloadSchema: req.ReloadSchema, DisableForeignKeyChecks: req.DisableForeignKeyChecks, }) if err != nil { From 5873e743fd09d1945e87ba90035565e2d6e019bd Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Thu, 15 Jan 2026 05:16:35 +0000 Subject: [PATCH 022/112] [release-22.0] Fix cross shard/keyspace joins with derived tables containing a `UNION`. (#19046) (#19136) Signed-off-by: Arthur Schreiber Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Arthur Schreiber --- go/vt/vtgate/planbuilder/operators/union.go | 9 +++ .../planbuilder/testdata/union_cases.json | 74 +++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/go/vt/vtgate/planbuilder/operators/union.go b/go/vt/vtgate/planbuilder/operators/union.go index 0c7ecc97bc3..8fd06adb219 100644 --- a/go/vt/vtgate/planbuilder/operators/union.go +++ b/go/vt/vtgate/planbuilder/operators/union.go @@ -23,6 +23,7 @@ import ( "vitess.io/vitess/go/slice" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/planbuilder/operators/predicates" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" ) @@ -103,6 +104,11 @@ func (u *Union) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Ex offsets[ae.ColumnName()] = i } + if jp, ok := expr.(*predicates.JoinPredicate); ok { + expr = jp.Current() + ctx.PredTracker.Skip(jp.ID) + } + needsFilter, exprPerSource := u.predicatePerSource(expr, offsets) if needsFilter { return newFilter(u, expr) @@ -118,6 +124,7 @@ func (u *Union) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Ex func (u *Union) predicatePerSource(expr sqlparser.Expr, offsets map[string]int) (bool, []sqlparser.Expr) { needsFilter := false exprPerSource := make([]sqlparser.Expr, len(u.Sources)) + for i := range u.Sources { predicate := sqlparser.CopyOnRewrite(expr, nil, func(cursor *sqlparser.CopyOnWriteCursor) { col, ok := cursor.Node().(*sqlparser.ColName) @@ -137,11 +144,13 @@ func (u *Union) predicatePerSource(expr sqlparser.Expr, offsets map[string]int) if !ok { panic(vterrors.VT09015()) } + cursor.Replace(ae.Expr) }, nil).(sqlparser.Expr) exprPerSource[i] = predicate } + return needsFilter, exprPerSource } diff --git a/go/vt/vtgate/planbuilder/testdata/union_cases.json b/go/vt/vtgate/planbuilder/testdata/union_cases.json index 0cf8defd671..7555662b078 100644 --- a/go/vt/vtgate/planbuilder/testdata/union_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/union_cases.json @@ -2086,5 +2086,79 @@ "user.user" ] } + }, + { + "comment": "join with derived table containing UNION with aliased columns across different keyspaces", + "query": "select u.id from user as u join (select id as pid from user where id = 1 union select id as pid from unsharded where id = 1) as i on u.id = i.pid", + "plan": { + "Type": "Join", + "QueryType": "SELECT", + "Original": "select u.id from user as u join (select id as pid from user where id = 1 union select id as pid from unsharded where id = 1) as i on u.id = i.pid", + "Instructions": { + "OperatorType": "Join", + "Variant": "Join", + "JoinColumnIndexes": "L:0", + "JoinVars": { + "u_id": 0 + }, + "TableName": "`user`_`user`_unsharded", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select u.id from `user` as u where 1 != 1", + "Query": "select u.id from `user` as u", + "Table": "`user`" + }, + { + "OperatorType": "Distinct", + "Collations": [ + "(0:1)" + ], + "Inputs": [ + { + "OperatorType": "Concatenate", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select dt.c0 as pid, weight_string(dt.c0) from (select id as pid from `user` where 1 != 1) as dt(c0) where 1 != 1", + "Query": "select dt.c0 as pid, weight_string(dt.c0) from (select distinct id as pid from `user` where id = 1 and id = :u_id) as dt(c0)", + "Table": "`user`", + "Values": [ + ":u_id" + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select dt.c0 as pid, weight_string(dt.c0) from (select id as pid from unsharded where 1 != 1) as dt(c0) where 1 != 1", + "Query": "select dt.c0 as pid, weight_string(dt.c0) from (select distinct id as pid from unsharded where id = 1 and id = :u_id) as dt(c0)", + "Table": "unsharded" + } + ] + } + ] + } + ] + }, + "TablesUsed": [ + "main.unsharded", + "user.user" + ] + } } ] From d765b528446627a9b89e2fd865494c760a264c96 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Thu, 15 Jan 2026 17:30:23 +0100 Subject: [PATCH 023/112] [release-22.0] workflows: avoid accidental deletion to routing rules (#19121) (#19135) Signed-off-by: Nick Van Wiggeren Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- go/vt/vtctl/workflow/server_test.go | 25 +++ go/vt/vtctl/workflow/traffic_switcher.go | 5 +- go/vt/vtctl/workflow/traffic_switcher_test.go | 169 ++++++++++++++++++ 3 files changed, 198 insertions(+), 1 deletion(-) diff --git a/go/vt/vtctl/workflow/server_test.go b/go/vt/vtctl/workflow/server_test.go index a836df13123..a3c7a7c02bb 100644 --- a/go/vt/vtctl/workflow/server_test.go +++ b/go/vt/vtctl/workflow/server_test.go @@ -1817,6 +1817,7 @@ func TestMirrorTraffic(t *testing.T) { sourceShards := []string{"-"} targetKs := "target" targetShards := []string{"-80", "80-"} + otherKs := "otherks" table1 := "table1" table2 := "table2" workflow := "src2target" @@ -2063,6 +2064,30 @@ func TestMirrorTraffic(t *testing.T) { }, }, }, + { + name: "percent zero preserves other mirror targets", + mirrorRules: map[string]map[string]float32{ + fmt.Sprintf("%s.%s", sourceKs, table1): { + fmt.Sprintf("%s.%s", targetKs, table1): 50.0, + fmt.Sprintf("%s.%s", otherKs, table1): 25.0, + }, + fmt.Sprintf("%s.%s", sourceKs, table2): { + fmt.Sprintf("%s.%s", targetKs, table2): 50.0, + }, + }, + req: &vtctldatapb.WorkflowMirrorTrafficRequest{ + Keyspace: targetKs, + Workflow: workflow, + TabletTypes: []topodatapb.TabletType{topodatapb.TabletType_PRIMARY}, + Percent: 0.0, + }, + routingRules: initialRoutingRules, + wantMirrorRules: map[string]map[string]float32{ + fmt.Sprintf("%s.%s", sourceKs, table1): { + fmt.Sprintf("%s.%s", otherKs, table1): 25.0, + }, + }, + }, { name: "does not overwrite unrelated mirror rules", mirrorRules: map[string]map[string]float32{ diff --git a/go/vt/vtctl/workflow/traffic_switcher.go b/go/vt/vtctl/workflow/traffic_switcher.go index db4df2ceb4d..2bdc9ffaebb 100644 --- a/go/vt/vtctl/workflow/traffic_switcher.go +++ b/go/vt/vtctl/workflow/traffic_switcher.go @@ -1571,7 +1571,10 @@ func (ts *trafficSwitcher) mirrorTableTraffic(ctx context.Context, types []topod if percent == 0 { // When percent is 0, remove mirror rule if it exists. if _, ok := mrs[fromTable][toTable]; ok { - delete(mrs, fromTable) + delete(mrs[fromTable], toTable) + if len(mrs[fromTable]) == 0 { + delete(mrs, fromTable) + } } } else { mrs[fromTable][toTable] = percent diff --git a/go/vt/vtctl/workflow/traffic_switcher_test.go b/go/vt/vtctl/workflow/traffic_switcher_test.go index d9b5e349630..24a0ce8014c 100644 --- a/go/vt/vtctl/workflow/traffic_switcher_test.go +++ b/go/vt/vtctl/workflow/traffic_switcher_test.go @@ -32,8 +32,10 @@ import ( tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/proto/vschema" + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topotools" "vitess.io/vitess/go/vt/vtgate/vindexes" ) @@ -450,3 +452,170 @@ func TestCancelMigration_SHARDS(t *testing.T) { assert.Empty(t, env.tmc.vrQueries[100]) assert.Empty(t, env.tmc.vrQueries[200]) } + +func TestDeleteRoutingRulesPreservesUnrelated(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + workflowName := "wf1" + tableName := "t1" + sourceKeyspaceName := "sourceks" + targetKeyspaceName := "targetks" + + sourceKeyspace := &testKeyspace{ + KeyspaceName: sourceKeyspaceName, + ShardNames: []string{"0"}, + } + targetKeyspace := &testKeyspace{ + KeyspaceName: targetKeyspaceName, + ShardNames: []string{"0"}, + } + + schema := map[string]*tabletmanagerdatapb.SchemaDefinition{ + tableName: { + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{ + { + Name: tableName, + Schema: fmt.Sprintf("CREATE TABLE %s (id BIGINT, name VARCHAR(64), PRIMARY KEY (id))", tableName), + }, + }, + }, + } + + env := newTestEnv(t, ctx, defaultCellName, sourceKeyspace, targetKeyspace) + defer env.close() + env.tmc.schema = schema + + ts, _, err := env.ws.getWorkflowState(ctx, targetKeyspaceName, workflowName) + require.NoError(t, err) + + rules := map[string][]string{ + tableName: {fmt.Sprintf("%s.%s", sourceKeyspaceName, tableName)}, + tableName + "@replica": {fmt.Sprintf("%s.%s", sourceKeyspaceName, tableName)}, + sourceKeyspaceName + "." + tableName: {fmt.Sprintf("%s.%s", sourceKeyspaceName, tableName)}, + targetKeyspaceName + "." + tableName: {fmt.Sprintf("%s.%s", sourceKeyspaceName, tableName)}, + "unrelated": {"otherks.unrelated"}, + } + require.NoError(t, topotools.SaveRoutingRules(ctx, env.ts, rules)) + + err = ts.deleteRoutingRules(ctx) + require.NoError(t, err) + + got, err := topotools.GetRoutingRules(ctx, env.ts) + require.NoError(t, err) + require.Equal(t, map[string][]string{ + "unrelated": {"otherks.unrelated"}, + }, got) +} + +func TestDeleteShardRoutingRulesPreservesUnrelated(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + workflowName := "wf1" + tableName := "t1" + sourceKeyspaceName := "sourceks" + targetKeyspaceName := "targetks" + + sourceKeyspace := &testKeyspace{ + KeyspaceName: sourceKeyspaceName, + ShardNames: []string{"0"}, + } + targetKeyspace := &testKeyspace{ + KeyspaceName: targetKeyspaceName, + ShardNames: []string{"0"}, + } + + schema := map[string]*tabletmanagerdatapb.SchemaDefinition{ + tableName: { + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{ + { + Name: tableName, + Schema: fmt.Sprintf("CREATE TABLE %s (id BIGINT, name VARCHAR(64), PRIMARY KEY (id))", tableName), + }, + }, + }, + } + + env := newTestEnv(t, ctx, defaultCellName, sourceKeyspace, targetKeyspace) + defer env.close() + env.tmc.schema = schema + + ts, _, err := env.ws.getWorkflowState(ctx, targetKeyspaceName, workflowName) + require.NoError(t, err) + ts.isPartialMigration = true + + require.NoError(t, topotools.SaveShardRoutingRules(ctx, env.ts, map[string]string{ + fmt.Sprintf("%s.%s", targetKeyspaceName, "0"): sourceKeyspaceName, + "otherks.0": "otherks", + })) + + err = ts.deleteShardRoutingRules(ctx) + require.NoError(t, err) + + got, err := topotools.GetShardRoutingRules(ctx, env.ts) + require.NoError(t, err) + require.Equal(t, map[string]string{ + "otherks.0": "otherks", + }, got) +} + +func TestDeleteKeyspaceRoutingRulesPreservesUnrelated(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + + workflowName := "wf1" + tableName := "t1" + sourceKeyspaceName := "sourceks" + targetKeyspaceName := "targetks" + + sourceKeyspace := &testKeyspace{ + KeyspaceName: sourceKeyspaceName, + ShardNames: []string{"0"}, + } + targetKeyspace := &testKeyspace{ + KeyspaceName: targetKeyspaceName, + ShardNames: []string{"0"}, + } + + schema := map[string]*tabletmanagerdatapb.SchemaDefinition{ + tableName: { + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{ + { + Name: tableName, + Schema: fmt.Sprintf("CREATE TABLE %s (id BIGINT, name VARCHAR(64), PRIMARY KEY (id))", tableName), + }, + }, + }, + } + + env := newTestEnv(t, ctx, defaultCellName, sourceKeyspace, targetKeyspace) + defer env.close() + env.tmc.schema = schema + + ts, _, err := env.ws.getWorkflowState(ctx, targetKeyspaceName, workflowName) + require.NoError(t, err) + ts.options = &vtctldatapb.WorkflowOptions{TenantId: "tenant"} + + rules := map[string]string{ + sourceKeyspaceName: targetKeyspaceName, + sourceKeyspaceName + "@replica": targetKeyspaceName, + sourceKeyspaceName + "@rdonly": targetKeyspaceName, + "otherks": "otherks", + } + require.NoError(t, topotools.UpdateKeyspaceRoutingRules(ctx, env.ts, "test", func(ctx context.Context, existing *map[string]string) error { + for key, value := range rules { + (*existing)[key] = value + } + return nil + })) + + err = ts.deleteKeyspaceRoutingRules(ctx) + require.NoError(t, err) + + got, err := topotools.GetKeyspaceRoutingRules(ctx, env.ts) + require.NoError(t, err) + require.Equal(t, map[string]string{ + "otherks": "otherks", + }, got) +} From 972daa9ccd99b3a97aa1c95a4aadff50b0b22d81 Mon Sep 17 00:00:00 2001 From: Mohamed Hamza Date: Thu, 15 Jan 2026 12:34:06 -0500 Subject: [PATCH 024/112] Pin GitHub Actions and Docker images by hash (#19151) Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- .github/workflows/codeql_analysis.yml | 6 +++--- .github/workflows/scorecards.yml | 8 ++++---- .github/workflows/static_checks_etc.yml | 4 ++-- .github/workflows/update_golang_dependencies.yml | 2 +- .github/workflows/update_golang_version.yml | 2 +- .github/workflows/vtadmin_web_build.yml | 2 +- .github/workflows/vtadmin_web_lint.yml | 2 +- .github/workflows/vtadmin_web_unit_tests.yml | 2 +- docker/bootstrap/Dockerfile.common | 2 +- docker/lite/Dockerfile | 4 ++-- docker/lite/Dockerfile.mysql84 | 4 ++-- docker/lite/Dockerfile.percona80 | 4 ++-- docker/vttestserver/Dockerfile.mysql80 | 4 ++-- docker/vttestserver/Dockerfile.mysql84 | 4 ++-- tools/check_go_versions.sh | 12 ++++++------ 15 files changed, 31 insertions(+), 31 deletions(-) diff --git a/.github/workflows/codeql_analysis.yml b/.github/workflows/codeql_analysis.yml index c98780ca527..19af0674bd0 100644 --- a/.github/workflows/codeql_analysis.yml +++ b/.github/workflows/codeql_analysis.yml @@ -41,7 +41,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@4bdb89f48054571735e3792627da6195c57459e2 # v3.28.18 with: languages: ${{ matrix.language }} # If you wish to specify cu stom queries, you can do so here or in a config file. @@ -75,11 +75,11 @@ jobs: make build - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@4bdb89f48054571735e3792627da6195c57459e2 # v3.28.18 - name: Slack Workflow Notification if: ${{ failure() }} - uses: Gamesight/slack-workflow-status@master + uses: Gamesight/slack-workflow-status@68bf00d0dbdbcb206c278399aa1ef6c14f74347a # v1.3.0 with: repo_token: ${{secrets.GITHUB_TOKEN}} slack_webhook_url: ${{secrets.SLACK_WEBHOOK_URL}} diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index de90706da27..b2cd979861d 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -26,12 +26,12 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@v4 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 + uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 with: results_file: results.sarif results_format: sarif @@ -53,7 +53,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: SARIF file path: results.sarif @@ -62,6 +62,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5 + uses: github/codeql-action/upload-sarif@4bdb89f48054571735e3792627da6195c57459e2 # v3.28.18 with: sarif_file: results.sarif diff --git a/.github/workflows/static_checks_etc.yml b/.github/workflows/static_checks_etc.yml index 7ae73965651..710d388d267 100644 --- a/.github/workflows/static_checks_etc.yml +++ b/.github/workflows/static_checks_etc.yml @@ -30,7 +30,7 @@ jobs: persist-credentials: 'false' - name: Run FOSSA scan and upload build data - uses: fossa-contrib/fossa-action@v3 + uses: fossa-contrib/fossa-action@3d2ef181b1820d6dcd1972f86a767d18167fa19b # v3.0.1 with: # This is a push-only API token: https://github.com/fossa-contrib/fossa-action#push-only-api-token fossa-api-key: f62c11ef0c249fef239947f01279aa0f @@ -218,7 +218,7 @@ jobs: - name: Setup Node if: steps.changes.outputs.proto_changes == 'true' - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: # make proto requires newer node than the pre-installed one node-version: '22.13.1' diff --git a/.github/workflows/update_golang_dependencies.yml b/.github/workflows/update_golang_dependencies.yml index fc8def557af..c305f7eb904 100644 --- a/.github/workflows/update_golang_dependencies.yml +++ b/.github/workflows/update_golang_dependencies.yml @@ -40,7 +40,7 @@ jobs: go mod tidy - name: Create Pull Request - uses: peter-evans/create-pull-request@v7 + uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0 with: token: ${{ secrets.CREATE_PR_VITESS_BOT }} branch: "upgrade-go-deps-on-main" diff --git a/.github/workflows/update_golang_version.yml b/.github/workflows/update_golang_version.yml index 686c1d85e9d..a1d2bdbcc97 100644 --- a/.github/workflows/update_golang_version.yml +++ b/.github/workflows/update_golang_version.yml @@ -66,7 +66,7 @@ jobs: - name: Create Pull Request if: steps.detect-and-update.outputs.create-pr == 'true' - uses: peter-evans/create-pull-request@v7 + uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0 with: token: ${{ secrets.CREATE_PR_VITESS_BOT }} branch: "upgrade-go-to-${{steps.detect-and-update.outputs.go-version}}-on-${{ matrix.branch }}" diff --git a/.github/workflows/vtadmin_web_build.yml b/.github/workflows/vtadmin_web_build.yml index 64cc4a454af..522535c2dde 100644 --- a/.github/workflows/vtadmin_web_build.yml +++ b/.github/workflows/vtadmin_web_build.yml @@ -37,7 +37,7 @@ jobs: - name: Tune the OS uses: ./.github/actions/tune-os - - uses: actions/setup-node@v4 + - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: # node-version should match package.json node-version: '22.13.1' diff --git a/.github/workflows/vtadmin_web_lint.yml b/.github/workflows/vtadmin_web_lint.yml index b46f36660c3..0ff53373f45 100644 --- a/.github/workflows/vtadmin_web_lint.yml +++ b/.github/workflows/vtadmin_web_lint.yml @@ -37,7 +37,7 @@ jobs: - name: Tune the OS uses: ./.github/actions/tune-os - - uses: actions/setup-node@v4 + - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: # node-version should match package.json node-version: '22.13.1' diff --git a/.github/workflows/vtadmin_web_unit_tests.yml b/.github/workflows/vtadmin_web_unit_tests.yml index 096634942e2..dfdd813118c 100644 --- a/.github/workflows/vtadmin_web_unit_tests.yml +++ b/.github/workflows/vtadmin_web_unit_tests.yml @@ -37,7 +37,7 @@ jobs: - name: Tune the OS uses: ./.github/actions/tune-os - - uses: actions/setup-node@v4 + - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: # node-version should match package.json node-version: '22.13.1' diff --git a/docker/bootstrap/Dockerfile.common b/docker/bootstrap/Dockerfile.common index e112119f836..53f86503f2f 100644 --- a/docker/bootstrap/Dockerfile.common +++ b/docker/bootstrap/Dockerfile.common @@ -1,4 +1,4 @@ -FROM --platform=linux/amd64 golang:1.24.10-bookworm +FROM --platform=linux/amd64 golang:1.24.10-bookworm@sha256:6d78b05df97ae4d12e887f2f2ba6bd0d1b9d644bcf63604fbb4c43cf6839ed9c # Install Vitess build dependencies RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ diff --git a/docker/lite/Dockerfile b/docker/lite/Dockerfile index 074097ddb2e..7bc43d42776 100644 --- a/docker/lite/Dockerfile +++ b/docker/lite/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.24.10-bookworm AS builder +FROM --platform=linux/amd64 golang:1.24.10-bookworm@sha256:6d78b05df97ae4d12e887f2f2ba6bd0d1b9d644bcf63604fbb4c43cf6839ed9c AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER @@ -40,7 +40,7 @@ COPY --chown=vitess:vitess . /vt/src/vitess.io/vitess RUN make install PREFIX=/vt/install # Start over and build the final image. -FROM --platform=linux/amd64 debian:bookworm-slim +FROM --platform=linux/amd64 debian:bookworm-slim@sha256:09c53e50b5110eb26e0932ab77934481ce9c0068069d4f28e3e7493e51323bfe # Install locale required for mysqlsh RUN apt-get update && apt-get install -y locales \ diff --git a/docker/lite/Dockerfile.mysql84 b/docker/lite/Dockerfile.mysql84 index ca7c0913534..52d61fd65b3 100644 --- a/docker/lite/Dockerfile.mysql84 +++ b/docker/lite/Dockerfile.mysql84 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.24.10-bookworm AS builder +FROM --platform=linux/amd64 golang:1.24.10-bookworm@sha256:6d78b05df97ae4d12e887f2f2ba6bd0d1b9d644bcf63604fbb4c43cf6839ed9c AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER @@ -40,7 +40,7 @@ COPY --chown=vitess:vitess . /vt/src/vitess.io/vitess RUN make install PREFIX=/vt/install # Start over and build the final image. -FROM --platform=linux/amd64 debian:bookworm-slim +FROM --platform=linux/amd64 debian:bookworm-slim@sha256:09c53e50b5110eb26e0932ab77934481ce9c0068069d4f28e3e7493e51323bfe # Install locale required for mysqlsh RUN apt-get update && apt-get install -y locales \ diff --git a/docker/lite/Dockerfile.percona80 b/docker/lite/Dockerfile.percona80 index 46a4cb80a3e..41b3d9b2c2a 100644 --- a/docker/lite/Dockerfile.percona80 +++ b/docker/lite/Dockerfile.percona80 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.24.10-bookworm AS builder +FROM --platform=linux/amd64 golang:1.24.10-bookworm@sha256:6d78b05df97ae4d12e887f2f2ba6bd0d1b9d644bcf63604fbb4c43cf6839ed9c AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER @@ -40,7 +40,7 @@ COPY --chown=vitess:vitess . /vt/src/vitess.io/vitess RUN make install PREFIX=/vt/install # Start over and build the final image. -FROM --platform=linux/amd64 debian:bookworm-slim +FROM --platform=linux/amd64 debian:bookworm-slim@sha256:09c53e50b5110eb26e0932ab77934481ce9c0068069d4f28e3e7493e51323bfe # Install dependencies COPY docker/utils/install_dependencies.sh /vt/dist/install_dependencies.sh diff --git a/docker/vttestserver/Dockerfile.mysql80 b/docker/vttestserver/Dockerfile.mysql80 index 2e25dc6f0bc..c7711b5a645 100644 --- a/docker/vttestserver/Dockerfile.mysql80 +++ b/docker/vttestserver/Dockerfile.mysql80 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.24.10-bookworm AS builder +FROM --platform=linux/amd64 golang:1.24.10-bookworm@sha256:6d78b05df97ae4d12e887f2f2ba6bd0d1b9d644bcf63604fbb4c43cf6839ed9c AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER @@ -31,7 +31,7 @@ COPY --chown=vitess:vitess . /vt/src/vitess.io/vitess RUN make install-testing PREFIX=/vt/install # Start over and build the final image. -FROM --platform=linux/amd64 debian:bookworm-slim +FROM --platform=linux/amd64 debian:bookworm-slim@sha256:09c53e50b5110eb26e0932ab77934481ce9c0068069d4f28e3e7493e51323bfe # Install dependencies COPY docker/utils/install_dependencies.sh /vt/dist/install_dependencies.sh diff --git a/docker/vttestserver/Dockerfile.mysql84 b/docker/vttestserver/Dockerfile.mysql84 index 6fe1326147a..fe4d50b5283 100644 --- a/docker/vttestserver/Dockerfile.mysql84 +++ b/docker/vttestserver/Dockerfile.mysql84 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.24.10-bookworm AS builder +FROM --platform=linux/amd64 golang:1.24.10-bookworm@sha256:6d78b05df97ae4d12e887f2f2ba6bd0d1b9d644bcf63604fbb4c43cf6839ed9c AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER @@ -31,7 +31,7 @@ COPY --chown=vitess:vitess . /vt/src/vitess.io/vitess RUN make install-testing PREFIX=/vt/install # Start over and build the final image. -FROM --platform=linux/amd64 debian:bookworm-slim +FROM --platform=linux/amd64 debian:bookworm-slim@sha256:09c53e50b5110eb26e0932ab77934481ce9c0068069d4f28e3e7493e51323bfe # Install dependencies COPY docker/utils/install_dependencies.sh /vt/dist/install_dependencies.sh diff --git a/tools/check_go_versions.sh b/tools/check_go_versions.sh index 846a10322f1..5c32a3b5cb4 100755 --- a/tools/check_go_versions.sh +++ b/tools/check_go_versions.sh @@ -10,13 +10,13 @@ set -e # go.mod GO_MOD_VERSION="$(awk '/^go [0-9].[0-9]+/{print $(NF-0)}' go.mod)" if [ -z "${GO_MOD_VERSION}" ]; then - echo "cannot find go version in go.mod" - exit 1 + echo "cannot find go version in go.mod" + exit 1 fi # docker/bootstrap/Dockerfile.common -BOOTSTRAP_GO_VERSION="$(awk -F ':' '/golang:/{print $(NF-0)}' docker/bootstrap/Dockerfile.common | cut -d- -f1)" -if [[ ! "${BOOTSTRAP_GO_VERSION}" =~ "${GO_MOD_VERSION}" ]]; then - echo "expected golang docker version in docker/bootstrap/Dockerfile.common to be equal to go.mod: '${TPL_GO_VERSION}' != '${GO_MOD_VERSION}'" - exit 1 +BOOTSTRAP_GO_VERSION="$(sed -n 's/.*golang:\([0-9]*\.[0-9]*\.[0-9]*\).*/\1/p' docker/bootstrap/Dockerfile.common)" +if [[ "${BOOTSTRAP_GO_VERSION}" != "${GO_MOD_VERSION}" ]]; then + echo "expected golang docker version in docker/bootstrap/Dockerfile.common to be equal to go.mod: '${BOOTSTRAP_GO_VERSION}' != '${GO_MOD_VERSION}'" + exit 1 fi From 16e68c3d602a0490b9f7adcb0904e5ff7f0fc8c7 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Fri, 16 Jan 2026 17:02:15 +0100 Subject: [PATCH 025/112] [release-22.0] Fix column offset tracking for `UNION`s to be case insensitive. (#19139) (#19161) Signed-off-by: Arthur Schreiber Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Arthur Schreiber --- go/vt/vtgate/planbuilder/operators/union.go | 34 ++-- .../planbuilder/testdata/union_cases.json | 150 ++++++++---------- 2 files changed, 85 insertions(+), 99 deletions(-) diff --git a/go/vt/vtgate/planbuilder/operators/union.go b/go/vt/vtgate/planbuilder/operators/union.go index 8fd06adb219..0731d8c888e 100644 --- a/go/vt/vtgate/planbuilder/operators/union.go +++ b/go/vt/vtgate/planbuilder/operators/union.go @@ -19,6 +19,7 @@ package operators import ( "fmt" "slices" + "strings" "vitess.io/vitess/go/slice" "vitess.io/vitess/go/vt/sqlparser" @@ -101,19 +102,10 @@ func (u *Union) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Ex if !ok { panic(vterrors.VT12001("pushing predicates on UNION where the first SELECT contains * or NEXT")) } - offsets[ae.ColumnName()] = i - } - - if jp, ok := expr.(*predicates.JoinPredicate); ok { - expr = jp.Current() - ctx.PredTracker.Skip(jp.ID) - } - - needsFilter, exprPerSource := u.predicatePerSource(expr, offsets) - if needsFilter { - return newFilter(u, expr) + offsets[strings.ToLower(ae.ColumnName())] = i } + exprPerSource := u.predicatePerSource(ctx, expr, offsets) for i, src := range u.Sources { u.Sources[i] = src.AddPredicate(ctx, exprPerSource[i]) } @@ -121,12 +113,20 @@ func (u *Union) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Ex return u } -func (u *Union) predicatePerSource(expr sqlparser.Expr, offsets map[string]int) (bool, []sqlparser.Expr) { - needsFilter := false +func (u *Union) predicatePerSource(ctx *plancontext.PlanningContext, expr sqlparser.Expr, offsets map[string]int) []sqlparser.Expr { exprPerSource := make([]sqlparser.Expr, len(u.Sources)) for i := range u.Sources { - predicate := sqlparser.CopyOnRewrite(expr, nil, func(cursor *sqlparser.CopyOnWriteCursor) { + predicate := expr + + if jp, ok := predicate.(*predicates.JoinPredicate); ok { + // Create a new JoinPredicate for each source to keep tracking working + // We can't use `*JoinPredicate.Clone` here as that would update the tracker and overwrite + // the expression for the original predicate + predicate = ctx.PredTracker.NewJoinPredicate(jp.Current()) + } + + predicate = sqlparser.CopyOnRewrite(predicate, nil, func(cursor *sqlparser.CopyOnWriteCursor) { col, ok := cursor.Node().(*sqlparser.ColName) if !ok { return @@ -134,9 +134,7 @@ func (u *Union) predicatePerSource(expr sqlparser.Expr, offsets map[string]int) idx, ok := offsets[col.Name.Lowered()] if !ok { - needsFilter = true - cursor.StopTreeWalk() - return + panic(vterrors.VT13001(fmt.Sprintf("could not find the column '%s' on the UNION", sqlparser.String(col)))) } sel := u.GetSelectFor(i) @@ -151,7 +149,7 @@ func (u *Union) predicatePerSource(expr sqlparser.Expr, offsets map[string]int) exprPerSource[i] = predicate } - return needsFilter, exprPerSource + return exprPerSource } func (u *Union) GetSelectFor(source int) *sqlparser.Select { diff --git a/go/vt/vtgate/planbuilder/testdata/union_cases.json b/go/vt/vtgate/planbuilder/testdata/union_cases.json index 7555662b078..6fccfba3eb7 100644 --- a/go/vt/vtgate/planbuilder/testdata/union_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/union_cases.json @@ -1357,45 +1357,39 @@ "QueryType": "SELECT", "Original": "select * from (select kcu.`COLUMN_NAME` from `information_schema`.`key_column_usage` `kcu` where `kcu`.`table_schema` = 'user' and `kcu`.`table_name` = 'user_extra' union select kcu.`COLUMN_NAME` from `information_schema`.`key_column_usage` `kcu` where `kcu`.`table_schema` = 'user' and `kcu`.`table_name` = 'music') `kcu` where `COLUMN_NAME` = 'primary'", "Instructions": { - "OperatorType": "Filter", - "Predicate": "`COLUMN_NAME` = 'primary'", + "OperatorType": "Distinct", + "Collations": [ + "0: utf8mb3_general_ci" + ], "Inputs": [ { - "OperatorType": "Distinct", - "Collations": [ - "0: utf8mb3_general_ci" - ], + "OperatorType": "Concatenate", "Inputs": [ { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select kcu.`COLUMN_NAME` from information_schema.key_column_usage as kcu where 1 != 1", - "Query": "select distinct kcu.`COLUMN_NAME` from information_schema.key_column_usage as kcu where kcu.table_schema = :__vtschemaname /* VARCHAR */ and kcu.`table_name` = :kcu_table_name /* VARCHAR */", - "SysTableTableName": "[kcu_table_name:'user_extra']", - "SysTableTableSchema": "['user']", - "Table": "information_schema.key_column_usage" - }, - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select kcu.`COLUMN_NAME` from information_schema.key_column_usage as kcu where 1 != 1", - "Query": "select distinct kcu.`COLUMN_NAME` from information_schema.key_column_usage as kcu where kcu.table_schema = :__vtschemaname /* VARCHAR */ and kcu.`table_name` = :kcu_table_name1 /* VARCHAR */", - "SysTableTableName": "[kcu_table_name1:'music']", - "SysTableTableSchema": "['user']", - "Table": "information_schema.key_column_usage" - } - ] + "OperatorType": "Route", + "Variant": "DBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select kcu.`COLUMN_NAME` from information_schema.key_column_usage as kcu where 1 != 1", + "Query": "select distinct kcu.`COLUMN_NAME` from information_schema.key_column_usage as kcu where kcu.table_schema = :__vtschemaname /* VARCHAR */ and kcu.`table_name` = :kcu_table_name /* VARCHAR */ and `COLUMN_NAME` = 'primary'", + "SysTableTableName": "[kcu_table_name:'user_extra']", + "SysTableTableSchema": "['user']", + "Table": "information_schema.key_column_usage" + }, + { + "OperatorType": "Route", + "Variant": "DBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select kcu.`COLUMN_NAME` from information_schema.key_column_usage as kcu where 1 != 1", + "Query": "select distinct kcu.`COLUMN_NAME` from information_schema.key_column_usage as kcu where kcu.table_schema = :__vtschemaname /* VARCHAR */ and kcu.`table_name` = :kcu_table_name1 /* VARCHAR */ and `COLUMN_NAME` = 'primary'", + "SysTableTableName": "[kcu_table_name1:'music']", + "SysTableTableSchema": "['user']", + "Table": "information_schema.key_column_usage" } ] } @@ -1439,56 +1433,50 @@ "QueryType": "SELECT", "Original": "select * from (select * from `information_schema`.`key_column_usage` `kcu` where `kcu`.`table_schema` = 'user' and `kcu`.`table_name` = 'user_extra' union select * from `information_schema`.`key_column_usage` `kcu` where `kcu`.`table_schema` = 'user' and `kcu`.`table_name` = 'music') `kcu` where `constraint_name` = 'primary'", "Instructions": { - "OperatorType": "Filter", - "Predicate": "`constraint_name` = 'primary'", + "OperatorType": "Distinct", + "Collations": [ + "0: utf8mb3_general_ci", + "1: utf8mb3_general_ci", + "2: utf8mb3_general_ci", + "3: utf8mb3_general_ci", + "4: utf8mb3_general_ci", + "5: utf8mb3_general_ci", + "6: utf8mb3_general_ci", + "7", + "8", + "9: utf8mb3_general_ci", + "10: utf8mb3_general_ci", + "11: utf8mb3_general_ci" + ], "Inputs": [ { - "OperatorType": "Distinct", - "Collations": [ - "0: utf8mb3_general_ci", - "1: utf8mb3_general_ci", - "2: utf8mb3_general_ci", - "3: utf8mb3_general_ci", - "4: utf8mb3_general_ci", - "5: utf8mb3_general_ci", - "6: utf8mb3_general_ci", - "7", - "8", - "9: utf8mb3_general_ci", - "10: utf8mb3_general_ci", - "11: utf8mb3_general_ci" - ], + "OperatorType": "Concatenate", "Inputs": [ { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select `CONSTRAINT_CATALOG`, `CONSTRAINT_SCHEMA`, `CONSTRAINT_NAME`, TABLE_CATALOG, TABLE_SCHEMA, `TABLE_NAME`, `COLUMN_NAME`, ORDINAL_POSITION, POSITION_IN_UNIQUE_CONSTRAINT, REFERENCED_TABLE_SCHEMA, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME from information_schema.key_column_usage as kcu where 1 != 1", - "Query": "select distinct `CONSTRAINT_CATALOG`, `CONSTRAINT_SCHEMA`, `CONSTRAINT_NAME`, TABLE_CATALOG, TABLE_SCHEMA, `TABLE_NAME`, `COLUMN_NAME`, ORDINAL_POSITION, POSITION_IN_UNIQUE_CONSTRAINT, REFERENCED_TABLE_SCHEMA, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME from information_schema.key_column_usage as kcu where kcu.table_schema = :__vtschemaname /* VARCHAR */ and kcu.`table_name` = :kcu_table_name /* VARCHAR */", - "SysTableTableName": "[kcu_table_name:'user_extra']", - "SysTableTableSchema": "['user']", - "Table": "information_schema.key_column_usage" - }, - { - "OperatorType": "Route", - "Variant": "DBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select `CONSTRAINT_CATALOG`, `CONSTRAINT_SCHEMA`, `CONSTRAINT_NAME`, TABLE_CATALOG, TABLE_SCHEMA, `TABLE_NAME`, `COLUMN_NAME`, ORDINAL_POSITION, POSITION_IN_UNIQUE_CONSTRAINT, REFERENCED_TABLE_SCHEMA, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME from information_schema.key_column_usage as kcu where 1 != 1", - "Query": "select distinct `CONSTRAINT_CATALOG`, `CONSTRAINT_SCHEMA`, `CONSTRAINT_NAME`, TABLE_CATALOG, TABLE_SCHEMA, `TABLE_NAME`, `COLUMN_NAME`, ORDINAL_POSITION, POSITION_IN_UNIQUE_CONSTRAINT, REFERENCED_TABLE_SCHEMA, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME from information_schema.key_column_usage as kcu where kcu.table_schema = :__vtschemaname /* VARCHAR */ and kcu.`table_name` = :kcu_table_name1 /* VARCHAR */", - "SysTableTableName": "[kcu_table_name1:'music']", - "SysTableTableSchema": "['user']", - "Table": "information_schema.key_column_usage" - } - ] + "OperatorType": "Route", + "Variant": "DBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select `CONSTRAINT_CATALOG`, `CONSTRAINT_SCHEMA`, `CONSTRAINT_NAME`, TABLE_CATALOG, TABLE_SCHEMA, `TABLE_NAME`, `COLUMN_NAME`, ORDINAL_POSITION, POSITION_IN_UNIQUE_CONSTRAINT, REFERENCED_TABLE_SCHEMA, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME from information_schema.key_column_usage as kcu where 1 != 1", + "Query": "select distinct `CONSTRAINT_CATALOG`, `CONSTRAINT_SCHEMA`, `CONSTRAINT_NAME`, TABLE_CATALOG, TABLE_SCHEMA, `TABLE_NAME`, `COLUMN_NAME`, ORDINAL_POSITION, POSITION_IN_UNIQUE_CONSTRAINT, REFERENCED_TABLE_SCHEMA, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME from information_schema.key_column_usage as kcu where kcu.table_schema = :__vtschemaname /* VARCHAR */ and kcu.`table_name` = :kcu_table_name /* VARCHAR */ and `CONSTRAINT_NAME` = 'primary'", + "SysTableTableName": "[kcu_table_name:'user_extra']", + "SysTableTableSchema": "['user']", + "Table": "information_schema.key_column_usage" + }, + { + "OperatorType": "Route", + "Variant": "DBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select `CONSTRAINT_CATALOG`, `CONSTRAINT_SCHEMA`, `CONSTRAINT_NAME`, TABLE_CATALOG, TABLE_SCHEMA, `TABLE_NAME`, `COLUMN_NAME`, ORDINAL_POSITION, POSITION_IN_UNIQUE_CONSTRAINT, REFERENCED_TABLE_SCHEMA, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME from information_schema.key_column_usage as kcu where 1 != 1", + "Query": "select distinct `CONSTRAINT_CATALOG`, `CONSTRAINT_SCHEMA`, `CONSTRAINT_NAME`, TABLE_CATALOG, TABLE_SCHEMA, `TABLE_NAME`, `COLUMN_NAME`, ORDINAL_POSITION, POSITION_IN_UNIQUE_CONSTRAINT, REFERENCED_TABLE_SCHEMA, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME from information_schema.key_column_usage as kcu where kcu.table_schema = :__vtschemaname /* VARCHAR */ and kcu.`table_name` = :kcu_table_name1 /* VARCHAR */ and `CONSTRAINT_NAME` = 'primary'", + "SysTableTableName": "[kcu_table_name1:'music']", + "SysTableTableSchema": "['user']", + "Table": "information_schema.key_column_usage" } ] } From ad9414996d865c99ac69636d7d5f6b845c546143 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Fri, 16 Jan 2026 19:40:58 +0000 Subject: [PATCH 026/112] [release-22.0] VDiff: Prevent division by 0 when reconciling mismatches for reference tables (#19160) (#19164) Signed-off-by: Matt Lord Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Matt Lord --- .../tabletmanager/vdiff/workflow_differ.go | 2 +- .../vdiff/workflow_differ_test.go | 114 ++++++++++++++++++ 2 files changed, 115 insertions(+), 1 deletion(-) diff --git a/go/vt/vttablet/tabletmanager/vdiff/workflow_differ.go b/go/vt/vttablet/tabletmanager/vdiff/workflow_differ.go index ea52a972d1c..a58e6ec1387 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/workflow_differ.go +++ b/go/vt/vttablet/tabletmanager/vdiff/workflow_differ.go @@ -82,7 +82,7 @@ func (wd *workflowDiffer) reconcileExtraRows(dr *DiffReport, maxExtraRowsToCompa } func (wd *workflowDiffer) reconcileReferenceTables(dr *DiffReport) error { - if dr.MismatchedRows == 0 { + if dr.MismatchedRows == 0 && dr.MatchingRows > 0 { // Get the VSchema on the target and source keyspaces. We can then use this // for handling additional edge cases, such as adjusting results for reference // tables when the shard count is different between the source and target as diff --git a/go/vt/vttablet/tabletmanager/vdiff/workflow_differ_test.go b/go/vt/vttablet/tabletmanager/vdiff/workflow_differ_test.go index dbd45f6a4d3..591acc756e8 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/workflow_differ_test.go +++ b/go/vt/vttablet/tabletmanager/vdiff/workflow_differ_test.go @@ -29,11 +29,13 @@ import ( "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/binlog/binlogplayer" "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/vtgate/engine" "vitess.io/vitess/go/vt/vtgate/engine/opcode" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" + vschemapb "vitess.io/vitess/go/vt/proto/vschema" ) func max(a, b int64) int64 { @@ -302,6 +304,118 @@ func TestReconcileExtraRows(t *testing.T) { }) } +func TestReconcileReferenceTables(t *testing.T) { + ctx := t.Context() + vdenv := newTestVDiffEnv(t) + defer vdenv.close() + UUID := uuid.New() + controllerQR := sqltypes.MakeTestResult(sqltypes.MakeTestFields( + vdiffTestCols, + vdiffTestColTypes, + ), + fmt.Sprintf("1|%s|%s|%s|%s|%s|%s|%s|", UUID, vdiffenv.workflow, tstenv.KeyspaceName, tstenv.ShardName, vdiffDBName, PendingState, optionsJS), + ) + + vdiffenv.dbClient.ExpectRequest("select * from _vt.vdiff where id = 1", noResults, nil) + ct := vdenv.newController(t, controllerQR) + ct.sourceKeyspace = tstenv.KeyspaceName + wd, err := newWorkflowDiffer(ct, vdiffenv.opts, collations.MySQL8()) + require.NoError(t, err) + + // Create VSchema for the source keyspace with a reference table. + err = tstenv.TopoServ.EnsureVSchema(ctx, tstenv.KeyspaceName) + require.NoError(t, err) + sourceVS := &vschemapb.Keyspace{ + Tables: map[string]*vschemapb.Table{ + "ref_table": { + Type: "reference", + }, + }, + } + err = tstenv.TopoServ.SaveVSchema(ctx, &topo.KeyspaceVSchemaInfo{ + Name: tstenv.KeyspaceName, + Keyspace: sourceVS, + }) + require.NoError(t, err) + + t.Run("division by zero with zero matching rows - source side", func(t *testing.T) { + dr := &DiffReport{ + TableName: "ref_table", + ProcessedRows: 10, + MatchingRows: 0, + MismatchedRows: 0, // Must be 0 to enter reconciliation logic + ExtraRowsSource: 10, + ExtraRowsSourceDiffs: []*RowDiff{{Row: map[string]string{"id": "1"}}}, + ExtraRowsTarget: 0, + } + + err := wd.reconcileReferenceTables(dr) + require.NoError(t, err) + + // Values should remain unchanged since MatchingRows is 0. + require.Equal(t, int64(10), dr.ExtraRowsSource) + require.Equal(t, int64(0), dr.ExtraRowsTarget) + }) + + t.Run("division by zero with zero matching rows - target side", func(t *testing.T) { + dr := &DiffReport{ + TableName: "ref_table", + ProcessedRows: 10, + MatchingRows: 0, + MismatchedRows: 0, // Must be 0 to enter reconciliation logic + ExtraRowsSource: 0, + ExtraRowsTarget: 10, + ExtraRowsTargetDiffs: []*RowDiff{{Row: map[string]string{"id": "1"}}}, + } + + err := wd.reconcileReferenceTables(dr) + require.NoError(t, err) + + // Values should remain unchanged since MatchingRows is 0. + require.Equal(t, int64(0), dr.ExtraRowsSource) + require.Equal(t, int64(10), dr.ExtraRowsTarget) + }) + + t.Run("reference table with positive matching rows - works correctly", func(t *testing.T) { + dr := &DiffReport{ + TableName: "ref_table", + ProcessedRows: 15, + MatchingRows: 5, + MismatchedRows: 0, + ExtraRowsSource: 10, // 10 % 5 = 0, so it's a multiple. + ExtraRowsSourceDiffs: []*RowDiff{{Row: map[string]string{"id": "1"}}}, + ExtraRowsTarget: 0, + } + + err := wd.reconcileReferenceTables(dr) + require.NoError(t, err) + + // ExtraRowsSource should be cleared since it's a multiple of MatchingRows. + require.Equal(t, int64(0), dr.ExtraRowsSource) + require.Equal(t, 0, len(dr.ExtraRowsSourceDiffs)) + }) + + t.Run("mismatched rows - reconciliation skipped entirely", func(t *testing.T) { + // With mismatched rows, reconciliation is skipped, so no VSchema access. + dr := &DiffReport{ + TableName: "ref_table", + ProcessedRows: 10, + MatchingRows: 0, + MismatchedRows: 5, // Non-zero means early return, no VSchema access + ExtraRowsSource: 10, + ExtraRowsSourceDiffs: []*RowDiff{{Row: map[string]string{"id": "1"}}}, + ExtraRowsTarget: 0, + } + + err := wd.reconcileReferenceTables(dr) + require.NoError(t, err) + + // Values should remain unchanged. + require.Equal(t, int64(10), dr.ExtraRowsSource) + require.Equal(t, int64(0), dr.ExtraRowsTarget) + }) +} + func TestBuildPlanSuccess(t *testing.T) { vdenv := newTestVDiffEnv(t) defer vdenv.close() From d5ffbdd9586e484972f2bf15ab01b3da8f9ab896 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Thu, 22 Jan 2026 20:39:35 +0000 Subject: [PATCH 027/112] [release-22.0] CI: Look for expected log message rather than code in Backup tests (#19199) (#19200) Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- go/test/endtoend/backup/vtbackup/backup_only_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/test/endtoend/backup/vtbackup/backup_only_test.go b/go/test/endtoend/backup/vtbackup/backup_only_test.go index 0ad25301af0..89871fe14f6 100644 --- a/go/test/endtoend/backup/vtbackup/backup_only_test.go +++ b/go/test/endtoend/backup/vtbackup/backup_only_test.go @@ -435,7 +435,7 @@ func verifyDisableEnableRedoLogs(ctx context.Context, t *testing.T, mysqlSocket // MY-013600 // https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html#error_er_ib_wrn_redo_disabled - qr, err = conn.ExecuteFetch("SELECT 1 FROM performance_schema.error_log WHERE error_code = 'MY-013600'", 1, false) + qr, err = conn.ExecuteFetch("SELECT 1 FROM performance_schema.error_log WHERE data like '%InnoDB redo logging is disabled%'", 1, false) require.NoError(t, err) if len(qr.Rows) != 1 { // Keep trying, possible we haven't disabled yet. @@ -444,7 +444,7 @@ func verifyDisableEnableRedoLogs(ctx context.Context, t *testing.T, mysqlSocket // MY-013601 // https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html#error_er_ib_wrn_redo_enabled - qr, err = conn.ExecuteFetch("SELECT 1 FROM performance_schema.error_log WHERE error_code = 'MY-013601'", 1, false) + qr, err = conn.ExecuteFetch("SELECT 1 FROM performance_schema.error_log WHERE data like '%InnoDB redo logging is enabled%'", 1, false) require.NoError(t, err) if len(qr.Rows) != 1 { // Keep trying, possible we haven't disabled yet. From 8cc26b8a3af08b8ae9b4b139eb813ba7e7d85edc Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Fri, 23 Jan 2026 11:06:20 -0500 Subject: [PATCH 028/112] [release-22.0] Update go-upgrade to update docker image digests (#19178) (#19188) Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Mohamed Hamza --- go.mod | 45 ++++++++----- go.sum | 92 ++++++++++++++++---------- go/tools/go-upgrade/go-upgrade.go | 51 ++++++++++++++ go/tools/go-upgrade/go-upgrade_test.go | 8 +++ 4 files changed, 143 insertions(+), 53 deletions(-) diff --git a/go.mod b/go.mod index 4df3b1013dd..cc354afe8f4 100644 --- a/go.mod +++ b/go.mod @@ -66,15 +66,15 @@ require ( go.etcd.io/etcd/client/pkg/v3 v3.5.25 go.etcd.io/etcd/client/v3 v3.5.25 go.uber.org/mock v0.5.0 - golang.org/x/crypto v0.36.0 // indirect - golang.org/x/mod v0.24.0 // indirect - golang.org/x/net v0.38.0 - golang.org/x/oauth2 v0.28.0 - golang.org/x/sys v0.31.0 - golang.org/x/term v0.30.0 - golang.org/x/text v0.23.0 // indirect + golang.org/x/crypto v0.44.0 // indirect + golang.org/x/mod v0.30.0 // indirect + golang.org/x/net v0.47.0 + golang.org/x/oauth2 v0.33.0 + golang.org/x/sys v0.38.0 + golang.org/x/term v0.37.0 + golang.org/x/text v0.31.0 // indirect golang.org/x/time v0.11.0 - golang.org/x/tools v0.31.0 + golang.org/x/tools v0.39.0 google.golang.org/api v0.226.0 google.golang.org/genproto v0.0.0-20250313205543-e70fdf4c4cb4 // indirect google.golang.org/grpc v1.71.1 @@ -98,6 +98,7 @@ require ( github.com/bndr/gotabulate v1.1.2 github.com/dustin/go-humanize v1.0.1 github.com/gammazero/deque v1.0.0 + github.com/google/go-containerregistry v0.20.6 github.com/google/safehtml v0.1.0 github.com/hashicorp/go-version v1.7.0 github.com/kr/pretty v0.3.1 @@ -109,7 +110,7 @@ require ( github.com/xlab/treeprint v1.2.0 go.uber.org/goleak v1.3.0 golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 - golang.org/x/sync v0.12.0 + golang.org/x/sync v0.18.0 gonum.org/v1/gonum v0.15.1 modernc.org/sqlite v1.36.1 ) @@ -119,7 +120,7 @@ require ( cloud.google.com/go v0.119.0 // indirect cloud.google.com/go/auth v0.15.0 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.7 // indirect - cloud.google.com/go/compute/metadata v0.6.0 // indirect + cloud.google.com/go/compute/metadata v0.7.0 // indirect cloud.google.com/go/iam v1.4.2 // indirect cloud.google.com/go/monitoring v1.24.1 // indirect github.com/DataDog/appsec-internal-go v1.10.0 // indirect @@ -149,17 +150,21 @@ require ( github.com/aws/aws-sdk-go-v2/service/sts v1.33.17 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42 // indirect + github.com/containerd/stargz-snapshotter/estargz v0.18.0 // indirect github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/docker/cli v29.0.3+incompatible // indirect + github.com/docker/distribution v2.8.3+incompatible // indirect + github.com/docker/docker-credential-helpers v0.9.3 // indirect github.com/eapache/queue/v2 v2.0.0-20230407133247-75960ed334e4 // indirect github.com/ebitengine/purego v0.8.2 // indirect github.com/envoyproxy/go-control-plane/envoy v1.32.4 // indirect github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect github.com/fatih/color v1.18.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/google/s2a-go v0.1.9 // indirect @@ -186,6 +191,8 @@ require ( github.com/ncruces/go-strftime v0.1.9 // indirect github.com/onsi/ginkgo v1.16.5 // indirect github.com/onsi/gomega v1.23.0 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.1 // indirect github.com/outcaste-io/ristretto v0.2.3 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect @@ -199,20 +206,22 @@ require ( github.com/sagikazarmark/locafero v0.7.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/secure-systems-lab/go-securesystemslib v0.9.0 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/cast v1.7.1 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect + github.com/vbatts/tar-split v0.12.2 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/detectors/gcp v1.35.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect - go.opentelemetry.io/otel v1.35.0 // indirect - go.opentelemetry.io/otel/metric v1.35.0 // indirect - go.opentelemetry.io/otel/sdk v1.35.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect - go.opentelemetry.io/otel/trace v1.35.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect + go.opentelemetry.io/otel v1.36.0 // indirect + go.opentelemetry.io/otel/metric v1.36.0 // indirect + go.opentelemetry.io/otel/sdk v1.36.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.36.0 // indirect + go.opentelemetry.io/otel/trace v1.36.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect diff --git a/go.sum b/go.sum index fcb9f3c158b..aa0e0eb85f8 100644 --- a/go.sum +++ b/go.sum @@ -8,8 +8,8 @@ cloud.google.com/go/auth v0.15.0 h1:Ly0u4aA5vG/fsSsxu98qCQBemXtAtJf+95z9HK+cxps= cloud.google.com/go/auth v0.15.0/go.mod h1:WJDGqZ1o9E9wKIL+IwStfyn/+s59zl4Bi+1KQNVXLZ8= cloud.google.com/go/auth/oauth2adapt v0.2.7 h1:/Lc7xODdqcEw8IrZ9SvwnlLX6j9FHQM74z6cBk9Rw6M= cloud.google.com/go/auth/oauth2adapt v0.2.7/go.mod h1:NTbTTzfvPl1Y3V1nPpOgl2w6d/FjO7NNUQaWSox6ZMc= -cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= -cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= +cloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU= +cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo= cloud.google.com/go/iam v1.4.2 h1:4AckGYAYsowXeHzsn/LCKWIwSWLkdb0eGjH8wWkd27Q= cloud.google.com/go/iam v1.4.2/go.mod h1:REGlrt8vSlh4dfCJfSEcNjLGq75wW75c5aU3FLOYq34= cloud.google.com/go/logging v1.13.0 h1:7j0HgAp0B94o1YRDqiqm26w4q1rDMH7XNRU34lJXHYc= @@ -144,14 +144,17 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42 h1:Om6kYQYDUk5wWbT0t0q6pvyM49i9XZAv9dDrkDA7gjk= github.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/codegangsta/cli v1.20.0/go.mod h1:/qJNoX69yVSKu5o4jLyXAENLRyk1uhi7zkbQ3slBdOA= +github.com/containerd/stargz-snapshotter/estargz v0.18.0 h1:Ny5yptQgEXSkDFKvlKJGTvf1YJ+4xD8V+hXqoRG0n74= +github.com/containerd/stargz-snapshotter/estargz v0.18.0/go.mod h1:7hfU1BO2KB3axZl0dRQCdnHrIWw7TRDdK6L44Rdeuo0= github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/corpix/uarand v0.1.1 h1:RMr1TWc9F4n5jiPDzFHtmaUXLKLNUFK0SgCLo4BhX/U= github.com/corpix/uarand v0.1.1/go.mod h1:SFKZvkcRoLqVRFZ4u25xPmp6m9ktANfbpXZ7SJ0/FNU= -github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo= +github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/dave/jennifer v1.7.1 h1:B4jJJDHelWcDhlRQxWeo0Npa/pYKBLrirAQoTN45txo= github.com/dave/jennifer v1.7.1/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3RmGZc= @@ -162,6 +165,12 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/docker/cli v29.0.3+incompatible h1:8J+PZIcF2xLd6h5sHPsp5pvvJA+Sr2wGQxHkRl53a1E= +github.com/docker/cli v29.0.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= +github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8= +github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= @@ -205,8 +214,8 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= @@ -248,6 +257,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-containerregistry v0.20.6 h1:cvWX87UxxLgaH76b4hIvya6Dzz9qHB31qAwjAohdSTU= +github.com/google/go-containerregistry v0.20.6/go.mod h1:T0x8MuoAoKX/873bkeSfLD2FAkwCDf9/HZgsFJ02E2Y= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -409,6 +420,10 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.23.0 h1:/oxKu9c2HVap+F3PfKort2Hw5DEU+HGlW8n+tguWsys= github.com/onsi/gomega v1.23.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= +github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= github.com/opentracing-contrib/go-grpc v0.1.1 h1:Ws7IN1zyiL1DFqKQPhRXuKe5pLYzMfdxnC1qtajE2PE= github.com/opentracing-contrib/go-grpc v0.1.1/go.mod h1:Nu6sz+4zzgxXu8rvKfnwjBEmHsuhTigxRwV2RhELrS8= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -492,6 +507,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sjmudd/stopwatch v0.1.1 h1:x45OvxFB5OtCkjvYtzRF5fWB857Jzjjk84Oyd5C5ebw= github.com/sjmudd/stopwatch v0.1.1/go.mod h1:BLw0oIQJ1YLXBO/q9ufK/SgnKBVIkC2qrm6uy78Zw6U= github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= @@ -549,6 +566,8 @@ github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaO github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/vbatts/tar-split v0.12.2 h1:w/Y6tjxpeiFMR47yzZPlPj/FcPLpXbTUi/9H7d3CPa4= +github.com/vbatts/tar-split v0.12.2/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= @@ -570,20 +589,20 @@ go.opentelemetry.io/contrib/detectors/gcp v1.35.0 h1:bGvFt68+KTiAKFlacHW6AhA56GF go.opentelemetry.io/contrib/detectors/gcp v1.35.0/go.mod h1:qGWP8/+ILwMRIUf9uIVLloR1uo5ZYAslM4O6OqUi1DA= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= -go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= -go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= +go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= +go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0 h1:WDdP9acbMYjbKIyJUhTvtzj601sVJOqgWdUxSdR/Ysc= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0/go.mod h1:BLbf7zbNIONBLPwvFnwNHGj4zge8uTCM/UPIVW1Mq2I= -go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= -go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= -go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY= -go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= -go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o= -go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= -go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= -go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= +go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= +go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= +go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= +go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= +go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis= +go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= +go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= +go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= @@ -606,8 +625,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= +golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw= golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM= @@ -618,8 +637,8 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= -golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= +golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= +golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -639,12 +658,12 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc= -golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= +golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= +golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -653,8 +672,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= -golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= +golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -688,18 +707,19 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= -golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= +golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= +golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -713,8 +733,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU= -golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ= +golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= +golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -786,6 +806,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= modernc.org/cc/v4 v4.24.4 h1:TFkx1s6dCkQpd6dKurBNmpo+G8Zl4Sq/ztJ+2+DEsh0= diff --git a/go/tools/go-upgrade/go-upgrade.go b/go/tools/go-upgrade/go-upgrade.go index 7b36fd14c02..fed0632691b 100644 --- a/go/tools/go-upgrade/go-upgrade.go +++ b/go/tools/go-upgrade/go-upgrade.go @@ -31,6 +31,8 @@ import ( "encoding/json" + "github.com/google/go-containerregistry/pkg/crane" + gocr "github.com/google/go-containerregistry/pkg/v1" "github.com/hashicorp/go-version" "github.com/spf13/cobra" ) @@ -38,6 +40,15 @@ import ( const ( goDevAPI = "https://go.dev/dl/?mode=json" + // dockerPlatformOS is the target OS for the Go base image. + dockerPlatformOS = "linux" + + // dockerPlatformArch is the target architecture for the Go base image. + dockerPlatformArch = "amd64" + + // dockerImageDistro is the distro suffix used in Go base image tags. + dockerImageDistro = "bookworm" + // regexpFindBootstrapVersion greps the current bootstrap version from the Makefile. The bootstrap // version is composed of either one or two numbers, for instance: 18.1 or 18. // The expected format of the input is BOOTSTRAP_VERSION=18 or BOOTSTRAP_VERSION=18.1 @@ -65,6 +76,15 @@ const ( regexpReplaceTestGoBootstrapVersion = `\"bootstrap-version\",[[:space:]]*\"([0-9.]+)\"` ) +// regexpReplaceGolangDockerImage replaces the Go version and image digest in Dockerfiles. +// Example input: "FROM --platform=linux/amd64 golang:1.25.3-bookworm@sha256:abc AS builder" +var regexpReplaceGolangDockerImage = fmt.Sprintf( + `(?i)(FROM[[:space:]]+--platform=%s/%s[[:space:]]+golang:)([0-9.]+-%s)@sha256:[a-f0-9]{64}`, + dockerPlatformOS, + dockerPlatformArch, + dockerImageDistro, +) + type ( latestGolangRelease struct { Version string `json:"version"` @@ -365,6 +385,22 @@ func replaceGoVersionInCodebase(old, new *version.Version) error { } } + dockerDigest, err := resolveGolangImageDigest(new) + if err != nil { + return err + } + + for _, fileToChange := range filesToChange { + err = replaceInFile( + []*regexp.Regexp{regexp.MustCompile(regexpReplaceGolangDockerImage)}, + []string{fmt.Sprintf("${1}%s@%s", golangDockerTag(new), dockerDigest)}, + fileToChange, + ) + if err != nil { + return err + } + } + if !isSameMajorMinorVersion(old, new) { goModFiles := []string{"./go.mod"} for _, file := range goModFiles { @@ -381,6 +417,21 @@ func replaceGoVersionInCodebase(old, new *version.Version) error { return nil } +func resolveGolangImageDigest(goVersion *version.Version) (string, error) { + ref := "golang:" + golangDockerTag(goVersion) + + digest, err := crane.Digest(ref, crane.WithPlatform(&gocr.Platform{OS: dockerPlatformOS, Architecture: dockerPlatformArch})) + if err != nil { + return "", fmt.Errorf("resolve golang digest for %s: %w", ref, err) + } + + return digest, nil +} + +func golangDockerTag(goVersion *version.Version) string { + return goVersion.String() + "-" + dockerImageDistro +} + func updateBootstrapVersionInCodebase(old, new string, newGoVersion *version.Version) error { if old == new { return nil diff --git a/go/tools/go-upgrade/go-upgrade_test.go b/go/tools/go-upgrade/go-upgrade_test.go index 6995ccb4002..438d5dc783f 100644 --- a/go/tools/go-upgrade/go-upgrade_test.go +++ b/go/tools/go-upgrade/go-upgrade_test.go @@ -87,6 +87,14 @@ func TestRegularExpressions(t *testing.T) { require.Equal(t, `flag.String("bootstrap-version", "18.2", "the version identifier to use for the docker images")`, res) }, }, + { + regexp: regexpReplaceGolangDockerImage, + input: "FROM --platform=linux/amd64 golang:1.25.3-bookworm@sha256:414a753c2f67d0efccb01b5f58b3d3a8a2cbb7c012ce9e535418b5b3492b2c24 AS builder", + checkF: func(t *testing.T, regexp *regexp.Regexp, input string) { + res := regexp.ReplaceAllString(input, "${1}1.25.4-bookworm@sha256:1111111111111111111111111111111111111111111111111111111111111111") + require.Equal(t, "FROM --platform=linux/amd64 golang:1.25.4-bookworm@sha256:1111111111111111111111111111111111111111111111111111111111111111 AS builder", res) + }, + }, } for _, list := range lists { From 22c70bcf9e586cb3b01f4e41a4908efc4f032e01 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Sat, 24 Jan 2026 09:40:06 -0500 Subject: [PATCH 029/112] [release-22.0] Fix sporadic TestServingKeyspaces panic on context cancellation (#19163) (#19186) Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- go/vt/vtgate/sandbox_test.go | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/go/vt/vtgate/sandbox_test.go b/go/vt/vtgate/sandbox_test.go index 6030de2ba59..f2f6e974bac 100644 --- a/go/vt/vtgate/sandbox_test.go +++ b/go/vt/vtgate/sandbox_test.go @@ -297,6 +297,11 @@ func (sct *sandboxTopo) WatchSrvVSchema(ctx context.Context, cell string, callba return } + // Context may already be canceled during test cleanup - exit gracefully. + if ctx.Err() != nil { + return + } + // Update the backing topo server with the current sandbox vschemas. for ks := range ksToSandbox { ksvs := &topo.KeyspaceVSchemaInfo{ @@ -304,12 +309,23 @@ func (sct *sandboxTopo) WatchSrvVSchema(ctx context.Context, cell string, callba Keyspace: srvVSchema.Keyspaces[ks], } if err := sct.topoServer.SaveVSchema(ctx, ksvs); err != nil { + if ctx.Err() != nil { + return + } panic(fmt.Sprintf("sandboxTopo SaveVSchema returned an error: %v", err)) } } - sct.topoServer.UpdateSrvVSchema(ctx, cell, srvVSchema) + if err := sct.topoServer.UpdateSrvVSchema(ctx, cell, srvVSchema); err != nil { + if ctx.Err() != nil { + return + } + panic(fmt.Sprintf("sandboxTopo UpdateSrvVSchema returned an error: %v", err)) + } current, updateChan, err := sct.topoServer.WatchSrvVSchema(ctx, cell) if err != nil { + if ctx.Err() != nil { + return + } panic(fmt.Sprintf("sandboxTopo WatchSrvVSchema returned an error: %v", err)) } if !callback(current.Value, nil) { From dd9442c1d072e1a7498cfa57e9458a4ffa77cf62 Mon Sep 17 00:00:00 2001 From: Mohamed Hamza Date: Sat, 24 Jan 2026 19:39:11 -0500 Subject: [PATCH 030/112] [release-22.0] Fix major upgrade logic in go upgrade tool (#19211) --- .github/workflows/update_golang_version.yml | 2 +- go/tools/go-upgrade/go-upgrade.go | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/update_golang_version.yml b/.github/workflows/update_golang_version.yml index a1d2bdbcc97..f1f7bcbde8d 100644 --- a/.github/workflows/update_golang_version.yml +++ b/.github/workflows/update_golang_version.yml @@ -56,7 +56,7 @@ jobs: echo "bootstrap-version=${bootstrap_version}" >> $GITHUB_OUTPUT # Check if the PR already exists, if it does then do not create new PR. - gh pr list -S "is:open [${{ matrix.branch }}] Upgrade the Golang version to go${go_version}" > out.txt 2>&1 | true + gh pr list -S 'is:open "[${{ matrix.branch }}] Upgrade the Golang version to go${go_version}"' > out.txt 2>&1 | true if [ -s out.txt ]; then rm -f out.txt exit 0 diff --git a/go/tools/go-upgrade/go-upgrade.go b/go/tools/go-upgrade/go-upgrade.go index fed0632691b..b1376e5e2be 100644 --- a/go/tools/go-upgrade/go-upgrade.go +++ b/go/tools/go-upgrade/go-upgrade.go @@ -401,12 +401,12 @@ func replaceGoVersionInCodebase(old, new *version.Version) error { } } - if !isSameMajorMinorVersion(old, new) { + if !isSameVersion(old, new) { goModFiles := []string{"./go.mod"} for _, file := range goModFiles { err = replaceInFile( []*regexp.Regexp{regexp.MustCompile(regexpReplaceGoModGoVersion)}, - []string{fmt.Sprintf("go %d.%d", new.Segments()[0], new.Segments()[1])}, + []string{fmt.Sprintf("go %d.%d.%d", new.Segments()[0], new.Segments()[1], new.Segments()[2])}, file, ) if err != nil { @@ -502,6 +502,10 @@ func updateBootstrapChangelog(new string, goVersion *version.Version) error { return nil } +func isSameVersion(a, b *version.Version) bool { + return a.Segments()[0] == b.Segments()[0] && a.Segments()[1] == b.Segments()[1] && a.Segments()[2] == b.Segments()[2] +} + func isSameMajorMinorVersion(a, b *version.Version) bool { return a.Segments()[0] == b.Segments()[0] && a.Segments()[1] == b.Segments()[1] } From c925356abbc71890e5f025678bab7ff88618da73 Mon Sep 17 00:00:00 2001 From: Matt Lord Date: Mon, 26 Jan 2026 09:37:30 -0500 Subject: [PATCH 031/112] [release-22.0] CI: Use new Percona Server repo name (#19221) Signed-off-by: Matt Lord --- .github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml | 2 +- .github/workflows/cluster_endtoend_xb_backup.yml | 2 +- .github/workflows/cluster_endtoend_xb_recovery.yml | 2 +- test/templates/cluster_endtoend_test.tpl | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml b/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml index bea73382a26..53c2655568b 100644 --- a/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml +++ b/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml @@ -85,7 +85,7 @@ jobs: sudo apt-get -qq install -y lsb-release gnupg2 wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb sudo DEBIAN_FRONTEND="noninteractive" dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb - sudo percona-release setup ps80 + sudo percona-release setup pdps8.0 sudo apt-get -qq update sudo apt-get -qq install -y percona-server-server percona-server-client diff --git a/.github/workflows/cluster_endtoend_xb_backup.yml b/.github/workflows/cluster_endtoend_xb_backup.yml index 22de31fcad1..bd62836a14b 100644 --- a/.github/workflows/cluster_endtoend_xb_backup.yml +++ b/.github/workflows/cluster_endtoend_xb_backup.yml @@ -85,7 +85,7 @@ jobs: sudo apt-get -qq install -y lsb-release gnupg2 wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb sudo DEBIAN_FRONTEND="noninteractive" dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb - sudo percona-release setup ps80 + sudo percona-release setup pdps8.0 sudo apt-get -qq update sudo apt-get -qq install -y percona-server-server percona-server-client diff --git a/.github/workflows/cluster_endtoend_xb_recovery.yml b/.github/workflows/cluster_endtoend_xb_recovery.yml index ee2627f0b09..f9039793633 100644 --- a/.github/workflows/cluster_endtoend_xb_recovery.yml +++ b/.github/workflows/cluster_endtoend_xb_recovery.yml @@ -85,7 +85,7 @@ jobs: sudo apt-get -qq install -y lsb-release gnupg2 wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb sudo DEBIAN_FRONTEND="noninteractive" dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb - sudo percona-release setup ps80 + sudo percona-release setup pdps8.0 sudo apt-get -qq update sudo apt-get -qq install -y percona-server-server percona-server-client diff --git a/test/templates/cluster_endtoend_test.tpl b/test/templates/cluster_endtoend_test.tpl index 3f6fa608b5b..ac6a1611919 100644 --- a/test/templates/cluster_endtoend_test.tpl +++ b/test/templates/cluster_endtoend_test.tpl @@ -115,7 +115,7 @@ jobs: sudo apt-get -qq install -y lsb-release gnupg2 wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb sudo DEBIAN_FRONTEND="noninteractive" dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb - sudo percona-release setup ps80 + sudo percona-release setup pdps8.0 sudo apt-get -qq update sudo apt-get -qq install -y percona-server-server percona-server-client From 57241c2e5a86cfef68818ef9c82d71dddb6d3ae2 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Mon, 26 Jan 2026 09:46:14 -0500 Subject: [PATCH 032/112] [release-22.0] Fix go upgrade workflow (#19216) (#19219) Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- .github/workflows/update_golang_version.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/update_golang_version.yml b/.github/workflows/update_golang_version.yml index f1f7bcbde8d..3fb20b3f87b 100644 --- a/.github/workflows/update_golang_version.yml +++ b/.github/workflows/update_golang_version.yml @@ -32,6 +32,7 @@ jobs: - name: Detect new version and update codebase env: GH_TOKEN: ${{ github.token }} + GOTOOLCHAIN: auto id: detect-and-update run: | old_go_version=$(go run ./go/tools/go-upgrade/go-upgrade.go get go-version) From 9869e92689b2d5fc1d9c71e53a5709c14338d248 Mon Sep 17 00:00:00 2001 From: vitess-go-upgrade-bot <139342327+vitess-bot@users.noreply.github.com> Date: Mon, 26 Jan 2026 22:31:42 -0400 Subject: [PATCH 033/112] [release-22.0] Upgrade the Golang version to `go1.24.12` (#19222) Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Signed-off-by: Matt Lord Co-authored-by: frouioui <35779988+frouioui@users.noreply.github.com> --- Makefile | 2 +- build.env | 2 +- docker/bootstrap/CHANGELOG.md | 6 +++++- docker/bootstrap/Dockerfile.common | 2 +- docker/lite/Dockerfile | 2 +- docker/lite/Dockerfile.mysql84 | 2 +- docker/lite/Dockerfile.percona80 | 2 +- docker/vttestserver/Dockerfile.mysql80 | 2 +- docker/vttestserver/Dockerfile.mysql84 | 2 +- go.mod | 2 +- test.go | 2 +- test/templates/dockerfile.tpl | 2 +- 12 files changed, 16 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index 1ddba949b1e..9e2e697a9e2 100644 --- a/Makefile +++ b/Makefile @@ -286,7 +286,7 @@ $(PROTO_GO_OUTS): minimaltools install_protoc-gen-go proto/*.proto # This rule builds the bootstrap images for all flavors. DOCKER_IMAGES_FOR_TEST = mysql80 mysql84 percona80 DOCKER_IMAGES = common $(DOCKER_IMAGES_FOR_TEST) -BOOTSTRAP_VERSION=43.5 +BOOTSTRAP_VERSION=43.6 ensure_bootstrap_version: find docker/ -type f -exec sed -i "s/^\(ARG bootstrap_version\)=.*/\1=${BOOTSTRAP_VERSION}/" {} \; sed -i 's/\(^.*flag.String(\"bootstrap-version\",\) *\"[^\"]\+\"/\1 \"${BOOTSTRAP_VERSION}\"/' test.go diff --git a/build.env b/build.env index 140c27f5cb9..6ae62334ef0 100755 --- a/build.env +++ b/build.env @@ -17,7 +17,7 @@ source ./tools/shell_functions.inc go version >/dev/null 2>&1 || fail "Go is not installed or is not in \$PATH. See https://vitess.io/contributing/build-from-source for install instructions." -goversion_min 1.24.10 || echo "Go version reported: `go version`. Version 1.24.10+ recommended. See https://vitess.io/contributing/build-from-source for install instructions." +goversion_min 1.24.12 || echo "Go version reported: `go version`. Version 1.24.12+ recommended. See https://vitess.io/contributing/build-from-source for install instructions." mkdir -p dist mkdir -p bin diff --git a/docker/bootstrap/CHANGELOG.md b/docker/bootstrap/CHANGELOG.md index 2275c4a5163..04630166b29 100644 --- a/docker/bootstrap/CHANGELOG.md +++ b/docker/bootstrap/CHANGELOG.md @@ -194,4 +194,8 @@ List of changes between bootstrap image versions. ## [43.5] - 2025-11-12 ### Changes -- Update build to golang 1.24.10 \ No newline at end of file +- Update build to golang 1.24.10 + +## [43.6] - 2026-01-27 +### Changes +- Update build to golang 1.24.12 \ No newline at end of file diff --git a/docker/bootstrap/Dockerfile.common b/docker/bootstrap/Dockerfile.common index 53f86503f2f..9117c401407 100644 --- a/docker/bootstrap/Dockerfile.common +++ b/docker/bootstrap/Dockerfile.common @@ -1,4 +1,4 @@ -FROM --platform=linux/amd64 golang:1.24.10-bookworm@sha256:6d78b05df97ae4d12e887f2f2ba6bd0d1b9d644bcf63604fbb4c43cf6839ed9c +FROM --platform=linux/amd64 golang:1.24.12-bookworm@sha256:8972893fa12177951b8bd4118470f338eaecea133c323be84066cd64f844fc03 # Install Vitess build dependencies RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ diff --git a/docker/lite/Dockerfile b/docker/lite/Dockerfile index 7bc43d42776..a23413c473d 100644 --- a/docker/lite/Dockerfile +++ b/docker/lite/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.24.10-bookworm@sha256:6d78b05df97ae4d12e887f2f2ba6bd0d1b9d644bcf63604fbb4c43cf6839ed9c AS builder +FROM --platform=linux/amd64 golang:1.24.12-bookworm@sha256:8972893fa12177951b8bd4118470f338eaecea133c323be84066cd64f844fc03 AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER diff --git a/docker/lite/Dockerfile.mysql84 b/docker/lite/Dockerfile.mysql84 index 52d61fd65b3..a2d0b08ac18 100644 --- a/docker/lite/Dockerfile.mysql84 +++ b/docker/lite/Dockerfile.mysql84 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.24.10-bookworm@sha256:6d78b05df97ae4d12e887f2f2ba6bd0d1b9d644bcf63604fbb4c43cf6839ed9c AS builder +FROM --platform=linux/amd64 golang:1.24.12-bookworm@sha256:8972893fa12177951b8bd4118470f338eaecea133c323be84066cd64f844fc03 AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER diff --git a/docker/lite/Dockerfile.percona80 b/docker/lite/Dockerfile.percona80 index 41b3d9b2c2a..b4ed5bb0098 100644 --- a/docker/lite/Dockerfile.percona80 +++ b/docker/lite/Dockerfile.percona80 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.24.10-bookworm@sha256:6d78b05df97ae4d12e887f2f2ba6bd0d1b9d644bcf63604fbb4c43cf6839ed9c AS builder +FROM --platform=linux/amd64 golang:1.24.12-bookworm@sha256:8972893fa12177951b8bd4118470f338eaecea133c323be84066cd64f844fc03 AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER diff --git a/docker/vttestserver/Dockerfile.mysql80 b/docker/vttestserver/Dockerfile.mysql80 index c7711b5a645..5b4dfac9cff 100644 --- a/docker/vttestserver/Dockerfile.mysql80 +++ b/docker/vttestserver/Dockerfile.mysql80 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.24.10-bookworm@sha256:6d78b05df97ae4d12e887f2f2ba6bd0d1b9d644bcf63604fbb4c43cf6839ed9c AS builder +FROM --platform=linux/amd64 golang:1.24.12-bookworm@sha256:8972893fa12177951b8bd4118470f338eaecea133c323be84066cd64f844fc03 AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER diff --git a/docker/vttestserver/Dockerfile.mysql84 b/docker/vttestserver/Dockerfile.mysql84 index fe4d50b5283..ac727de46cb 100644 --- a/docker/vttestserver/Dockerfile.mysql84 +++ b/docker/vttestserver/Dockerfile.mysql84 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.24.10-bookworm@sha256:6d78b05df97ae4d12e887f2f2ba6bd0d1b9d644bcf63604fbb4c43cf6839ed9c AS builder +FROM --platform=linux/amd64 golang:1.24.12-bookworm@sha256:8972893fa12177951b8bd4118470f338eaecea133c323be84066cd64f844fc03 AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER diff --git a/go.mod b/go.mod index cc354afe8f4..45a0cb1b0d6 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module vitess.io/vitess -go 1.24.10 +go 1.24.12 require ( cloud.google.com/go/storage v1.51.0 diff --git a/test.go b/test.go index a61861890ae..c1a235d9d33 100755 --- a/test.go +++ b/test.go @@ -77,7 +77,7 @@ For example: // Flags var ( flavor = flag.String("flavor", "mysql80", "comma-separated bootstrap flavor(s) to run against (when using Docker mode). Available flavors: all,"+flavors) - bootstrapVersion = flag.String("bootstrap-version", "43.5", "the version identifier to use for the docker images") + bootstrapVersion = flag.String("bootstrap-version", "43.6", "the version identifier to use for the docker images") runCount = flag.Int("runs", 1, "run each test this many times") retryMax = flag.Int("retry", 3, "max number of retries, to detect flaky tests") logPass = flag.Bool("log-pass", false, "log test output even if it passes") diff --git a/test/templates/dockerfile.tpl b/test/templates/dockerfile.tpl index 3f0afe39e1b..53174e391ea 100644 --- a/test/templates/dockerfile.tpl +++ b/test/templates/dockerfile.tpl @@ -1,4 +1,4 @@ -ARG bootstrap_version=43.5 +ARG bootstrap_version=43.6 ARG image="vitess/bootstrap:${bootstrap_version}-{{.Platform}}" FROM "${image}" From 04ada2629f7e7bc7ca8ae2f8b6f80d1c7a3268ab Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Tue, 27 Jan 2026 08:39:54 -0500 Subject: [PATCH 034/112] [release-22.0] VReplication: Properly Handle Sequence Table Initialization For Empty Tables (#19226) (#19227) Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Matt Lord --- go/vt/vtctl/workflow/sequences.go | 20 +++++----- go/vt/vtctl/workflow/sequences_test.go | 53 +++++++++++++++++++++----- 2 files changed, 53 insertions(+), 20 deletions(-) diff --git a/go/vt/vtctl/workflow/sequences.go b/go/vt/vtctl/workflow/sequences.go index 5c1e2ca7fa6..e1a13b96b72 100644 --- a/go/vt/vtctl/workflow/sequences.go +++ b/go/vt/vtctl/workflow/sequences.go @@ -166,18 +166,21 @@ func (ts *trafficSwitcher) getMaxSequenceValue(ctx context.Context, seq *sequenc Query: []byte(query.Query), MaxRows: 1, }) - if terr != nil || len(qr.Rows) != 1 { + if terr != nil { return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "failed to get the max used sequence value for target table %s.%s on tablet %s in order to initialize the backing sequence table: %v", ts.targetKeyspace, seq.usingTableName, topoproto.TabletAliasString(primary.Alias), terr) } - rawVal := sqltypes.Proto3ToResult(qr).Rows[0][0] maxID := int64(0) - if !rawVal.IsNull() { // If it's NULL then there are no rows and 0 remains the max - maxID, terr = rawVal.ToInt64() - if terr != nil { - return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "failed to get the max used sequence value for target table %s.%s on tablet %s in order to initialize the backing sequence table: %v", - ts.targetKeyspace, seq.usingTableName, topoproto.TabletAliasString(primary.Alias), terr) + // If no rows are returned, max remains 0. + if len(qr.Rows) != 0 { + rawVal := sqltypes.Proto3ToResult(qr).Rows[0][0] + if !rawVal.IsNull() { // If it's NULL then 0 remains the max + maxID, terr = rawVal.ToInt64() + if terr != nil { + return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "failed to get the max used sequence value for target table %s.%s on tablet %s in order to initialize the backing sequence table: %v", + ts.targetKeyspace, seq.usingTableName, topoproto.TabletAliasString(primary.Alias), terr) + } } } setMaxSequenceValue(maxID) @@ -352,9 +355,6 @@ func (ts *trafficSwitcher) initializeTargetSequences(ctx context.Context, sequen } for _, sm := range sequencesByBackingTable { maxValue := maxValues[sm.backingTableName] - if maxValue == 0 { - continue - } if err := ts.updateSequenceValue(ctx, sm, maxValue); err != nil { return err } diff --git a/go/vt/vtctl/workflow/sequences_test.go b/go/vt/vtctl/workflow/sequences_test.go index 61b020c1e2a..3822e2822a3 100644 --- a/go/vt/vtctl/workflow/sequences_test.go +++ b/go/vt/vtctl/workflow/sequences_test.go @@ -28,12 +28,13 @@ import ( "vitess.io/vitess/go/sqlescape" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/mysqlctl/tmutils" - tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" "vitess.io/vitess/go/vt/proto/vschema" - vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/vttablet/tabletmanager/vreplication" + + tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" ) func TestInitializeTargetSequences(t *testing.T) { @@ -89,16 +90,48 @@ func TestInitializeTargetSequences(t *testing.T) { }, } - env.tmc.expectVRQuery(200, "/select max.*", sqltypes.MakeTestResult(sqltypes.MakeTestFields("maxval", "int64"), "34")) - // Expect the insert query to be executed with 35 as a params, since we provide a maxID of 34 in the last query - env.tmc.expectVRQuery(100, "/insert into.*35.*", &sqltypes.Result{RowsAffected: 1}) + type testCase struct { + name string + selectMaxQuery string + selectMaxResult *sqltypes.Result + insertQuery string + } - err = sw.initializeTargetSequences(ctx, sequencesByBackingTable) - assert.NoError(t, err) + testCases := []testCase{ + { + name: "initialize sequences", + selectMaxQuery: "/select max.*", + selectMaxResult: sqltypes.MakeTestResult( + sqltypes.MakeTestFields("maxval", "int64"), + "34", + ), + insertQuery: "/insert into.*35.*", + }, + { + name: "initialize sequences for empty tables", + selectMaxQuery: "/select max.*", + selectMaxResult: sqltypes.MakeTestResult( + sqltypes.MakeTestFields("maxval", "int64"), + ), + insertQuery: "/insert into.*1.*", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // Expect the select max query to be executed + env.tmc.expectVRQuery(200, tc.selectMaxQuery, tc.selectMaxResult) + // Expect the insert query to be executed + env.tmc.expectVRQuery(100, tc.insertQuery, &sqltypes.Result{RowsAffected: 1}) + + err = sw.initializeTargetSequences(ctx, sequencesByBackingTable) + assert.NoError(t, err) - // Expect the queries to be cleared - assert.Emptyf(t, env.tmc.vrQueries[100], "expected no queries to be executed, found: %q", env.tmc.vrQueries[100]) - assert.Empty(t, env.tmc.vrQueries[200], "expected no queries to be executed, found: %q", env.tmc.vrQueries[200]) + // Expect the queries to be cleared + assert.Emptyf(t, env.tmc.vrQueries[100], "expected no queries to be executed, found: %q", env.tmc.vrQueries[100]) + assert.Empty(t, env.tmc.vrQueries[200], "expected no queries to be executed, found: %q", env.tmc.vrQueries[200]) + }) + } } func TestGetTargetSequenceMetadata(t *testing.T) { From bd45bd69cf4b9785d17693524f69e95ecbf7fdb3 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Tue, 27 Jan 2026 15:08:00 -0500 Subject: [PATCH 035/112] [release-22.0] `vtorc`: detect errant GTIDs for replicas not connected to primary (#19224) (#19233) Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- go/vt/vtorc/inst/instance_dao.go | 59 +++++++---- go/vt/vtorc/inst/instance_dao_test.go | 147 ++++++++++++++++++++++---- 2 files changed, 170 insertions(+), 36 deletions(-) diff --git a/go/vt/vtorc/inst/instance_dao.go b/go/vt/vtorc/inst/instance_dao.go index eae38bc955f..f975008a1e6 100644 --- a/go/vt/vtorc/inst/instance_dao.go +++ b/go/vt/vtorc/inst/instance_dao.go @@ -405,27 +405,37 @@ Cleanup: func detectErrantGTIDs(instance *Instance, tablet *topodatapb.Tablet) (err error) { // If the tablet is not replicating from anyone, then it could be the previous primary. // We should check for errant GTIDs by finding the difference with the shard's current primary. - if instance.primaryExecutedGtidSet == "" && instance.SourceHost == "" { - var primaryInstance *Instance - primaryAlias, _, _ := ReadShardPrimaryInformation(tablet.Keyspace, tablet.Shard) - if primaryAlias != "" { - // Check if the current tablet is the primary. - // If it is, then we don't need to run errant gtid detection on it. - if primaryAlias == instance.InstanceAlias { - return nil - } - primaryInstance, _, _ = ReadInstance(primaryAlias) + primaryAlias, _, err := ReadShardPrimaryInformation(tablet.Keyspace, tablet.Shard) + if err != nil { + return fmt.Errorf("failed to read shard primary for %s/%s: %w", tablet.Keyspace, tablet.Shard, err) + } + + // Check if the current tablet is the primary. If it is, then we don't need to + // run errant GTID detection on it. + if primaryAlias == instance.InstanceAlias { + return nil + } + + var primaryInstance *Instance + if primaryAlias != "" { + primaryInstance, _, err = ReadInstance(primaryAlias) + if err != nil { + return fmt.Errorf("failed to read primary instance %q: %w", primaryAlias, err) } - // Only run errant GTID detection, if we are sure that the data read of the current primary - // is up-to-date enough to reflect that it has been promoted. This is needed to prevent - // flagging incorrect errant GTIDs. If we were to use old data, we could have some GTIDs - // accepted by the old primary (this tablet) that don't show in the new primary's set. - if primaryInstance != nil { - if primaryInstance.SourceHost == "" { - instance.primaryExecutedGtidSet = primaryInstance.ExecutedGtidSet - } + } + + // Only run errant GTID detection if we are sure that the data read of the current primary + // is up-to-date enough to reflect that it has been promoted. This is needed to prevent + // flagging incorrect errant GTIDs. If we were to use old data, we could have some GTIDs + // accepted by the old primary (this tablet) that don't show in the new primary's set. + if primaryInstance != nil && primaryInstance.SourceHost == "" { + // If the instance has no replication source and no primary GTID set yet, or if the instance's replication + // source is not the primary, use the shard primary's executed GTID set for comparison. + if (instance.SourceHost == "" && instance.primaryExecutedGtidSet == "") || !sourceIsPrimary(instance, primaryInstance) { + instance.primaryExecutedGtidSet = primaryInstance.ExecutedGtidSet } } + if instance.ExecutedGtidSet != "" && instance.primaryExecutedGtidSet != "" { // Compare primary & replica GTID sets, but ignore the sets that present the primary's UUID. // This is because vtorc may pool primary and replica at an inconvenient timing, @@ -458,6 +468,19 @@ func detectErrantGTIDs(instance *Instance, tablet *topodatapb.Tablet) (err error return err } +// sourceIsPrimary returns true if the instance's replication source is the given primary. +func sourceIsPrimary(instance *Instance, primaryInstance *Instance) bool { + if instance.SourceHost == "" { + return false + } + + if instance.SourceUUID != "" && primaryInstance.ServerUUID != "" { + return instance.SourceUUID == primaryInstance.ServerUUID + } + + return instance.SourceHost == primaryInstance.Hostname && instance.SourcePort == primaryInstance.Port +} + // getKeyspaceShardName returns a single string having both the keyspace and shard func getKeyspaceShardName(keyspace, shard string) string { return fmt.Sprintf("%v:%v", keyspace, shard) diff --git a/go/vt/vtorc/inst/instance_dao_test.go b/go/vt/vtorc/inst/instance_dao_test.go index c07f303b9d2..3c0e06c021b 100644 --- a/go/vt/vtorc/inst/instance_dao_test.go +++ b/go/vt/vtorc/inst/instance_dao_test.go @@ -898,6 +898,29 @@ func TestExpireTableData(t *testing.T) { } func TestDetectErrantGTIDs(t *testing.T) { + keyspaceName := "ks" + shardName := "0" + tablet := &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone-1", + Uid: 100, + }, + Keyspace: keyspaceName, + Shard: shardName, + } + primaryTablet := &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone-1", + Uid: 101, + }, + Keyspace: keyspaceName, + Shard: shardName, + Type: topodatapb.TabletType_PRIMARY, + + MysqlHostname: "primary-host", + MysqlPort: 6714, + } + tests := []struct { name string instance *Instance @@ -947,6 +970,8 @@ func TestDetectErrantGTIDs(t *testing.T) { primaryInstance: &Instance{ SourceHost: "", ExecutedGtidSet: "230ea8ea-81e3-11e4-972a-e25ec4bd140a:1-10589,8bc65c84-3fe4-11ed-a912-257f0fcdd6c9:1-34,316d193c-70e5-11e5-adb2-ecf4bb2262ff:1-341", + Hostname: primaryTablet.MysqlHostname, + Port: int(primaryTablet.MysqlPort), }, wantErrantGTID: "316d193c-70e5-11e5-adb2-ecf4bb2262ff:342", }, { @@ -963,24 +988,6 @@ func TestDetectErrantGTIDs(t *testing.T) { }, } - keyspaceName := "ks" - shardName := "0" - tablet := &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{ - Cell: "zone-1", - Uid: 100, - }, - Keyspace: keyspaceName, - Shard: shardName, - } - primaryTablet := &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{ - Cell: "zone-1", - Uid: 101, - }, - Keyspace: keyspaceName, - Shard: shardName, - } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Clear the database after the test. The easiest way to do that is to run all the initialization commands again. @@ -997,6 +1004,7 @@ func TestDetectErrantGTIDs(t *testing.T) { if tt.primaryInstance != nil { tt.primaryInstance.InstanceAlias = topoproto.TabletAliasString(primaryTablet.Alias) + err = SaveTablet(primaryTablet) require.NoError(t, err) err = WriteInstance(tt.primaryInstance, true, nil) @@ -1015,6 +1023,109 @@ func TestDetectErrantGTIDs(t *testing.T) { } } +// TestDetectErrantGTIDsWithWrongPrimarySource ensures that errant GTIDs are +// detected by comparing against the shard primary when a replica is pointed at +// a different source. +func TestDetectErrantGTIDsWithWrongPrimarySource(t *testing.T) { + defer func() { + db.ClearVTOrcDatabase() + }() + db.ClearVTOrcDatabase() + + keyspaceName := "ks" + shardName := "0" + + primaryUUID := "a5ce8e8a-4e56-11ef-9f7d-92339a7d9f6c" + wrongPrimaryUUID := "bb1db5f6-4e56-11ef-8bda-3ae65c7f7f5e" + replicaUUID := "cc946b58-4e56-11ef-9e6f-3e527c1a9e9d" + + primaryTablet := &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone-1", + Uid: 101, + }, + Keyspace: keyspaceName, + Shard: shardName, + Type: topodatapb.TabletType_PRIMARY, + + MysqlHostname: "primary-host", + MysqlPort: 6714, + } + + replicaTablet := &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone-1", + Uid: 100, + }, + Keyspace: keyspaceName, + Shard: shardName, + } + + err := SaveShard(topo.NewShardInfo(keyspaceName, shardName, &topodatapb.Shard{ + PrimaryAlias: primaryTablet.Alias, + }, nil)) + require.NoError(t, err) + + err = SaveTablet(primaryTablet) + require.NoError(t, err) + + // Create the real shard primary instance and give it a GTID set that does + // not include the replica UUID. This represents the authoritative primary. + primaryInstance := &Instance{ + InstanceAlias: topoproto.TabletAliasString(primaryTablet.Alias), + Hostname: "primary-host", + Port: 6714, + SourceHost: "", + ExecutedGtidSet: primaryUUID + ":1-10", + ServerUUID: primaryUUID, + } + + err = WriteInstance(primaryInstance, true, nil) + require.NoError(t, err) + + // Create a wrong primary instance that contains the replica UUID in its + // executed GTID set. This masks errant GTIDs if the replica uses it for + // comparison + wrongPrimaryInstance := &Instance{ + InstanceAlias: "zone-1-0000000102", + Hostname: "wrong-primary", + Port: 6720, + SourceHost: "", + ExecutedGtidSet: fmt.Sprintf("%s:1-10,%s:1-5", wrongPrimaryUUID, replicaUUID), + ServerUUID: wrongPrimaryUUID, + AncestryUUID: wrongPrimaryUUID, + } + + err = WriteInstance(wrongPrimaryInstance, true, nil) + require.NoError(t, err) + + // Create a replica instance that is pointed at the wrong primary. The replica + // contains errant GTIDs that should be caught. + replicaInstance := &Instance{ + InstanceAlias: topoproto.TabletAliasString(replicaTablet.Alias), + Hostname: "replica-host", + Port: 6711, + SourceHost: wrongPrimaryInstance.Hostname, + SourcePort: wrongPrimaryInstance.Port, + SourceUUID: wrongPrimaryInstance.ServerUUID, + ExecutedGtidSet: fmt.Sprintf("%s:1-10,%s:1-5", wrongPrimaryUUID, replicaUUID), + ServerUUID: replicaUUID, + } + + err = ReadInstanceClusterAttributes(replicaInstance) + require.NoError(t, err) + require.Equal(t, wrongPrimaryInstance.ExecutedGtidSet, replicaInstance.primaryExecutedGtidSet) + require.Equal(t, wrongPrimaryInstance.AncestryUUID, replicaInstance.AncestryUUID) + + // Run errant GTID detection. We should find some. + err = detectErrantGTIDs(replicaInstance, replicaTablet) + require.NoError(t, err) + + // The replica's own UUID entries should be reported as errant because the + // real shard primary does not include them. + require.Equal(t, replicaUUID+":1-5", replicaInstance.GtidErrant) +} + // TestPrimaryErrantGTIDs tests that we don't run Errant GTID detection on the primary tablet itself! func TestPrimaryErrantGTIDs(t *testing.T) { // Clear the database after the test. The easiest way to do that is to run all the initialization commands again. From c8646044994dfbc041324e7741b4fbca7ac9f252 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Wed, 28 Jan 2026 10:08:07 -0500 Subject: [PATCH 036/112] [release-22.0] Add new `force` flag to `DemotePrimary` to force a demotion even when blocked on waiting for semi-sync acks (#18714) (#19238) Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Mohamed Hamza --- go/test/endtoend/cluster/vttablet_process.go | 14 + .../reparent/emergencyreparent/ers_test.go | 129 ++ go/test/endtoend/reparent/utils/utils.go | 30 +- go/vt/mysqlctl/fakemysqldaemon.go | 5 + go/vt/mysqlctl/mysql_daemon.go | 1 + go/vt/mysqlctl/replication.go | 27 + .../tabletmanagerdata/tabletmanagerdata.pb.go | 1397 +++++++++-------- .../tabletmanagerdata_vtproto.pb.go | 34 + go/vt/vtcombo/tablet_map.go | 6 +- .../testutil/test_tmclient.go | 2 +- .../reparentutil/emergency_reparenter_test.go | 10 +- .../vtctl/reparentutil/planned_reparenter.go | 4 +- go/vt/vtctl/reparentutil/policy/durability.go | 27 + .../reparentutil/policy/durability_test.go | 7 + go/vt/vtctl/reparentutil/replication.go | 2 +- go/vt/vtctl/reparentutil/replication_test.go | 2 +- go/vt/vttablet/faketmclient/fake_client.go | 2 +- go/vt/vttablet/grpctmclient/client.go | 4 +- go/vt/vttablet/grpctmserver/server.go | 2 +- go/vt/vttablet/tabletmanager/rpc_agent.go | 2 +- .../vttablet/tabletmanager/rpc_replication.go | 68 +- .../tabletmanager/rpc_replication_test.go | 8 +- go/vt/vttablet/tabletmanager/shard_sync.go | 2 +- go/vt/vttablet/tmclient/rpc_client_api.go | 2 +- go/vt/vttablet/tmrpctest/test_tm_rpc.go | 6 +- proto/tabletmanagerdata.proto | 1 + web/vtadmin/src/proto/vtadmin.d.ts | 6 + web/vtadmin/src/proto/vtadmin.js | 34 +- 28 files changed, 1098 insertions(+), 736 deletions(-) diff --git a/go/test/endtoend/cluster/vttablet_process.go b/go/test/endtoend/cluster/vttablet_process.go index 8fbe4be54d9..73fa2b01b3f 100644 --- a/go/test/endtoend/cluster/vttablet_process.go +++ b/go/test/endtoend/cluster/vttablet_process.go @@ -410,6 +410,20 @@ func (vttablet *VttabletProcess) TearDown() error { return vttablet.TearDownWithTimeout(vttabletStateTimeout) } +func (vttablet *VttabletProcess) Stop() { + if vttablet.proc == nil || vttablet.exit == nil { + return + } + vttablet.proc.Process.Signal(syscall.SIGSTOP) +} + +func (vttablet *VttabletProcess) Resume() { + if vttablet.proc == nil || vttablet.exit == nil { + return + } + vttablet.proc.Process.Signal(syscall.SIGCONT) +} + // Kill shuts down the running vttablet service immediately. func (vttablet *VttabletProcess) Kill() error { if vttablet.proc == nil || vttablet.exit == nil { diff --git a/go/test/endtoend/reparent/emergencyreparent/ers_test.go b/go/test/endtoend/reparent/emergencyreparent/ers_test.go index f2febf9e27f..d03b47f085e 100644 --- a/go/test/endtoend/reparent/emergencyreparent/ers_test.go +++ b/go/test/endtoend/reparent/emergencyreparent/ers_test.go @@ -19,9 +19,11 @@ package emergencyreparent import ( "context" "os/exec" + "sync" "testing" "time" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "vitess.io/vitess/go/mysql" @@ -29,6 +31,8 @@ import ( "vitess.io/vitess/go/test/endtoend/reparent/utils" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) func TestTrivialERS(t *testing.T) { @@ -131,6 +135,131 @@ func TestReparentDownPrimary(t *testing.T) { utils.ResurrectTablet(ctx, t, clusterInstance, tablets[0]) } +func TestEmergencyReparentWithBlockedPrimary(t *testing.T) { + clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) + defer utils.TeardownCluster(clusterInstance) + + if clusterInstance.VtTabletMajorVersion < 24 { + t.Skip("Skipping test since `DemotePrimary` on earlier versions does not handle blocked primaries correctly") + } + + // start vtgate w/disabled buffering + clusterInstance.VtGateExtraArgs = append(clusterInstance.VtGateExtraArgs, + "--enable_buffer=false", + "--query-timeout", "3000") + err := clusterInstance.StartVtgate() + require.NoError(t, err) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + conn, err := mysql.Connect(ctx, &mysql.ConnParams{ + Host: clusterInstance.Hostname, + Port: clusterInstance.VtgateMySQLPort, + }) + require.NoError(t, err) + defer conn.Close() + + _, err = conn.ExecuteFetch("CREATE TABLE test (id INT PRIMARY KEY, msg VARCHAR(64))", 0, false) + require.NoError(t, err) + + tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets + + // Simulate no semi-sync replicas being available by disabling semi-sync on all replicas + for _, tablet := range tablets[1:] { + utils.RunSQL(ctx, t, "STOP REPLICA IO_THREAD", tablet) + + // Disable semi-sync on replicas to simulate blocking + semisyncType, err := utils.SemiSyncExtensionLoaded(context.Background(), tablet) + require.NoError(t, err) + switch semisyncType { + case mysql.SemiSyncTypeSource: + utils.RunSQL(context.Background(), t, "SET GLOBAL rpl_semi_sync_replica_enabled = false", tablet) + case mysql.SemiSyncTypeMaster: + utils.RunSQL(context.Background(), t, "SET GLOBAL rpl_semi_sync_slave_enabled = false", tablet) + } + + utils.RunSQL(context.Background(), t, "START REPLICA IO_THREAD", tablet) + } + + // Try performing a write and ensure that it blocks. + writeSQL := `insert into test(id, msg) values (1, 'test 1')` + wg := sync.WaitGroup{} + wg.Add(1) + go func() { + defer wg.Done() + + // Attempt writing via vtgate against the primary. This should block (because there's no replicas to ack the semi-sync), + // and fail on the vtgate query timeout. Async replicas will still receive this write (probably), because it is written + // to the PRIMARY binlog even when no ackers exist. This means we need to disable the vtgate buffer (above), because it + // will attempt the write on the promoted, unblocked primary - and this will hit a dupe key error. + _, err := conn.ExecuteFetch(writeSQL, 0, false) + require.ErrorContains(t, err, "context deadline exceeded (errno 1317) (sqlstate 70100) during query: "+writeSQL) + + // Verify vtgate really processed the insert in case something unrelated caused the deadline exceeded. + vtgateVars := clusterInstance.VtgateProcess.GetVars() + require.NotNil(t, vtgateVars) + require.NotNil(t, vtgateVars["QueryRoutes"]) + require.NotNil(t, vtgateVars["VtgateApiErrorCounts"]) + require.EqualValues(t, map[string]interface{}{ + "DDL.DirectDDL.PRIMARY": float64(1), + "INSERT.Passthrough.PRIMARY": float64(1), + }, vtgateVars["QueryRoutes"]) + require.EqualValues(t, map[string]interface{}{ + "Execute.ks.primary.DEADLINE_EXCEEDED": float64(1), + }, vtgateVars["VtgateApiErrorCounts"]) + }() + + wg.Add(1) + waitReplicasTimeout := time.Second * 10 + go func() { + defer wg.Done() + + // Ensure the write (other goroutine above) is blocked waiting on ACKs on the primary. + utils.WaitForQueryWithStateInProcesslist(context.Background(), t, tablets[0], writeSQL, "Waiting for semi-sync ACK from replica", time.Second*20) + + // Send SIGSTOP to primary to simulate it being unresponsive. + tablets[0].VttabletProcess.Stop() + + // Run forced reparent operation, this should now proceed unimpeded. + out, err := utils.Ers(clusterInstance, tablets[1], "15s", waitReplicasTimeout.String()) + require.NoError(t, err, out) + }() + + wg.Wait() + + // We need to wait at least 10 seconds here to ensure the wait-for-replicas-timeout has passed, + // before we resume the old primary - otherwise the old primary will receive a `SetReplicationSource` call. + time.Sleep(waitReplicasTimeout * 2) + + // Bring back the demoted primary + tablets[0].VttabletProcess.Resume() + + // Give the old primary some time to realize it's no longer the primary, + // and for a new primary to be promoted. + require.EventuallyWithT(t, func(c *assert.CollectT) { + // Ensure the old primary was demoted correctly + tabletInfo, err := clusterInstance.VtctldClientProcess.GetTablet(tablets[0].Alias) + require.NoError(c, err) + + // The old primary should have noticed there's a new primary tablet now and should + // have demoted itself to REPLICA. + require.Equal(c, topodatapb.TabletType_REPLICA, tabletInfo.GetType()) + + // The old primary should be in not serving mode because we should be unable to re-attach it + // as a replica due to the errant GTID caused by semi-sync writes that were never replicated out. + // + // Note: The writes that were not replicated were caused by the semi sync unblocker, which + // performed writes after ERS. + require.Equal(c, "NOT_SERVING", tablets[0].VttabletProcess.GetTabletStatus()) + require.Equal(c, "replica", tablets[0].VttabletProcess.GetTabletType()) + + // Check the 2nd tablet becomes PRIMARY. + require.Equal(c, "SERVING", tablets[1].VttabletProcess.GetTabletStatus()) + require.Equal(c, "primary", tablets[1].VttabletProcess.GetTabletType()) + }, 30*time.Second, time.Second, "could not validate primary was demoted") +} + func TestReparentNoChoiceDownPrimary(t *testing.T) { clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync) defer utils.TeardownCluster(clusterInstance) diff --git a/go/test/endtoend/reparent/utils/utils.go b/go/test/endtoend/reparent/utils/utils.go index 08a97a91ed7..64b67e87054 100644 --- a/go/test/endtoend/reparent/utils/utils.go +++ b/go/test/endtoend/reparent/utils/utils.go @@ -31,15 +31,14 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - querypb "vitess.io/vitess/go/vt/proto/query" - "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" - "vitess.io/vitess/go/vt/vttablet/tabletconn" - "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/vt/log" + querypb "vitess.io/vitess/go/vt/proto/query" topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" + "vitess.io/vitess/go/vt/vttablet/tabletconn" ) var ( @@ -365,7 +364,8 @@ func PrsAvoid(t *testing.T, clusterInstance *cluster.LocalProcessCluster, tab *c func PrsWithTimeout(t *testing.T, clusterInstance *cluster.LocalProcessCluster, tab *cluster.Vttablet, avoid bool, actionTimeout, waitTimeout string, extraArgs ...string) (string, error) { args := []string{ "PlannedReparentShard", - fmt.Sprintf("%s/%s", KeyspaceName, ShardName)} + fmt.Sprintf("%s/%s", KeyspaceName, ShardName), + } if actionTimeout != "" { args = append(args, "--action_timeout", actionTimeout) } @@ -839,6 +839,7 @@ func CheckReplicationStatus(ctx context.Context, t *testing.T, tablet *cluster.V } } +// WaitForTabletToBeServing waits for a tablet to reach a serving state. func WaitForTabletToBeServing(ctx context.Context, t *testing.T, clusterInstance *cluster.LocalProcessCluster, tablet *cluster.Vttablet, timeout time.Duration) { vTablet, err := clusterInstance.VtctldClientProcess.GetTablet(tablet.Alias) require.NoError(t, err) @@ -859,3 +860,22 @@ func WaitForTabletToBeServing(ctx context.Context, t *testing.T, clusterInstance t.Fatal(err.Error()) } } + +// WaitForQueryWithStateInProcesslist waits for a query to be present in the processlist with a specific state. +func WaitForQueryWithStateInProcesslist(ctx context.Context, t *testing.T, tablet *cluster.Vttablet, sql, state string, timeout time.Duration) { + require.Eventually(t, func() bool { + qr := RunSQL(ctx, t, "select Command, State, Info from information_schema.processlist", tablet) + for _, row := range qr.Rows { + if len(row) != 3 { + continue + } + if strings.EqualFold(row[0].ToString(), "Query") { + continue + } + if strings.EqualFold(row[1].ToString(), state) && strings.EqualFold(row[2].ToString(), sql) { + return true + } + } + return false + }, timeout, time.Second, "query with state not in processlist") +} diff --git a/go/vt/mysqlctl/fakemysqldaemon.go b/go/vt/mysqlctl/fakemysqldaemon.go index a2b5e66bd49..73d8a87dbf5 100644 --- a/go/vt/mysqlctl/fakemysqldaemon.go +++ b/go/vt/mysqlctl/fakemysqldaemon.go @@ -763,6 +763,11 @@ func (fmd *FakeMysqlDaemon) SemiSyncReplicationStatus(ctx context.Context) (bool return fmd.SemiSyncReplicaEnabled, nil } +// IsSemiSyncBlocked is part of the MysqlDaemon interface. +func (fmd *FakeMysqlDaemon) IsSemiSyncBlocked(ctx context.Context) (bool, error) { + return false, nil +} + // GetVersionString is part of the MysqlDaemon interface. func (fmd *FakeMysqlDaemon) GetVersionString(ctx context.Context) (string, error) { return fmd.Version, nil diff --git a/go/vt/mysqlctl/mysql_daemon.go b/go/vt/mysqlctl/mysql_daemon.go index f7a564c7bec..048f1bd89c8 100644 --- a/go/vt/mysqlctl/mysql_daemon.go +++ b/go/vt/mysqlctl/mysql_daemon.go @@ -74,6 +74,7 @@ type MysqlDaemon interface { SemiSyncClients(ctx context.Context) (count uint32) SemiSyncSettings(ctx context.Context) (timeout uint64, numReplicas uint32) SemiSyncReplicationStatus(ctx context.Context) (bool, error) + IsSemiSyncBlocked(ctx context.Context) (bool, error) ResetReplicationParameters(ctx context.Context) error GetBinlogInformation(ctx context.Context) (binlogFormat string, logEnabled bool, logReplicaUpdate bool, binlogRowImage string, err error) GetGTIDMode(ctx context.Context) (gtidMode string, err error) diff --git a/go/vt/mysqlctl/replication.go b/go/vt/mysqlctl/replication.go index bd244d4f5c7..1aabafe85f1 100644 --- a/go/vt/mysqlctl/replication.go +++ b/go/vt/mysqlctl/replication.go @@ -819,3 +819,30 @@ func (mysqld *Mysqld) SemiSyncExtensionLoaded(ctx context.Context) (mysql.SemiSy return conn.Conn.SemiSyncExtensionLoaded() } + +func (mysqld *Mysqld) IsSemiSyncBlocked(ctx context.Context) (bool, error) { + conn, err := getPoolReconnect(ctx, mysqld.dbaPool) + if err != nil { + return false, err + } + defer conn.Recycle() + + // Execute the query to check if the primary is blocked on semi-sync. + semiSyncWaitSessionsRead := "select variable_value from performance_schema.global_status where regexp_like(variable_name, 'Rpl_semi_sync_(source|master)_wait_sessions')" + res, err := conn.Conn.ExecuteFetch(semiSyncWaitSessionsRead, 1, false) + if err != nil { + return false, err + } + // If we have no rows, then the primary doesn't have semi-sync enabled. + // It then follows, that the primary isn't blocked :) + if len(res.Rows) == 0 { + return false, nil + } + + // Read the status value and check if it is non-zero. + if len(res.Rows) != 1 || len(res.Rows[0]) != 1 { + return false, fmt.Errorf("unexpected number of rows received - %v", res.Rows) + } + value, err := res.Rows[0][0].ToCastInt64() + return value != 0, err +} diff --git a/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go b/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go index 7540ee2b4e5..9e3d9f2e384 100644 --- a/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go +++ b/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go @@ -4380,6 +4380,7 @@ func (*InitReplicaResponse) Descriptor() ([]byte, []int) { type DemotePrimaryRequest struct { state protoimpl.MessageState `protogen:"open.v1"` + Force bool `protobuf:"varint,1,opt,name=force,proto3" json:"force,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -4414,6 +4415,13 @@ func (*DemotePrimaryRequest) Descriptor() ([]byte, []int) { return file_tabletmanagerdata_proto_rawDescGZIP(), []int{90} } +func (x *DemotePrimaryRequest) GetForce() bool { + if x != nil { + return x.Force + } + return false +} + type DemotePrimaryResponse struct { state protoimpl.MessageState `protogen:"open.v1"` // PrimaryStatus represents the response from calling `SHOW BINARY LOG STATUS` on a primary that has been demoted. @@ -8507,724 +8515,725 @@ var file_tabletmanagerdata_proto_rawDesc = string([]byte{ 0x0a, 0x08, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x22, 0x15, 0x0a, 0x13, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x16, 0x0a, 0x14, 0x44, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, - 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x64, 0x0a, 0x15, 0x44, 0x65, 0x6d, - 0x6f, 0x74, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0e, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x72, 0x69, - 0x6d, 0x61, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0d, 0x70, 0x72, 0x69, 0x6d, - 0x61, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, - 0x36, 0x0a, 0x18, 0x55, 0x6e, 0x64, 0x6f, 0x44, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x72, 0x69, - 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, - 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, - 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x22, 0x1b, 0x0a, 0x19, 0x55, 0x6e, 0x64, 0x6f, 0x44, - 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x0a, 0x19, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x57, - 0x61, 0x73, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x22, 0x1c, 0x0a, 0x1a, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x57, 0x61, 0x73, 0x50, - 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x23, 0x0a, 0x21, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x22, 0x24, 0x0a, 0x22, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, - 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x13, 0x0a, 0x11, 0x46, 0x75, - 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, - 0x49, 0x0a, 0x12, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x9c, 0x02, 0x0a, 0x1b, 0x53, - 0x65, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x06, 0x70, 0x61, - 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, - 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, - 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x74, 0x69, 0x6d, - 0x65, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x0d, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x4e, - 0x73, 0x12, 0x36, 0x0a, 0x17, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x15, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x77, 0x61, 0x69, - 0x74, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x77, 0x61, 0x69, 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, - 0x0a, 0x08, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x08, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x2d, 0x0a, 0x12, 0x68, 0x65, - 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, 0x11, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, - 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x22, 0x1e, 0x0a, 0x1c, 0x53, 0x65, 0x74, - 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4b, 0x0a, 0x1a, 0x52, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x57, 0x61, 0x73, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x06, - 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x22, 0x1d, 0x0a, 0x1b, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x57, 0x61, 0x73, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7e, 0x0a, 0x22, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x47, 0x65, 0x74, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x58, 0x0a, 0x15, 0x73, - 0x74, 0x6f, 0x70, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x72, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x74, 0x6f, - 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, - 0x52, 0x13, 0x73, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0x6b, 0x0a, 0x23, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x47, 0x65, 0x74, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x06, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x72, - 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, - 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4a, 0x04, 0x08, 0x01, - 0x10, 0x02, 0x22, 0x33, 0x0a, 0x15, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, - 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, - 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x22, 0x34, 0x0a, 0x16, 0x50, 0x72, 0x6f, 0x6d, 0x6f, - 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xaf, 0x02, - 0x0a, 0x0d, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, - 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, - 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x50, - 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x70, 0x6f, 0x73, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, - 0x6c, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x6f, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x70, 0x67, 0x72, - 0x61, 0x64, 0x65, 0x5f, 0x73, 0x61, 0x66, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, - 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x53, 0x61, 0x66, 0x65, 0x12, 0x28, 0x0a, 0x0d, 0x62, - 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x48, 0x00, 0x52, 0x0c, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x67, 0x69, - 0x6e, 0x65, 0x88, 0x01, 0x01, 0x12, 0x46, 0x0a, 0x16, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x5f, 0x73, - 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x14, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x53, 0x68, - 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x42, 0x10, 0x0a, - 0x0e, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x22, - 0x36, 0x0a, 0x0e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x24, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, 0x69, 0x6c, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0xfe, 0x01, 0x0a, 0x18, 0x52, 0x65, 0x73, 0x74, - 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x54, - 0x69, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x74, - 0x6f, 0x5f, 0x70, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, - 0x74, 0x6f, 0x72, 0x65, 0x54, 0x6f, 0x50, 0x6f, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, - 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, - 0x75, 0x6e, 0x12, 0x3e, 0x0a, 0x14, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, - 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x12, - 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x54, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x12, 0x34, 0x0a, 0x16, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x62, 0x61, - 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x14, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, - 0x70, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x73, 0x22, 0x41, 0x0a, 0x19, 0x52, 0x65, 0x73, 0x74, - 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, 0x69, 0x6c, 0x2e, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0xee, 0x04, 0x0a, 0x21, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x65, 0x22, 0x2c, 0x0a, 0x14, 0x44, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, + 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, + 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x22, + 0x64, 0x0a, 0x15, 0x44, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0e, 0x70, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1e, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x0d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4a, + 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x36, 0x0a, 0x18, 0x55, 0x6e, 0x64, 0x6f, 0x44, 0x65, 0x6d, + 0x6f, 0x74, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x22, 0x1b, 0x0a, + 0x19, 0x55, 0x6e, 0x64, 0x6f, 0x44, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x72, 0x69, 0x6d, 0x61, + 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x0a, 0x19, 0x52, 0x65, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x57, 0x61, 0x73, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x64, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x1c, 0x0a, 0x1a, 0x52, 0x65, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x57, 0x61, 0x73, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x0a, 0x21, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x24, 0x0a, 0x22, 0x52, 0x65, + 0x73, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x13, 0x0a, 0x11, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x49, 0x0a, 0x12, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x65, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x75, + 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x22, 0x9c, 0x02, 0x0a, 0x1b, 0x53, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x2d, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, + 0x26, 0x0a, 0x0f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, + 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x4e, 0x73, 0x12, 0x36, 0x0a, 0x17, 0x66, 0x6f, 0x72, 0x63, 0x65, + 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x23, 0x0a, 0x0d, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, 0x61, 0x69, 0x74, 0x50, 0x6f, 0x73, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, + 0x12, 0x2d, 0x0a, 0x12, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x5f, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, 0x11, 0x68, 0x65, + 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x22, + 0x1e, 0x0a, 0x1c, 0x53, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x4b, 0x0a, 0x1a, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x57, 0x61, 0x73, 0x52, 0x65, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, + 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, + 0x6c, 0x69, 0x61, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x22, 0x1d, 0x0a, 0x1b, + 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x57, 0x61, 0x73, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7e, 0x0a, 0x22, 0x53, + 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, + 0x64, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x58, 0x0a, 0x15, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x24, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x13, 0x73, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0x6b, 0x0a, 0x23, 0x53, + 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, + 0x64, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x33, 0x0a, 0x15, 0x50, 0x72, 0x6f, 0x6d, + 0x6f, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, 0x65, 0x6d, 0x69, 0x53, 0x79, 0x6e, 0x63, 0x22, 0x34, 0x0a, + 0x16, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0xaf, 0x02, 0x0a, 0x0d, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, + 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, + 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x30, 0x0a, 0x14, + 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x5f, 0x66, 0x72, 0x6f, 0x6d, + 0x5f, 0x70, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x69, 0x6e, 0x63, 0x72, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x6f, 0x73, 0x12, 0x21, + 0x0a, 0x0c, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x5f, 0x73, 0x61, 0x66, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x53, 0x61, 0x66, + 0x65, 0x12, 0x28, 0x0a, 0x0d, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x65, 0x6e, 0x67, 0x69, + 0x6e, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0c, 0x62, 0x61, 0x63, 0x6b, + 0x75, 0x70, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x88, 0x01, 0x01, 0x12, 0x46, 0x0a, 0x16, 0x6d, + 0x79, 0x73, 0x71, 0x6c, 0x5f, 0x73, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x14, 0x6d, + 0x79, 0x73, 0x71, 0x6c, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x54, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x65, + 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x22, 0x36, 0x0a, 0x0e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, 0x69, 0x6c, + 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0xfe, 0x01, + 0x0a, 0x18, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x61, 0x63, + 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x0b, 0x62, 0x61, + 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0a, 0x62, + 0x61, 0x63, 0x6b, 0x75, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x72, 0x65, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x70, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x54, 0x6f, 0x50, 0x6f, 0x73, 0x12, + 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x3e, 0x0a, 0x14, 0x72, 0x65, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x54, 0x69, 0x6d, 0x65, 0x52, 0x12, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x54, 0x6f, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x34, 0x0a, 0x16, 0x61, 0x6c, 0x6c, 0x6f, + 0x77, 0x65, 0x64, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x14, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, + 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x73, 0x22, 0x41, + 0x0a, 0x19, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x61, 0x63, + 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x05, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, + 0x75, 0x74, 0x69, 0x6c, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x22, 0xee, 0x04, 0x0a, 0x21, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x12, 0x3d, 0x0a, 0x0d, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x5f, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x62, 0x69, 0x6e, + 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x53, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x52, 0x0c, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x53, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x14, + 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, + 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, + 0x49, 0x0a, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, 0x77, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x79, 0x70, 0x65, 0x12, 0x53, 0x0a, 0x11, 0x77, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x73, 0x75, 0x62, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x75, 0x62, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0f, + 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x75, 0x62, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x30, 0x0a, 0x14, 0x64, 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, + 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x64, + 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, + 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, + 0x6f, 0x70, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x41, + 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x22, 0x50, 0x0a, 0x22, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x22, 0xda, 0x01, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x60, 0x0a, 0x0d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, + 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x53, 0x69, 0x7a, 0x65, + 0x1a, 0x3f, 0x0a, 0x11, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0x19, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3f, 0x0a, 0x21, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x3d, 0x0a, - 0x0d, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0c, - 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, - 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, - 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x49, 0x0a, 0x0d, 0x77, 0x6f, 0x72, - 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x24, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x52, - 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, - 0x6f, 0x77, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x53, 0x0a, 0x11, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x5f, 0x73, 0x75, 0x62, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x27, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x52, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x53, 0x75, 0x62, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, - 0x6f, 0x77, 0x53, 0x75, 0x62, 0x54, 0x79, 0x70, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x64, 0x65, 0x66, - 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, - 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x64, 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, - 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, - 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x09, 0x61, 0x75, 0x74, 0x6f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, - 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x0a, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x41, 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, - 0x70, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0b, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x50, 0x0a, 0x22, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xda, - 0x01, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x61, - 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x60, 0x0a, 0x0d, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x3b, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x62, - 0x61, 0x74, 0x63, 0x68, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x53, 0x69, 0x7a, 0x65, 0x1a, 0x3f, 0x0a, 0x11, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x19, 0x0a, 0x17, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3f, 0x0a, 0x21, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x22, 0x50, 0x0a, 0x22, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, - 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, - 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, - 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x21, 0x0a, 0x1f, 0x48, 0x61, 0x73, - 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x34, 0x0a, 0x20, - 0x48, 0x61, 0x73, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x10, 0x0a, 0x03, 0x68, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x68, - 0x61, 0x73, 0x22, 0xe0, 0x02, 0x0a, 0x20, 0x52, 0x65, 0x61, 0x64, 0x56, 0x52, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x63, 0x6c, 0x75, - 0x64, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x05, 0x52, 0x0a, 0x69, 0x6e, - 0x63, 0x6c, 0x75, 0x64, 0x65, 0x49, 0x64, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x69, 0x6e, 0x63, 0x6c, - 0x75, 0x64, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x10, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x57, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x12, 0x4c, 0x0a, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, - 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x25, 0x2e, - 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x52, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x77, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, - 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, - 0x12, 0x4c, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, - 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, - 0x0d, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x12, 0x25, - 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x66, 0x72, 0x6f, 0x7a, 0x65, 0x6e, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x46, - 0x72, 0x6f, 0x7a, 0x65, 0x6e, 0x22, 0x76, 0x0a, 0x21, 0x52, 0x65, 0x61, 0x64, 0x56, 0x52, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x09, 0x77, 0x6f, - 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x22, 0x3d, 0x0a, - 0x1f, 0x52, 0x65, 0x61, 0x64, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x22, 0xe7, 0x0a, 0x0a, - 0x20, 0x52, 0x65, 0x61, 0x64, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x14, 0x0a, - 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, - 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, - 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x62, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x62, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x49, 0x0a, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x22, 0x50, 0x0a, + 0x22, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, + 0x21, 0x0a, 0x1f, 0x48, 0x61, 0x73, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x22, 0x34, 0x0a, 0x20, 0x48, 0x61, 0x73, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x68, 0x61, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x03, 0x68, 0x61, 0x73, 0x22, 0xe0, 0x02, 0x0a, 0x20, 0x52, 0x65, 0x61, + 0x64, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, + 0x0b, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x05, 0x52, 0x0a, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x49, 0x64, 0x73, 0x12, 0x2b, + 0x0a, 0x11, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x69, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x12, 0x4c, 0x0a, 0x0e, 0x69, + 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0d, 0x69, 0x6e, 0x63, 0x6c, + 0x75, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x57, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x12, 0x4c, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, + 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x79, - 0x70, 0x65, 0x12, 0x53, 0x0a, 0x11, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x73, - 0x75, 0x62, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, - 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, - 0x75, 0x62, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x53, 0x75, 0x62, 0x54, 0x79, 0x70, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x64, 0x65, 0x66, 0x65, 0x72, - 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, - 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x64, 0x65, 0x66, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, - 0x6e, 0x64, 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x54, 0x0a, 0x07, 0x73, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0d, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, + 0x66, 0x72, 0x6f, 0x7a, 0x65, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x65, 0x78, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x46, 0x72, 0x6f, 0x7a, 0x65, 0x6e, 0x22, 0x76, 0x0a, 0x21, 0x52, 0x65, 0x61, 0x64, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x07, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, - 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x73, 0x0a, 0x10, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x18, 0x0d, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x48, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x51, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4f, - 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x1a, 0xc1, - 0x04, 0x0a, 0x06, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2a, 0x0a, 0x03, 0x62, 0x6c, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x52, 0x03, 0x62, 0x6c, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x70, 0x6f, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x74, 0x6f, 0x70, 0x5f, - 0x70, 0x6f, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x70, 0x50, - 0x6f, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x70, 0x73, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x06, 0x6d, 0x61, 0x78, 0x54, 0x70, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x6d, - 0x61, 0x78, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, - 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x67, 0x12, 0x2f, 0x0a, 0x0c, 0x74, - 0x69, 0x6d, 0x65, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x73, 0x22, 0x3d, 0x0a, 0x1f, 0x52, 0x65, 0x61, 0x64, 0x56, 0x52, 0x65, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x22, 0xe7, 0x0a, 0x0a, 0x20, 0x52, 0x65, 0x61, 0x64, 0x56, 0x52, 0x65, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0e, 0x32, + 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x73, 0x12, 0x6c, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x12, 0x17, 0x0a, 0x07, 0x64, 0x62, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x64, 0x62, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, + 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x49, 0x0a, + 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x79, 0x70, 0x65, 0x12, 0x53, 0x0a, 0x11, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x73, 0x75, 0x62, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x75, 0x62, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0f, 0x77, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x75, 0x62, 0x54, 0x79, 0x70, 0x65, 0x12, 0x30, 0x0a, + 0x14, 0x64, 0x65, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, + 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x64, 0x65, 0x66, + 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x12, + 0x54, 0x0a, 0x07, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x3a, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x07, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x73, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, + 0x64, 0x65, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x48, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, + 0x61, 0x64, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, + 0x69, 0x64, 0x65, 0x73, 0x1a, 0xc1, 0x04, 0x0a, 0x06, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x2a, 0x0a, 0x03, 0x62, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x62, + 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, + 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x03, 0x62, 0x6c, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x70, + 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x6f, 0x73, 0x12, 0x19, 0x0a, + 0x08, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x70, 0x6f, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x73, 0x74, 0x6f, 0x70, 0x50, 0x6f, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x5f, + 0x74, 0x70, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6d, 0x61, 0x78, 0x54, 0x70, + 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, + 0x6d, 0x61, 0x78, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, + 0x67, 0x12, 0x2f, 0x0a, 0x0c, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x64, 0x12, 0x41, 0x0a, 0x15, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, - 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x12, 0x41, 0x0a, 0x15, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x14, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, - 0x3b, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, - 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x63, - 0x6f, 0x70, 0x69, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x6f, 0x77, - 0x73, 0x43, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x12, 0x33, 0x0a, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x5f, - 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0d, 0x74, - 0x69, 0x6d, 0x65, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x12, 0x33, 0x0a, 0x0e, - 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x18, 0x0d, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x52, 0x0d, 0x74, 0x69, 0x6d, 0x65, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, - 0x64, 0x12, 0x2f, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x74, - 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, - 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, - 0x65, 0x64, 0x1a, 0x42, 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, - 0x72, 0x69, 0x64, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x28, 0x0a, 0x26, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x14, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3b, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x0a, 0x0b, + 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x0a, 0x72, 0x6f, 0x77, 0x73, 0x43, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x12, 0x33, 0x0a, + 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x52, 0x0d, 0x74, 0x69, 0x6d, 0x65, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, + 0x61, 0x74, 0x12, 0x33, 0x0a, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x74, 0x68, 0x72, 0x6f, 0x74, + 0x74, 0x6c, 0x65, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0d, 0x74, 0x69, 0x6d, 0x65, 0x54, 0x68, + 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x12, 0x2f, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x70, 0x6f, + 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x18, 0x0e, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, + 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x1a, 0x42, 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x28, 0x0a, 0x26, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4d, 0x0a, 0x27, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x22, 0x4d, 0x0a, 0x27, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, - 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, - 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x22, - 0xd7, 0x01, 0x0a, 0x0c, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, - 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x72, 0x67, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x72, 0x67, 0x12, - 0x1d, 0x0a, 0x0a, 0x76, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x76, 0x64, 0x69, 0x66, 0x66, 0x55, 0x75, 0x69, 0x64, 0x12, 0x39, - 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1f, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x6a, 0x0a, 0x0d, 0x56, 0x44, 0x69, - 0x66, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2a, 0x0a, 0x06, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, - 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x76, 0x64, 0x69, 0x66, 0x66, 0x5f, - 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x76, 0x64, 0x69, 0x66, - 0x66, 0x55, 0x75, 0x69, 0x64, 0x22, 0x79, 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x50, 0x69, - 0x63, 0x6b, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x1f, - 0x0a, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x12, - 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, - 0x22, 0xce, 0x01, 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, - 0x70, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6f, 0x6e, 0x6c, 0x79, 0x50, - 0x6b, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x64, 0x65, 0x62, 0x75, 0x67, 0x51, 0x75, - 0x65, 0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x6d, - 0x61, 0x78, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, - 0x6f, 0x77, 0x73, 0x12, 0x3c, 0x0a, 0x1b, 0x72, 0x6f, 0x77, 0x5f, 0x64, 0x69, 0x66, 0x66, 0x5f, - 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x5f, - 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x72, 0x6f, 0x77, 0x44, 0x69, 0x66, - 0x66, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x41, - 0x74, 0x22, 0x8d, 0x03, 0x0a, 0x10, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x6f, 0x72, 0x65, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x1d, - 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x52, 0x65, 0x74, 0x72, 0x79, 0x12, 0x19, 0x0a, - 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x07, 0x6d, 0x61, 0x78, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x68, 0x65, 0x63, - 0x6b, 0x73, 0x75, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x63, 0x68, 0x65, 0x63, - 0x6b, 0x73, 0x75, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x70, - 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, - 0x50, 0x63, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x73, - 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x74, 0x69, - 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x38, 0x0a, 0x19, - 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x74, - 0x6f, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x15, 0x6d, 0x61, 0x78, 0x45, 0x78, 0x74, 0x72, 0x61, 0x52, 0x6f, 0x77, 0x73, 0x54, 0x6f, 0x43, - 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x10, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x53, - 0x74, 0x61, 0x74, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x69, 0x66, 0x66, - 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, - 0x6d, 0x61, 0x78, 0x44, 0x69, 0x66, 0x66, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x22, - 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x0a, 0x20, 0x01, - 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x88, - 0x01, 0x01, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, - 0x74, 0x22, 0xf2, 0x01, 0x0a, 0x0c, 0x56, 0x44, 0x69, 0x66, 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x4c, 0x0a, 0x0e, 0x70, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x5f, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x22, 0xd7, 0x01, 0x0a, 0x0c, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x16, + 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x61, 0x72, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x41, 0x72, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x76, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x75, + 0x75, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x76, 0x64, 0x69, 0x66, 0x66, + 0x55, 0x75, 0x69, 0x64, 0x12, 0x39, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, + 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, + 0x6a, 0x0a, 0x0d, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x2a, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x1d, 0x0a, 0x0a, + 0x76, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x76, 0x64, 0x69, 0x66, 0x66, 0x55, 0x75, 0x69, 0x64, 0x22, 0x79, 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, 0x50, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x52, 0x0d, 0x70, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x46, 0x0a, 0x0c, 0x63, 0x6f, 0x72, 0x65, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, - 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, - 0x43, 0x6f, 0x72, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0b, 0x63, 0x6f, 0x72, - 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4c, 0x0a, 0x0e, 0x72, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x63, + 0x65, 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, + 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x22, 0xce, 0x01, 0x0a, 0x12, 0x56, 0x44, 0x69, 0x66, 0x66, + 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x19, 0x0a, + 0x08, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x70, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x07, 0x6f, 0x6e, 0x6c, 0x79, 0x50, 0x6b, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x62, 0x75, + 0x67, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x64, + 0x65, 0x62, 0x75, 0x67, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, + 0x72, 0x6f, 0x77, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x53, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x3c, 0x0a, 0x1b, 0x72, 0x6f, 0x77, + 0x5f, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x74, 0x72, 0x75, + 0x6e, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, + 0x72, 0x6f, 0x77, 0x44, 0x69, 0x66, 0x66, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x72, 0x75, + 0x6e, 0x63, 0x61, 0x74, 0x65, 0x41, 0x74, 0x22, 0x8d, 0x03, 0x0a, 0x10, 0x56, 0x44, 0x69, 0x66, + 0x66, 0x43, 0x6f, 0x72, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x16, 0x0a, 0x06, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x72, 0x65, 0x74, + 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x52, 0x65, + 0x74, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x1a, + 0x0a, 0x08, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x08, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x70, 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, + 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x50, 0x63, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x69, 0x6d, + 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x53, 0x65, 0x63, 0x6f, 0x6e, + 0x64, 0x73, 0x12, 0x38, 0x0a, 0x19, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, + 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x6d, 0x61, 0x78, 0x45, 0x78, 0x74, 0x72, 0x61, 0x52, + 0x6f, 0x77, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x12, 0x2c, 0x0a, 0x12, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, + 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x61, + 0x78, 0x5f, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x6d, 0x61, 0x78, 0x44, 0x69, 0x66, 0x66, 0x53, 0x65, 0x63, + 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x22, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x61, 0x75, 0x74, + 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x22, 0xf2, 0x01, 0x0a, 0x0c, 0x56, 0x44, 0x69, 0x66, + 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4c, 0x0a, 0x0e, 0x70, 0x69, 0x63, 0x6b, + 0x65, 0x72, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0d, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x7a, 0x0a, 0x10, 0x56, 0x44, 0x69, 0x66, 0x66, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x12, 0x2a, 0x0a, 0x06, 0x74, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x2f, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x48, 0x00, 0x52, 0x06, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x22, 0xaa, 0x05, 0x0a, 0x21, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, - 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, - 0x70, 0x65, 0x73, 0x12, 0x71, 0x0a, 0x1b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, - 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, - 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x19, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x88, 0x01, 0x01, 0x12, 0x33, 0x0a, 0x06, 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x4f, 0x6e, 0x44, 0x44, 0x4c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, - 0x01, 0x52, 0x05, 0x6f, 0x6e, 0x44, 0x64, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x40, 0x0a, 0x05, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x62, 0x69, 0x6e, - 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x48, 0x02, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x88, 0x01, 0x01, 0x12, 0x16, 0x0a, - 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, - 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x74, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, - 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x49, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, - 0x72, 0x69, 0x64, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x07, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x07, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x1a, 0x42, 0x0a, 0x14, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x1e, - 0x0a, 0x1c, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x09, - 0x0a, 0x07, 0x5f, 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, - 0x50, 0x0a, 0x22, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, - 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x22, 0xd6, 0x02, 0x0a, 0x22, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x5f, - 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0c, 0x61, 0x6c, 0x6c, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x12, 0x2b, 0x0a, - 0x11, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, - 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, - 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, - 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x57, 0x6f, - 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x12, 0x40, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, - 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x07, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x12, 0x28, 0x0a, 0x0d, 0x73, 0x74, 0x6f, 0x70, - 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, - 0x02, 0x52, 0x0c, 0x73, 0x74, 0x6f, 0x70, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x88, - 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x42, 0x0a, 0x0a, 0x08, - 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x73, 0x74, 0x6f, - 0x70, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x51, 0x0a, 0x23, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x2f, 0x0a, - 0x15, 0x52, 0x65, 0x73, 0x65, 0x74, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x22, 0x18, - 0x0a, 0x16, 0x52, 0x65, 0x73, 0x65, 0x74, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xc6, 0x01, 0x0a, 0x15, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x70, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, - 0x6f, 0x70, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x73, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x73, 0x6b, 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x73, 0x12, 0x27, 0x0a, 0x10, 0x6f, - 0x6b, 0x5f, 0x69, 0x66, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x6f, 0x6b, 0x49, 0x66, 0x4e, 0x6f, 0x74, 0x45, 0x78, - 0x69, 0x73, 0x74, 0x73, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x52, 0x15, 0x6d, 0x75, 0x6c, 0x74, - 0x69, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x64, 0x22, 0xf6, 0x05, 0x0a, 0x16, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, - 0x74, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, - 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x5f, 0x63, 0x68, 0x65, - 0x63, 0x6b, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x72, 0x65, 0x63, 0x65, - 0x6e, 0x74, 0x6c, 0x79, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x50, 0x0a, 0x07, 0x6d, - 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x74, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x50, 0x69, 0x63, 0x6b, 0x65, 0x72, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0d, 0x70, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x46, 0x0a, 0x0c, 0x63, 0x6f, 0x72, 0x65, 0x5f, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, 0x43, 0x6f, 0x72, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x0b, 0x63, 0x6f, 0x72, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4c, + 0x0a, 0x0e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, + 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x44, 0x69, 0x66, 0x66, + 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0d, 0x72, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x7a, 0x0a, 0x10, + 0x56, 0x44, 0x69, 0x66, 0x66, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, + 0x12, 0x2a, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x2f, 0x0a, 0x06, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x48, 0x00, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, + 0x07, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0xaa, 0x05, 0x0a, 0x21, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, + 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, + 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, + 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x71, 0x0a, 0x1b, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, + 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x19, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x88, 0x01, 0x01, 0x12, 0x33, 0x0a, 0x06, + 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x62, + 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4f, 0x6e, 0x44, 0x44, 0x4c, 0x41, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x01, 0x52, 0x05, 0x6f, 0x6e, 0x44, 0x64, 0x6c, 0x88, 0x01, + 0x01, 0x12, 0x40, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x25, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x52, + 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x48, 0x02, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x88, 0x01, 0x01, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x07, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x74, 0x0a, 0x10, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x18, + 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x49, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, + 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, + 0x73, 0x12, 0x1d, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x03, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, + 0x1a, 0x42, 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, + 0x64, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x42, 0x1e, 0x0a, 0x1c, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x42, + 0x08, 0x0a, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x50, 0x0a, 0x22, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, + 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, + 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xd6, 0x02, 0x0a, 0x22, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, + 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x61, 0x6c, 0x6c, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x77, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, + 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, + 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x65, 0x78, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x12, 0x40, 0x0a, + 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x62, + 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x88, 0x01, 0x01, 0x12, + 0x1d, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x01, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x12, 0x28, + 0x0a, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x0c, 0x73, 0x74, 0x6f, 0x70, 0x50, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x10, + 0x0a, 0x0e, 0x5f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x22, 0x51, 0x0a, 0x23, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x52, 0x65, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x22, 0x2f, 0x0a, 0x15, 0x52, 0x65, 0x73, 0x65, 0x74, 0x53, 0x65, 0x71, 0x75, + 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x22, 0x18, 0x0a, 0x16, 0x52, 0x65, 0x73, 0x65, 0x74, 0x53, 0x65, 0x71, + 0x75, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xc6, + 0x01, 0x0a, 0x15, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x70, 0x70, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x73, 0x6b, 0x69, + 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, + 0x65, 0x61, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x73, 0x6b, 0x69, 0x70, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, + 0x73, 0x12, 0x27, 0x0a, 0x10, 0x6f, 0x6b, 0x5f, 0x69, 0x66, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x65, + 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x6f, 0x6b, 0x49, + 0x66, 0x4e, 0x6f, 0x74, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, + 0x52, 0x15, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, + 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0xf6, 0x05, 0x0a, 0x16, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, + 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x74, 0x68, 0x72, + 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, + 0x6c, 0x79, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0f, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, + 0x64, 0x12, 0x50, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x07, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, + 0x74, 0x74, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x70, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, + 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x52, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x2d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, + 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x0c, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x1a, 0xf0, 0x01, 0x0a, + 0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, + 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x52, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x19, 0x0a, - 0x08, 0x61, 0x70, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x61, 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, - 0x61, 0x72, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x12, 0x52, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x63, - 0x6f, 0x64, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x68, - 0x65, 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x1a, 0xf0, 0x01, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, - 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, - 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, - 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, - 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, - 0x52, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x64, 0x65, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, - 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, - 0x6f, 0x64, 0x65, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x1a, 0x6c, 0x0a, 0x0c, 0x4d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, - 0x68, 0x65, 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x52, 0x0b, 0x73, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x22, 0x1b, 0x0a, 0x19, 0x47, 0x65, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x0c, 0x72, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x1a, + 0x6c, 0x0a, 0x0c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x46, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x30, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, + 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x4a, 0x04, 0x08, + 0x01, 0x10, 0x02, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, + 0x22, 0x1b, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x9b, 0x10, + 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, + 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, + 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x73, 0x5f, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x73, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x17, + 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x06, 0x69, 0x73, 0x4f, 0x70, 0x65, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x45, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x64, 0x6f, 0x72, + 0x6d, 0x61, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x44, 0x6f, + 0x72, 0x6d, 0x61, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x6c, 0x61, 0x67, 0x5f, 0x6d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0e, 0x6c, 0x61, 0x67, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, + 0x2e, 0x0a, 0x13, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x63, 0x75, + 0x73, 0x74, 0x6f, 0x6d, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, + 0x2b, 0x0a, 0x11, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, + 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x01, 0x52, 0x10, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x3c, 0x0a, 0x1b, + 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x64, + 0x5f, 0x61, 0x73, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x17, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x55, 0x73, 0x65, + 0x64, 0x41, 0x73, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x73, 0x0a, 0x12, 0x61, 0x67, + 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, + 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x44, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, + 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, + 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, + 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x61, 0x67, + 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, + 0x70, 0x0a, 0x11, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, + 0x6f, 0x6c, 0x64, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x43, 0x2e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, + 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x10, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, + 0x73, 0x12, 0x67, 0x0a, 0x0e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x68, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x9b, 0x10, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x54, - 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x69, - 0x73, 0x5f, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, - 0x69, 0x73, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x6f, - 0x70, 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x4f, 0x70, 0x65, - 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, - 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x64, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x74, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x44, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x74, 0x12, - 0x28, 0x0a, 0x10, 0x6c, 0x61, 0x67, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x6c, 0x61, 0x67, 0x4d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x75, 0x73, - 0x74, 0x6f, 0x6d, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x4d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x65, 0x66, - 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x0a, - 0x20, 0x01, 0x28, 0x01, 0x52, 0x10, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x54, 0x68, 0x72, - 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x3c, 0x0a, 0x1b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x61, 0x73, 0x5f, 0x64, 0x65, - 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x6d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x55, 0x73, 0x65, 0x64, 0x41, 0x73, 0x44, 0x65, 0x66, - 0x61, 0x75, 0x6c, 0x74, 0x12, 0x73, 0x0a, 0x12, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, - 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, + 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x6d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x73, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x67, 0x0a, 0x0e, 0x74, 0x68, + 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x5f, 0x61, 0x70, 0x70, 0x73, 0x18, 0x0f, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, + 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x2e, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x41, 0x70, 0x70, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x41, + 0x70, 0x70, 0x73, 0x12, 0x74, 0x0a, 0x13, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x10, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x44, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, - 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, - 0x65, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x70, 0x0a, 0x11, 0x6d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x73, 0x18, 0x0d, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x43, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, - 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, - 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, - 0x6f, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x10, 0x6d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x73, 0x12, 0x67, 0x0a, 0x0e, 0x6d, - 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x18, 0x0e, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, - 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, - 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x48, 0x65, - 0x61, 0x6c, 0x74, 0x68, 0x12, 0x67, 0x0a, 0x0e, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, - 0x64, 0x5f, 0x61, 0x70, 0x70, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x74, + 0x41, 0x70, 0x70, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x61, 0x70, 0x70, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x65, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x63, + 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x11, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0f, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x65, 0x64, 0x12, 0x5e, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x5f, 0x61, + 0x70, 0x70, 0x73, 0x18, 0x12, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, + 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x41, + 0x70, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, + 0x41, 0x70, 0x70, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x1a, 0x80, 0x01, 0x0a, 0x16, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x4d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x50, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x68, 0x72, 0x6f, - 0x74, 0x74, 0x6c, 0x65, 0x64, 0x41, 0x70, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, - 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x41, 0x70, 0x70, 0x73, 0x12, 0x74, 0x0a, - 0x13, 0x61, 0x70, 0x70, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x73, 0x18, 0x10, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x44, 0x2e, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, - 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x65, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x11, 0x61, 0x70, 0x70, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x4d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x5f, - 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x72, - 0x65, 0x63, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x5e, - 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x70, 0x70, 0x73, 0x18, 0x12, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x1a, 0x43, 0x0a, 0x15, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x68, 0x72, + 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x81, 0x01, 0x0a, 0x0c, 0x4d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x34, 0x0a, 0x0f, 0x6c, 0x61, 0x73, + 0x74, 0x5f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x5f, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x52, 0x0d, 0x6c, 0x61, 0x73, 0x74, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x41, 0x74, 0x12, + 0x3b, 0x0a, 0x1a, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x5f, 0x73, 0x69, 0x6e, 0x63, 0x65, + 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x17, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x53, 0x69, 0x6e, 0x63, + 0x65, 0x4c, 0x61, 0x73, 0x74, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x1a, 0x7c, 0x0a, 0x12, + 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x50, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x41, 0x70, 0x70, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x41, 0x70, 0x70, 0x73, 0x1a, 0x3a, - 0x0a, 0x0c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x14, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x1a, 0x80, 0x01, 0x0a, 0x16, 0x41, - 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x50, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, - 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, - 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x43, 0x0a, - 0x15, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, + 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x5c, 0x0a, 0x12, 0x54, 0x68, + 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x41, 0x70, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x68, 0x72, + 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x41, 0x70, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x44, 0x0a, 0x16, 0x41, 0x70, 0x70, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x92, + 0x01, 0x0a, 0x09, 0x52, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x41, 0x70, 0x70, 0x12, 0x2b, 0x0a, 0x0a, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x09, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x41, 0x74, 0x12, 0x52, 0x0a, 0x0d, 0x72, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x2d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, + 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x52, + 0x0c, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x4a, 0x04, 0x08, + 0x02, 0x10, 0x03, 0x1a, 0x76, 0x0a, 0x0f, 0x52, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x41, 0x70, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x1a, 0x81, 0x01, 0x0a, 0x0c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x48, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x12, 0x34, 0x0a, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x68, 0x65, 0x61, 0x6c, - 0x74, 0x68, 0x79, 0x5f, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, - 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0d, 0x6c, 0x61, 0x73, 0x74, - 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x41, 0x74, 0x12, 0x3b, 0x0a, 0x1a, 0x73, 0x65, 0x63, - 0x6f, 0x6e, 0x64, 0x73, 0x5f, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, - 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x73, - 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x53, 0x69, 0x6e, 0x63, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x48, - 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x1a, 0x7c, 0x0a, 0x12, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, - 0x73, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x50, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x5c, 0x0a, 0x12, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, - 0x64, 0x41, 0x70, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x6f, - 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x64, - 0x41, 0x70, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x1a, 0x44, 0x0a, 0x16, 0x41, 0x70, 0x70, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, - 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x4d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, + 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x41, 0x70, 0x70, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xaa, 0x01, 0x0a, 0x11, + 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x42, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x2e, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x1a, + 0x37, 0x0a, 0x09, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x92, 0x01, 0x0a, 0x09, 0x52, 0x65, 0x63, - 0x65, 0x6e, 0x74, 0x41, 0x70, 0x70, 0x12, 0x2b, 0x0a, 0x0a, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, - 0x64, 0x5f, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x09, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, - 0x64, 0x41, 0x74, 0x12, 0x52, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, - 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, - 0x68, 0x65, 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x1a, 0x76, 0x0a, - 0x0f, 0x52, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x41, 0x70, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x12, 0x4d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x37, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, - 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2e, 0x52, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x41, 0x70, 0x70, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xaa, 0x01, 0x0a, 0x11, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, - 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x04, 0x74, - 0x61, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, - 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, - 0x18, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x1a, 0x37, 0x0a, 0x09, 0x54, 0x61, 0x67, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x22, 0x92, 0x01, 0x0a, 0x12, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x61, 0x67, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x04, 0x74, 0x61, 0x67, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, - 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x1a, 0x37, - 0x0a, 0x09, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x2a, 0x3e, 0x0a, 0x19, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4e, 0x59, 0x10, 0x00, 0x12, 0x0b, 0x0a, - 0x07, 0x49, 0x4e, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, - 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x03, 0x2a, 0x83, 0x01, 0x0a, 0x1a, 0x43, 0x68, 0x65, 0x63, - 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x49, - 0x4e, 0x45, 0x44, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0x01, 0x12, 0x16, 0x0a, - 0x12, 0x54, 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, 0x5f, 0x45, 0x58, 0x43, 0x45, 0x45, - 0x44, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x41, 0x50, 0x50, 0x5f, 0x44, 0x45, 0x4e, - 0x49, 0x45, 0x44, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, - 0x5f, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x49, 0x4e, 0x54, - 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x05, 0x42, 0x30, 0x5a, - 0x2e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, - 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x92, 0x01, 0x0a, 0x12, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x43, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, + 0x74, 0x61, 0x67, 0x73, 0x1a, 0x37, 0x0a, 0x09, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x2a, 0x3e, 0x0a, + 0x19, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4e, + 0x59, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x10, 0x01, + 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x03, 0x2a, 0x83, 0x01, + 0x0a, 0x1a, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x72, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x0d, 0x0a, 0x09, + 0x55, 0x4e, 0x44, 0x45, 0x46, 0x49, 0x4e, 0x45, 0x44, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x4f, + 0x4b, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x48, 0x52, 0x45, 0x53, 0x48, 0x4f, 0x4c, 0x44, + 0x5f, 0x45, 0x58, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x41, + 0x50, 0x50, 0x5f, 0x44, 0x45, 0x4e, 0x49, 0x45, 0x44, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x55, + 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x52, 0x49, 0x43, 0x10, 0x04, 0x12, + 0x12, 0x0a, 0x0e, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x10, 0x05, 0x42, 0x30, 0x5a, 0x2e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, + 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, + 0x72, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, }) var ( diff --git a/go/vt/proto/tabletmanagerdata/tabletmanagerdata_vtproto.pb.go b/go/vt/proto/tabletmanagerdata/tabletmanagerdata_vtproto.pb.go index 74e3cab9f1e..e6fe78e093d 100644 --- a/go/vt/proto/tabletmanagerdata/tabletmanagerdata_vtproto.pb.go +++ b/go/vt/proto/tabletmanagerdata/tabletmanagerdata_vtproto.pb.go @@ -1715,6 +1715,7 @@ func (m *DemotePrimaryRequest) CloneVT() *DemotePrimaryRequest { return (*DemotePrimaryRequest)(nil) } r := new(DemotePrimaryRequest) + r.Force = m.Force if len(m.unknownFields) > 0 { r.unknownFields = make([]byte, len(m.unknownFields)) copy(r.unknownFields, m.unknownFields) @@ -7029,6 +7030,16 @@ func (m *DemotePrimaryRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if m.Force { + i-- + if m.Force { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } return len(dAtA) - i, nil } @@ -11997,6 +12008,9 @@ func (m *DemotePrimaryRequest) SizeVT() (n int) { } var l int _ = l + if m.Force { + n += 2 + } n += len(m.unknownFields) return n } @@ -21793,6 +21807,26 @@ func (m *DemotePrimaryRequest) UnmarshalVT(dAtA []byte) error { return fmt.Errorf("proto: DemotePrimaryRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Force", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Force = bool(v != 0) default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) diff --git a/go/vt/vtcombo/tablet_map.go b/go/vt/vtcombo/tablet_map.go index e8c8935f989..8d04a2e559e 100644 --- a/go/vt/vtcombo/tablet_map.go +++ b/go/vt/vtcombo/tablet_map.go @@ -18,6 +18,7 @@ package vtcombo import ( "context" + "errors" "fmt" "os" "path" @@ -1009,8 +1010,8 @@ func (itmc *internalTabletManagerClient) ReadReparentJournalInfo(ctx context.Con return 0, fmt.Errorf("not implemented in vtcombo") } -func (itmc *internalTabletManagerClient) DemotePrimary(context.Context, *topodatapb.Tablet) (*replicationdatapb.PrimaryStatus, error) { - return nil, fmt.Errorf("not implemented in vtcombo") +func (itmc *internalTabletManagerClient) DemotePrimary(context.Context, *topodatapb.Tablet, bool) (*replicationdatapb.PrimaryStatus, error) { + return nil, errors.New("not implemented in vtcombo") } func (itmc *internalTabletManagerClient) UndoDemotePrimary(context.Context, *topodatapb.Tablet, bool) error { @@ -1091,6 +1092,7 @@ func (itmc *internalTabletManagerClient) ResetReplicationParameters(context.Cont func (itmc *internalTabletManagerClient) ReplicaWasRestarted(context.Context, *topodatapb.Tablet, *topodatapb.TabletAlias) error { return fmt.Errorf("not implemented in vtcombo") } + func (itmc *internalTabletManagerClient) ResetSequences(ctx context.Context, tablet *topodatapb.Tablet, tables []string) error { return fmt.Errorf("not implemented in vtcombo") } diff --git a/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go b/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go index 3b6af754d4e..e548d08cad5 100644 --- a/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go +++ b/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go @@ -549,7 +549,7 @@ func (fake *TabletManagerClient) ChangeType(ctx context.Context, tablet *topodat } // DemotePrimary is part of the tmclient.TabletManagerClient interface. -func (fake *TabletManagerClient) DemotePrimary(ctx context.Context, tablet *topodatapb.Tablet) (*replicationdatapb.PrimaryStatus, error) { +func (fake *TabletManagerClient) DemotePrimary(ctx context.Context, tablet *topodatapb.Tablet, force bool) (*replicationdatapb.PrimaryStatus, error) { if fake.DemotePrimaryResults == nil { return nil, assert.AnError } diff --git a/go/vt/vtctl/reparentutil/emergency_reparenter_test.go b/go/vt/vtctl/reparentutil/emergency_reparenter_test.go index 529c2a8f366..888e6c77130 100644 --- a/go/vt/vtctl/reparentutil/emergency_reparenter_test.go +++ b/go/vt/vtctl/reparentutil/emergency_reparenter_test.go @@ -18,7 +18,7 @@ package reparentutil import ( "context" - "fmt" + "errors" "slices" "testing" "time" @@ -2017,7 +2017,7 @@ func TestEmergencyReparenter_promotionOfNewPrimary(t *testing.T) { Error error }{ "zone1-0000000100": { - Error: fmt.Errorf("primary position error"), + Error: errors.New("primary position error"), }, }, }, @@ -3143,7 +3143,7 @@ func TestEmergencyReparenter_reparentReplicas(t *testing.T) { Error error }{ "zone1-0000000100": { - Error: fmt.Errorf("primary position error"), + Error: errors.New("primary position error"), }, }, }, @@ -3799,7 +3799,7 @@ func TestEmergencyReparenter_promoteIntermediateSource(t *testing.T) { "zone1-0000000100": nil, }, SetReplicationSourceResults: map[string]error{ - "zone1-0000000101": fmt.Errorf("An error"), + "zone1-0000000101": errors.New("An error"), }, }, newSourceTabletAlias: "zone1-0000000100", @@ -4615,7 +4615,7 @@ func getRelayLogPosition(gtidSets ...string) string { res += "," } first = false - res += fmt.Sprintf("%s:%s", uuids[idx], set) + res += uuids[idx] + ":" + set } return res } diff --git a/go/vt/vtctl/reparentutil/planned_reparenter.go b/go/vt/vtctl/reparentutil/planned_reparenter.go index dcd6dc7c590..52b51b52b8f 100644 --- a/go/vt/vtctl/reparentutil/planned_reparenter.go +++ b/go/vt/vtctl/reparentutil/planned_reparenter.go @@ -275,7 +275,7 @@ func (pr *PlannedReparenter) performGracefulPromotion( demoteCtx, demoteCancel := context.WithTimeout(ctx, topo.RemoteOperationTimeout) defer demoteCancel() - primaryStatus, err := pr.tmc.DemotePrimary(demoteCtx, currentPrimary.Tablet) + primaryStatus, err := pr.tmc.DemotePrimary(demoteCtx, currentPrimary.Tablet, false) if err != nil { return vterrors.Wrapf(err, "failed to DemotePrimary on current primary %v: %v", currentPrimary.AliasString(), err) } @@ -426,7 +426,7 @@ func (pr *PlannedReparenter) performPotentialPromotion( // tablet type), that's already in read-only. pr.logger.Infof("demoting tablet %v", alias) - primaryStatus, err := pr.tmc.DemotePrimary(stopAllCtx, tablet) + primaryStatus, err := pr.tmc.DemotePrimary(stopAllCtx, tablet, false) if err != nil { rec.RecordError(vterrors.Wrapf(err, "DemotePrimary(%v) failed on contested primary", alias)) diff --git a/go/vt/vtctl/reparentutil/policy/durability.go b/go/vt/vtctl/reparentutil/policy/durability.go index bad6846ef29..1ff88267fbf 100644 --- a/go/vt/vtctl/reparentutil/policy/durability.go +++ b/go/vt/vtctl/reparentutil/policy/durability.go @@ -91,6 +91,8 @@ type Durabler interface { SemiSyncAckers(*topodatapb.Tablet) int // IsReplicaSemiSync returns whether the "replica" should send semi-sync acks if "primary" were to become the PRIMARY instance IsReplicaSemiSync(primary, replica *topodatapb.Tablet) bool + // HasSemiSync returns whether the durability policy uses semi-sync. + HasSemiSync() bool } func RegisterDurability(name string, newDurablerFunc NewDurabler) { @@ -142,6 +144,11 @@ func IsReplicaSemiSync(durability Durabler, primary, replica *topodatapb.Tablet) return durability.IsReplicaSemiSync(primary, replica) } +// HasSemiSync returns true if the durability policy uses semi-sync. +func HasSemiSync(durability Durabler) bool { + return durability.HasSemiSync() +} + //======================================================================= // durabilityNone has no semi-sync and returns NeutralPromoteRule for Primary and Replica tablet types, MustNotPromoteRule for everything else @@ -166,6 +173,11 @@ func (d *durabilityNone) IsReplicaSemiSync(primary, replica *topodatapb.Tablet) return false } +// HasSemiSync implements the Durabler interface +func (d *durabilityNone) HasSemiSync() bool { + return false +} + //======================================================================= // durabilitySemiSync has 1 semi-sync setup. It only allows Primary and Replica type servers to acknowledge semi sync @@ -199,6 +211,11 @@ func (d *durabilitySemiSync) IsReplicaSemiSync(primary, replica *topodatapb.Tabl return false } +// HasSemiSync implements the Durabler interface +func (d *durabilitySemiSync) HasSemiSync() bool { + return true +} + //======================================================================= // durabilityCrossCell has 1 semi-sync setup. It only allows Primary and Replica type servers from a different cell to acknowledge semi sync. @@ -233,6 +250,11 @@ func (d *durabilityCrossCell) IsReplicaSemiSync(primary, replica *topodatapb.Tab return false } +// HasSemiSync implements the Durabler interface +func (d *durabilityCrossCell) HasSemiSync() bool { + return true +} + //======================================================================= // durabilityTest is like durabilityNone. It overrides the type for a specific tablet to prefer. It is only meant to be used for testing purposes! @@ -260,3 +282,8 @@ func (d *durabilityTest) SemiSyncAckers(tablet *topodatapb.Tablet) int { func (d *durabilityTest) IsReplicaSemiSync(primary, replica *topodatapb.Tablet) bool { return false } + +// HasSemiSync implements the Durabler interface +func (d *durabilityTest) HasSemiSync() bool { + return false +} diff --git a/go/vt/vtctl/reparentutil/policy/durability_test.go b/go/vt/vtctl/reparentutil/policy/durability_test.go index 441275f29bf..e3a4710b2d1 100644 --- a/go/vt/vtctl/reparentutil/policy/durability_test.go +++ b/go/vt/vtctl/reparentutil/policy/durability_test.go @@ -331,3 +331,10 @@ func TestDurabilityTest(t *testing.T) { }) } } + +func TestHasSemiSync(t *testing.T) { + require.False(t, HasSemiSync(&durabilityNone{})) + require.False(t, HasSemiSync(&durabilityTest{})) + require.True(t, HasSemiSync(&durabilitySemiSync{})) + require.True(t, HasSemiSync(&durabilityCrossCell{})) +} diff --git a/go/vt/vtctl/reparentutil/replication.go b/go/vt/vtctl/reparentutil/replication.go index 81211fac4cd..46568a5164f 100644 --- a/go/vt/vtctl/reparentutil/replication.go +++ b/go/vt/vtctl/reparentutil/replication.go @@ -210,7 +210,7 @@ func stopReplicationAndBuildStatusMaps( if isSQLErr && sqlErr != nil && sqlErr.Number() == sqlerror.ERNotReplica { var primaryStatus *replicationdatapb.PrimaryStatus - primaryStatus, err = tmc.DemotePrimary(groupCtx, tabletInfo.Tablet) + primaryStatus, err = tmc.DemotePrimary(groupCtx, tabletInfo.Tablet, true /* force */) if err != nil { msg := "replica %v thinks it's primary but we failed to demote it: %v" err = vterrors.Wrapf(err, msg, alias, err) diff --git a/go/vt/vtctl/reparentutil/replication_test.go b/go/vt/vtctl/reparentutil/replication_test.go index 3d124b7495b..af909d602ed 100644 --- a/go/vt/vtctl/reparentutil/replication_test.go +++ b/go/vt/vtctl/reparentutil/replication_test.go @@ -225,7 +225,7 @@ type stopReplicationAndBuildStatusMapsTestTMClient struct { stopReplicationAndGetStatusDelays map[string]time.Duration } -func (fake *stopReplicationAndBuildStatusMapsTestTMClient) DemotePrimary(ctx context.Context, tablet *topodatapb.Tablet) (*replicationdatapb.PrimaryStatus, error) { +func (fake *stopReplicationAndBuildStatusMapsTestTMClient) DemotePrimary(ctx context.Context, tablet *topodatapb.Tablet, force bool) (*replicationdatapb.PrimaryStatus, error) { if tablet.Alias == nil { return nil, assert.AnError } diff --git a/go/vt/vttablet/faketmclient/fake_client.go b/go/vt/vttablet/faketmclient/fake_client.go index 5a5cd33535f..6ee84bb5926 100644 --- a/go/vt/vttablet/faketmclient/fake_client.go +++ b/go/vt/vttablet/faketmclient/fake_client.go @@ -363,7 +363,7 @@ func (client *FakeTabletManagerClient) ReadReparentJournalInfo(ctx context.Conte } // DemotePrimary is part of the tmclient.TabletManagerClient interface. -func (client *FakeTabletManagerClient) DemotePrimary(ctx context.Context, tablet *topodatapb.Tablet) (*replicationdatapb.PrimaryStatus, error) { +func (client *FakeTabletManagerClient) DemotePrimary(ctx context.Context, tablet *topodatapb.Tablet, force bool) (*replicationdatapb.PrimaryStatus, error) { return nil, nil } diff --git a/go/vt/vttablet/grpctmclient/client.go b/go/vt/vttablet/grpctmclient/client.go index f531d88ed15..b9bb6bdf101 100644 --- a/go/vt/vttablet/grpctmclient/client.go +++ b/go/vt/vttablet/grpctmclient/client.go @@ -1154,13 +1154,13 @@ func (client *Client) InitReplica(ctx context.Context, tablet *topodatapb.Tablet } // DemotePrimary is part of the tmclient.TabletManagerClient interface. -func (client *Client) DemotePrimary(ctx context.Context, tablet *topodatapb.Tablet) (*replicationdatapb.PrimaryStatus, error) { +func (client *Client) DemotePrimary(ctx context.Context, tablet *topodatapb.Tablet, force bool) (*replicationdatapb.PrimaryStatus, error) { c, closer, err := client.dialer.dial(ctx, tablet) if err != nil { return nil, err } defer closer.Close() - response, err := c.DemotePrimary(ctx, &tabletmanagerdatapb.DemotePrimaryRequest{}) + response, err := c.DemotePrimary(ctx, &tabletmanagerdatapb.DemotePrimaryRequest{Force: force}) if err != nil { return nil, err } diff --git a/go/vt/vttablet/grpctmserver/server.go b/go/vt/vttablet/grpctmserver/server.go index be1b8ae9372..24bba022692 100644 --- a/go/vt/vttablet/grpctmserver/server.go +++ b/go/vt/vttablet/grpctmserver/server.go @@ -586,7 +586,7 @@ func (s *server) DemotePrimary(ctx context.Context, request *tabletmanagerdatapb defer s.tm.HandleRPCPanic(ctx, "DemotePrimary", request, response, true /*verbose*/, &err) ctx = callinfo.GRPCCallInfo(ctx) response = &tabletmanagerdatapb.DemotePrimaryResponse{} - status, err := s.tm.DemotePrimary(ctx) + status, err := s.tm.DemotePrimary(ctx, request.Force) if err == nil { response.PrimaryStatus = status } diff --git a/go/vt/vttablet/tabletmanager/rpc_agent.go b/go/vt/vttablet/tabletmanager/rpc_agent.go index e779cfa8ff5..e055043ef4f 100644 --- a/go/vt/vttablet/tabletmanager/rpc_agent.go +++ b/go/vt/vttablet/tabletmanager/rpc_agent.go @@ -144,7 +144,7 @@ type RPCTM interface { InitReplica(ctx context.Context, parent *topodatapb.TabletAlias, replicationPosition string, timeCreatedNS int64, semiSync bool) error - DemotePrimary(ctx context.Context) (*replicationdatapb.PrimaryStatus, error) + DemotePrimary(ctx context.Context, force bool) (*replicationdatapb.PrimaryStatus, error) UndoDemotePrimary(ctx context.Context, semiSync bool) error diff --git a/go/vt/vttablet/tabletmanager/rpc_replication.go b/go/vt/vttablet/tabletmanager/rpc_replication.go index 67a252c3290..0dbd785aa1a 100644 --- a/go/vt/vttablet/tabletmanager/rpc_replication.go +++ b/go/vt/vttablet/tabletmanager/rpc_replication.go @@ -519,20 +519,20 @@ func (tm *TabletManager) InitReplica(ctx context.Context, parent *topodatapb.Tab // or on a tablet that already transitioned to REPLICA. // // If a step fails in the middle, it will try to undo any changes it made. -func (tm *TabletManager) DemotePrimary(ctx context.Context) (*replicationdatapb.PrimaryStatus, error) { +func (tm *TabletManager) DemotePrimary(ctx context.Context, force bool) (*replicationdatapb.PrimaryStatus, error) { log.Infof("DemotePrimary") if err := tm.waitForGrantsToHaveApplied(ctx); err != nil { return nil, err } // The public version always reverts on partial failure. - return tm.demotePrimary(ctx, true /* revertPartialFailure */) + return tm.demotePrimary(ctx, true /* revertPartialFailure */, force) } // demotePrimary implements DemotePrimary with an additional, private option. // // If revertPartialFailure is true, and a step fails in the middle, it will try // to undo any changes it made. -func (tm *TabletManager) demotePrimary(ctx context.Context, revertPartialFailure bool) (primaryStatus *replicationdatapb.PrimaryStatus, finalErr error) { +func (tm *TabletManager) demotePrimary(ctx context.Context, revertPartialFailure bool, force bool) (primaryStatus *replicationdatapb.PrimaryStatus, finalErr error) { if err := tm.lock(ctx); err != nil { return nil, err } @@ -594,13 +594,66 @@ func (tm *TabletManager) demotePrimary(ctx context.Context, revertPartialFailure }() } - // Now we know no writes are in-flight and no new writes can occur. - // We just need to wait for no write being blocked on semi-sync ACKs. - err = tm.SemiSyncMonitor.WaitUntilSemiSyncUnblocked(ctx) + isSemiSyncBlocked, err := tm.MysqlDaemon.IsSemiSyncBlocked(ctx) if err != nil { return nil, err } + // `force` is true when `DemotePrimary` is called for `EmergencyReparentShard` or when a primary notices + // that a different tablet has been promoted to primary and demotes itself. + // + // In both cases, the reason for semi sync being blocked is very likely that there's no replica + // connected that can send semi-sync ACKs, so we need to disable semi-sync to enable read-only mode. + // And in either of these cases, it's almost guaranteed that no semi-sync enabled replica will connect + // to this tablet again. + // + // The only way for us to finish the demotion in this scenario is to disable semi-sync - otherwise + // enabling ``super_read_only` will end up waiting indefinitely for in-flight transactions + // to complete, which won't happen as they are waiting for semi-sync ACKs. + // + // By disabling semi-sync, we allow the blocking in-flight transactions to complete. Note that at this point, + // the query service is already disabled, so the original sessions that issued those writes + // will never have seen their transactions commit - they will already have received an error. + // + // The demoted primary will end up with errant GTIDs, but that's unavoidable in this scenario. + if force && isSemiSyncBlocked { + if tm.isPrimarySideSemiSyncEnabled(ctx) { + // Disable the primary side semi-sync to unblock the writes. + if err := tm.fixSemiSync(ctx, topodatapb.TabletType_REPLICA, SemiSyncActionSet); err != nil { + return nil, err + } + defer func() { + if finalErr != nil && revertPartialFailure && wasPrimary { + // enable primary-side semi-sync again + if err := tm.fixSemiSync(ctx, topodatapb.TabletType_PRIMARY, SemiSyncActionSet); err != nil { + log.Warningf("fixSemiSync(PRIMARY) failed during revert: %v", err) + } + } + }() + } + } else { + // If `force` is false, we're demoting this primary as part of a `PlannedReparentShard` operation, + // but we might be blocked on semi-sync ACKs. + // + // If there's any in-flight transactions waiting for semi-sync ACKs, + // we won't be able to change the MySQL `super_read_only` because turning on + // read only mode requires all in-flight transactions to complete. + // + // So we're doing a last-ditch effort here trying to wait for in-flight transactions to complete. + // This will only be successful if at least one semi-sync enabled replica connects back to this primary + // and a new transaction commit unblocks the semi-sync wait. + // + // The scenario where this could happen is some sort of network hiccup during a + // `PlannedReparentShard` call, where the primary temporarily loses connectivity to + // all semi-sync enabled replicas. + // + // If we can't unblock within the context timeout, the `PlannedReparentShard` operation will fail. + err = tm.SemiSyncMonitor.WaitUntilSemiSyncUnblocked(ctx) + if err != nil { + return nil, err + } + } + // We can now set MySQL to super_read_only mode. If we are already super_read_only because of a // previous demotion, or because we are not primary anyway, this should be // idempotent. @@ -622,8 +675,7 @@ func (tm *TabletManager) demotePrimary(ctx context.Context, revertPartialFailure } }() - // Here, we check if the primary side semi sync is enabled or not. If it isn't enabled then we do not need to take any action. - // If it is enabled then we should turn it off and revert in case of failure. + // If we haven't disabled the primary side semi-sync so far, do it now. if tm.isPrimarySideSemiSyncEnabled(ctx) { // If using semi-sync, we need to disable primary-side. if err := tm.fixSemiSync(ctx, topodatapb.TabletType_REPLICA, SemiSyncActionSet); err != nil { diff --git a/go/vt/vttablet/tabletmanager/rpc_replication_test.go b/go/vt/vttablet/tabletmanager/rpc_replication_test.go index 7ba8fc6729c..31da3abb732 100644 --- a/go/vt/vttablet/tabletmanager/rpc_replication_test.go +++ b/go/vt/vttablet/tabletmanager/rpc_replication_test.go @@ -98,7 +98,7 @@ func TestDemotePrimaryStalled(t *testing.T) { } go func() { - tm.demotePrimary(context.Background(), false) + tm.demotePrimary(context.Background(), false /* revertPartialFailure */, false /* force */) }() // We make IsServing stall by making it wait on a channel. // This should cause the demote primary operation to be stalled. @@ -149,7 +149,7 @@ func TestDemotePrimaryWaitingForSemiSyncUnblock(t *testing.T) { // Start the demote primary operation in a go routine. var demotePrimaryFinished atomic.Bool go func() { - _, err := tm.demotePrimary(ctx, false) + _, err := tm.demotePrimary(ctx, false /* revertPartialFailure */, false /* force */) require.NoError(t, err) demotePrimaryFinished.Store(true) }() @@ -220,7 +220,7 @@ func TestDemotePrimaryWithSemiSyncProgressDetection(t *testing.T) { // Start the demote primary operation in a go routine. var demotePrimaryFinished atomic.Bool go func() { - _, err := tm.demotePrimary(ctx, false) + _, err := tm.demotePrimary(ctx, false /* revertPartialFailure */, false /* force */) require.NoError(t, err) demotePrimaryFinished.Store(true) }() @@ -278,7 +278,7 @@ func TestDemotePrimaryWhenSemiSyncBecomesUnblockedBetweenChecks(t *testing.T) { // Start the demote primary operation in a go routine. var demotePrimaryFinished atomic.Bool go func() { - _, err := tm.demotePrimary(ctx, false) + _, err := tm.demotePrimary(ctx, false /* revertPartialFailure */, false /* force */) require.NoError(t, err) demotePrimaryFinished.Store(true) }() diff --git a/go/vt/vttablet/tabletmanager/shard_sync.go b/go/vt/vttablet/tabletmanager/shard_sync.go index 4afbaa1a639..dcb9245b06a 100644 --- a/go/vt/vttablet/tabletmanager/shard_sync.go +++ b/go/vt/vttablet/tabletmanager/shard_sync.go @@ -241,7 +241,7 @@ func (tm *TabletManager) endPrimaryTerm(ctx context.Context, primaryAlias *topod log.Infof("Active reparents are enabled; converting MySQL to replica.") demotePrimaryCtx, cancelDemotePrimary := context.WithTimeout(ctx, topo.RemoteOperationTimeout) defer cancelDemotePrimary() - if _, err := tm.demotePrimary(demotePrimaryCtx, false /* revertPartialFailure */); err != nil { + if _, err := tm.demotePrimary(demotePrimaryCtx, false /* revertPartialFailure */, true /* force */); err != nil { return vterrors.Wrap(err, "failed to demote primary") } setPrimaryCtx, cancelSetPrimary := context.WithTimeout(ctx, topo.RemoteOperationTimeout) diff --git a/go/vt/vttablet/tmclient/rpc_client_api.go b/go/vt/vttablet/tmclient/rpc_client_api.go index 7ce4c7f0bf4..32f788bea1a 100644 --- a/go/vt/vttablet/tmclient/rpc_client_api.go +++ b/go/vt/vttablet/tmclient/rpc_client_api.go @@ -248,7 +248,7 @@ type TabletManagerClient interface { // DemotePrimary tells the soon-to-be-former primary it's going to change, // and it should go read-only and return its current position. - DemotePrimary(ctx context.Context, tablet *topodatapb.Tablet) (*replicationdatapb.PrimaryStatus, error) + DemotePrimary(ctx context.Context, tablet *topodatapb.Tablet, force bool) (*replicationdatapb.PrimaryStatus, error) // UndoDemotePrimary reverts all changes made by DemotePrimary // To be used if we are unable to promote the chosen new primary diff --git a/go/vt/vttablet/tmrpctest/test_tm_rpc.go b/go/vt/vttablet/tmrpctest/test_tm_rpc.go index 0ec380882cc..45f7786debd 100644 --- a/go/vt/vttablet/tmrpctest/test_tm_rpc.go +++ b/go/vt/vttablet/tmrpctest/test_tm_rpc.go @@ -1236,7 +1236,7 @@ func tmRPCTestInitReplicaPanic(ctx context.Context, t *testing.T, client tmclien expectHandleRPCPanic(t, "InitReplica", true /*verbose*/, err) } -func (fra *fakeRPCTM) DemotePrimary(ctx context.Context) (*replicationdatapb.PrimaryStatus, error) { +func (fra *fakeRPCTM) DemotePrimary(ctx context.Context, force bool) (*replicationdatapb.PrimaryStatus, error) { if fra.panics { panic(fmt.Errorf("test-triggered panic")) } @@ -1244,12 +1244,12 @@ func (fra *fakeRPCTM) DemotePrimary(ctx context.Context) (*replicationdatapb.Pri } func tmRPCTestDemotePrimary(ctx context.Context, t *testing.T, client tmclient.TabletManagerClient, tablet *topodatapb.Tablet) { - PrimaryStatus, err := client.DemotePrimary(ctx, tablet) + PrimaryStatus, err := client.DemotePrimary(ctx, tablet, false) compareError(t, "DemotePrimary", err, PrimaryStatus.Position, testPrimaryStatus.Position) } func tmRPCTestDemotePrimaryPanic(ctx context.Context, t *testing.T, client tmclient.TabletManagerClient, tablet *topodatapb.Tablet) { - _, err := client.DemotePrimary(ctx, tablet) + _, err := client.DemotePrimary(ctx, tablet, false) expectHandleRPCPanic(t, "DemotePrimary", true /*verbose*/, err) } diff --git a/proto/tabletmanagerdata.proto b/proto/tabletmanagerdata.proto index 9b300a2a939..0fe8649bb71 100644 --- a/proto/tabletmanagerdata.proto +++ b/proto/tabletmanagerdata.proto @@ -478,6 +478,7 @@ message InitReplicaResponse { } message DemotePrimaryRequest { + bool force = 1; } message DemotePrimaryResponse { diff --git a/web/vtadmin/src/proto/vtadmin.d.ts b/web/vtadmin/src/proto/vtadmin.d.ts index 49da5095c26..9428c5d46eb 100644 --- a/web/vtadmin/src/proto/vtadmin.d.ts +++ b/web/vtadmin/src/proto/vtadmin.d.ts @@ -29791,6 +29791,9 @@ export namespace tabletmanagerdata { /** Properties of a DemotePrimaryRequest. */ interface IDemotePrimaryRequest { + + /** DemotePrimaryRequest force */ + force?: (boolean|null); } /** Represents a DemotePrimaryRequest. */ @@ -29802,6 +29805,9 @@ export namespace tabletmanagerdata { */ constructor(properties?: tabletmanagerdata.IDemotePrimaryRequest); + /** DemotePrimaryRequest force. */ + public force: boolean; + /** * Creates a new DemotePrimaryRequest instance using the specified properties. * @param [properties] Properties to set diff --git a/web/vtadmin/src/proto/vtadmin.js b/web/vtadmin/src/proto/vtadmin.js index 1c6897eb2f5..3f3ea08ba34 100644 --- a/web/vtadmin/src/proto/vtadmin.js +++ b/web/vtadmin/src/proto/vtadmin.js @@ -68087,6 +68087,7 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { * Properties of a DemotePrimaryRequest. * @memberof tabletmanagerdata * @interface IDemotePrimaryRequest + * @property {boolean|null} [force] DemotePrimaryRequest force */ /** @@ -68104,6 +68105,14 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { this[keys[i]] = properties[keys[i]]; } + /** + * DemotePrimaryRequest force. + * @member {boolean} force + * @memberof tabletmanagerdata.DemotePrimaryRequest + * @instance + */ + DemotePrimaryRequest.prototype.force = false; + /** * Creates a new DemotePrimaryRequest instance using the specified properties. * @function create @@ -68128,6 +68137,8 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { DemotePrimaryRequest.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); + if (message.force != null && Object.hasOwnProperty.call(message, "force")) + writer.uint32(/* id 1, wireType 0 =*/8).bool(message.force); return writer; }; @@ -68162,6 +68173,10 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { while (reader.pos < end) { let tag = reader.uint32(); switch (tag >>> 3) { + case 1: { + message.force = reader.bool(); + break; + } default: reader.skipType(tag & 7); break; @@ -68197,6 +68212,9 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { DemotePrimaryRequest.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; + if (message.force != null && message.hasOwnProperty("force")) + if (typeof message.force !== "boolean") + return "force: boolean expected"; return null; }; @@ -68211,7 +68229,10 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { DemotePrimaryRequest.fromObject = function fromObject(object) { if (object instanceof $root.tabletmanagerdata.DemotePrimaryRequest) return object; - return new $root.tabletmanagerdata.DemotePrimaryRequest(); + let message = new $root.tabletmanagerdata.DemotePrimaryRequest(); + if (object.force != null) + message.force = Boolean(object.force); + return message; }; /** @@ -68223,8 +68244,15 @@ export const tabletmanagerdata = $root.tabletmanagerdata = (() => { * @param {$protobuf.IConversionOptions} [options] Conversion options * @returns {Object.} Plain object */ - DemotePrimaryRequest.toObject = function toObject() { - return {}; + DemotePrimaryRequest.toObject = function toObject(message, options) { + if (!options) + options = {}; + let object = {}; + if (options.defaults) + object.force = false; + if (message.force != null && message.hasOwnProperty("force")) + object.force = message.force; + return object; }; /** From bea1835825378d0628c2188ec9224442f7109bed Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Wed, 28 Jan 2026 13:29:58 -0500 Subject: [PATCH 037/112] [release-22.0] vtorc: add `StaleTopoPrimary` analysis and recovery (#19173) (#19236) Co-authored-by: Mohamed Hamza --- go/test/endtoend/vtorc/general/vtorc_test.go | 71 ++++++ go/vt/external/golib/sqlutils/sqlutils.go | 5 + go/vt/vtorc/inst/analysis.go | 22 +- go/vt/vtorc/inst/analysis_dao.go | 21 +- go/vt/vtorc/inst/analysis_dao_test.go | 217 +++++++++++++++---- go/vt/vtorc/logic/topology_recovery.go | 77 +++++++ go/vt/vtorc/test/recovery_analysis.go | 8 +- 7 files changed, 368 insertions(+), 53 deletions(-) diff --git a/go/test/endtoend/vtorc/general/vtorc_test.go b/go/test/endtoend/vtorc/general/vtorc_test.go index 4e6cf8abf16..b713a65dba2 100644 --- a/go/test/endtoend/vtorc/general/vtorc_test.go +++ b/go/test/endtoend/vtorc/general/vtorc_test.go @@ -31,6 +31,7 @@ import ( "vitess.io/vitess/go/test/endtoend/vtorc/utils" "vitess.io/vitess/go/vt/log" topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/vt/vtorc/inst" "vitess.io/vitess/go/vt/vtorc/logic" ) @@ -401,6 +402,76 @@ func TestRepairAfterTER(t *testing.T) { utils.CheckReplication(t, clusterInfo, newPrimary, []*cluster.Vttablet{curPrimary}, 15*time.Second) } +// TestStalePrimary tests that an old primary that remains writable and of tablet type PRIMARY in the topo +// is properly demoted to a read-only replica by VTOrc. +func TestStalePrimary(t *testing.T) { + ctx := t.Context() + + defer utils.PrintVTOrcLogsOnFailure(t, clusterInfo.ClusterInstance) + utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 4, 0, []string{"--topo-information-refresh-duration", "1s"}, cluster.VTOrcConfiguration{ + PreventCrossCellFailover: true, + }, 1, policy.DurabilitySemiSync) + keyspace := &clusterInfo.ClusterInstance.Keyspaces[0] + shard0 := &keyspace.Shards[0] + + curPrimary := utils.ShardPrimaryTablet(t, clusterInfo, keyspace, shard0) + assert.NotNil(t, curPrimary, "should have elected a primary") + utils.CheckPrimaryTablet(t, clusterInfo, curPrimary, true) + + var badPrimary, healthyReplica *cluster.Vttablet + for _, tablet := range shard0.Vttablets { + if tablet.Alias == curPrimary.Alias { + continue + } + + if badPrimary == nil { + badPrimary = tablet + continue + } + + healthyReplica = tablet + } + + utils.CheckReplication(t, clusterInfo, curPrimary, []*cluster.Vttablet{badPrimary, healthyReplica}, 15*time.Second) + + curPrimaryTopo, err := clusterInfo.Ts.GetTablet(ctx, curPrimary.GetAlias()) + require.NoError(t, err, "expected to read current primary topo record") + + curPrimaryTermStart := protoutil.TimeFromProto(curPrimaryTopo.PrimaryTermStartTime) + require.False(t, curPrimaryTermStart.IsZero(), "expected current primary term start time to be set") + + err = utils.RunSQLs(t, []string{"SET GLOBAL read_only = OFF"}, badPrimary, "") + require.NoError(t, err) + require.True(t, utils.WaitForReadOnlyValue(t, badPrimary, 0)) + + // We set the tablet's type in the topology to PRIMARY. This mimics the situation where during a demotion + // in a hypothetical ERS, the old primary starts running as a replica, but fails before updating the topology + // accordingly. + _, err = clusterInfo.Ts.UpdateTabletFields(ctx, badPrimary.GetAlias(), func(tablet *topodatapb.Tablet) error { + tablet.Type = topodatapb.TabletType_PRIMARY + tablet.PrimaryTermStartTime = protoutil.TimeToProto(curPrimaryTermStart.Add(-1 * time.Minute)) + return nil + }) + require.NoError(t, err) + + // Expect VTOrc to demote the stale primary to a read-only replica. + require.Eventuallyf(t, func() bool { + topoTablet, topoErr := clusterInfo.Ts.GetTablet(ctx, badPrimary.GetAlias()) + if topoErr != nil { + t.Logf("stale primary probe: topo error=%v", topoErr) + return false + } + + readOnly, readErr := badPrimary.VttabletProcess.GetDBVar("read_only", "") + if readErr != nil { + t.Logf("stale primary probe: alias=%s topo=%v read_only error=%v", badPrimary.Alias, topoTablet.Type, readErr) + return false + } + + return topoTablet.Type == topodatapb.TabletType_REPLICA && readOnly == "ON" + }, 30*time.Second, time.Second, "expected demotion to REPLICA with read_only=ON") +} + // TestSemiSync tests that semi-sync is setup correctly by vtorc if it is incorrectly set func TestSemiSync(t *testing.T) { // stop any vtorc instance running due to a previous test. diff --git a/go/vt/external/golib/sqlutils/sqlutils.go b/go/vt/external/golib/sqlutils/sqlutils.go index 38b0b0c9e62..8c686f29737 100644 --- a/go/vt/external/golib/sqlutils/sqlutils.go +++ b/go/vt/external/golib/sqlutils/sqlutils.go @@ -135,6 +135,11 @@ func (rm *RowMap) GetTime(key string) time.Time { if t, err := time.Parse(DateTimeFormat, rm.GetString(key)); err == nil { return t } + + if t, err := time.Parse(time.RFC3339Nano, rm.GetString(key)); err == nil { + return t + } + return time.Time{} } diff --git a/go/vt/vtorc/inst/analysis.go b/go/vt/vtorc/inst/analysis.go index f6948ad89f4..b8eeb3a3c9f 100644 --- a/go/vt/vtorc/inst/analysis.go +++ b/go/vt/vtorc/inst/analysis.go @@ -59,6 +59,10 @@ const ( PrimarySemiSyncBlocked AnalysisCode = "PrimarySemiSyncBlocked" ErrantGTIDDetected AnalysisCode = "ErrantGTIDDetected" PrimaryDiskStalled AnalysisCode = "PrimaryDiskStalled" + + // StaleTopoPrimary describes when a tablet still has the type PRIMARY in the topology when a newer primary + // has been elected. VTOrc should demote this primary to a replica. + StaleTopoPrimary AnalysisCode = "StaleTopoPrimary" ) type StructureAnalysisCode string @@ -88,12 +92,18 @@ type ReplicationAnalysisHints struct { type ReplicationAnalysis struct { AnalyzedInstanceAlias string AnalyzedInstancePrimaryAlias string - TabletType topodatapb.TabletType - CurrentTabletType topodatapb.TabletType - PrimaryTimeStamp time.Time - ClusterDetails ClusterInfo - AnalyzedKeyspace string - AnalyzedShard string + + // TabletType is the tablet's type as seen in the topology. + TabletType topodatapb.TabletType + + // CurrentTabletType is the type this tablet is currently running as. + CurrentTabletType topodatapb.TabletType + + PrimaryTimeStamp time.Time + ClusterDetails ClusterInfo + AnalyzedKeyspace string + AnalyzedShard string + // ShardPrimaryTermTimestamp is the primary term start time stored in the shard record. ShardPrimaryTermTimestamp string AnalyzedInstanceBinlogCoordinates BinlogCoordinates diff --git a/go/vt/vtorc/inst/analysis_dao.go b/go/vt/vtorc/inst/analysis_dao.go index 0e480f74ee8..6479923dda3 100644 --- a/go/vt/vtorc/inst/analysis_dao.go +++ b/go/vt/vtorc/inst/analysis_dao.go @@ -54,7 +54,12 @@ type clusterAnalysis struct { hasClusterwideAction bool totalTablets int primaryAlias string - durability policy.Durabler + + // primaryTimestamp is the most recent primary term start time observed for the shard. + primaryTimestamp time.Time + + // durability is the shard's current durability policy. + durability policy.Durabler } // GetReplicationAnalysis will check for replication problems (dead primary; unreachable primary; etc) @@ -379,6 +384,7 @@ func GetReplicationAnalysis(keyspace string, shard string, hints *ReplicationAna if a.TabletType == topodatapb.TabletType_PRIMARY { a.IsClusterPrimary = true clusters[keyspaceShard].primaryAlias = a.AnalyzedInstanceAlias + clusters[keyspaceShard].primaryTimestamp = a.PrimaryTimeStamp } durabilityPolicy := m.GetString("durability_policy") if durabilityPolicy == "" { @@ -458,6 +464,9 @@ func GetReplicationAnalysis(keyspace string, shard string, hints *ReplicationAna } else if topo.IsReplicaType(a.TabletType) && a.ErrantGTID != "" { a.Analysis = ErrantGTIDDetected a.Description = "Tablet has errant GTIDs" + } else if isStaleTopoPrimary(a, ca) { + a.Analysis = StaleTopoPrimary + a.Description = "Primary tablet is stale, older than current primary" } else if topo.IsReplicaType(a.TabletType) && ca.primaryAlias == "" && a.ShardPrimaryTermTimestamp == "" { // ClusterHasNoPrimary should only be detected when the shard record doesn't have any primary term start time specified either. a.Analysis = ClusterHasNoPrimary @@ -603,6 +612,16 @@ func GetReplicationAnalysis(keyspace string, shard string, hints *ReplicationAna return result, err } +// isStaleTopoPrimary returns true when a tablet has type PRIMARY in the topology and has an older primary term +// start time than the shard's current primary. +func isStaleTopoPrimary(tablet *ReplicationAnalysis, cluster *clusterAnalysis) bool { + if tablet.TabletType != topodatapb.TabletType_PRIMARY { + return false + } + + return tablet.PrimaryTimeStamp.Before(cluster.primaryTimestamp) +} + // postProcessAnalyses is used to update different analyses based on the information gleaned from looking at all the analyses together instead of individual data. func postProcessAnalyses(result []*ReplicationAnalysis, clusters map[string]*clusterAnalysis) []*ReplicationAnalysis { for { diff --git a/go/vt/vtorc/inst/analysis_dao_test.go b/go/vt/vtorc/inst/analysis_dao_test.go index b24e15107d4..ddf2e9bc0af 100644 --- a/go/vt/vtorc/inst/analysis_dao_test.go +++ b/go/vt/vtorc/inst/analysis_dao_test.go @@ -30,22 +30,20 @@ import ( "vitess.io/vitess/go/vt/vtorc/test" ) -var ( - // The initialSQL is a set of insert commands copied from a dump of an actual running VTOrc instances. The relevant insert commands are here. - // This is a dump taken from a test running 4 tablets, zone1-101 is the primary, zone1-100 is a replica, zone1-112 is a rdonly and zone2-200 is a cross-cell replica. - initialSQL = []string{ - `INSERT INTO database_instance VALUES('zone1-0000000112','localhost',6747,3,'2022-12-28 07:26:04','2022-12-28 07:26:04',213696377,'8.0.31','ROW',1,1,'vt-0000000112-bin.000001',15963,'localhost',6714,8,4.0,1,1,'vt-0000000101-bin.000001',15583,'vt-0000000101-bin.000001',15583,0,0,1,'','',1,'vt-0000000112-relay-bin.000002',15815,1,0,'zone1','',0,0,0,1,'729a4cc4-8680-11ed-a104-47706090afbd:1-54','729a5138-8680-11ed-9240-92a06c3be3c2','2022-12-28 07:26:04','',1,0,0,'Homebrew','8.0','FULL',10816929,0,0,'ON',1,'729a4cc4-8680-11ed-a104-47706090afbd','','729a4cc4-8680-11ed-a104-47706090afbd,729a5138-8680-11ed-9240-92a06c3be3c2',1,1,'',1000000000000000000,1,0,0,0,false,false);`, - `INSERT INTO database_instance VALUES('zone1-0000000100','localhost',6711,2,'2022-12-28 07:26:04','2022-12-28 07:26:04',1094500338,'8.0.31','ROW',1,1,'vt-0000000100-bin.000001',15963,'localhost',6714,8,4.0,1,1,'vt-0000000101-bin.000001',15583,'vt-0000000101-bin.000001',15583,0,0,1,'','',1,'vt-0000000100-relay-bin.000002',15815,1,0,'zone1','',0,0,0,1,'729a4cc4-8680-11ed-a104-47706090afbd:1-54','729a5138-8680-11ed-acf8-d6b0ef9f4eaa','2022-12-28 07:26:04','',1,0,0,'Homebrew','8.0','FULL',10103920,0,1,'ON',1,'729a4cc4-8680-11ed-a104-47706090afbd','','729a4cc4-8680-11ed-a104-47706090afbd,729a5138-8680-11ed-acf8-d6b0ef9f4eaa',1,1,'',1000000000000000000,1,0,1,0,false,false);`, - `INSERT INTO database_instance VALUES('zone1-0000000101','localhost',6714,1,'2022-12-28 07:26:04','2022-12-28 07:26:04',390954723,'8.0.31','ROW',1,1,'vt-0000000101-bin.000001',15583,'',0,0,0,0,0,'',0,'',0,NULL,NULL,0,'','',0,'',0,0,0,'zone1','',0,0,0,1,'729a4cc4-8680-11ed-a104-47706090afbd:1-54','729a4cc4-8680-11ed-a104-47706090afbd','2022-12-28 07:26:04','',0,0,0,'Homebrew','8.0','FULL',11366095,1,1,'ON',1,'','','729a4cc4-8680-11ed-a104-47706090afbd',-1,-1,'',1000000000000000000,1,1,0,2,false,false);`, - `INSERT INTO database_instance VALUES('zone2-0000000200','localhost',6756,2,'2022-12-28 07:26:05','2022-12-28 07:26:05',444286571,'8.0.31','ROW',1,1,'vt-0000000200-bin.000001',15963,'localhost',6714,8,4.0,1,1,'vt-0000000101-bin.000001',15583,'vt-0000000101-bin.000001',15583,0,0,1,'','',1,'vt-0000000200-relay-bin.000002',15815,1,0,'zone2','',0,0,0,1,'729a4cc4-8680-11ed-a104-47706090afbd:1-54','729a497c-8680-11ed-8ad4-3f51d747db75','2022-12-28 07:26:05','',1,0,0,'Homebrew','8.0','FULL',10443112,0,1,'ON',1,'729a4cc4-8680-11ed-a104-47706090afbd','','729a4cc4-8680-11ed-a104-47706090afbd,729a497c-8680-11ed-8ad4-3f51d747db75',1,1,'',1000000000000000000,1,0,1,0,false,false);`, - `INSERT INTO vitess_tablet VALUES('zone1-0000000100','localhost',6711,'ks','0','zone1',2,'0001-01-01 00:00:00+00:00',X'616c6961733a7b63656c6c3a227a6f6e653122207569643a3130307d20686f73746e616d653a226c6f63616c686f73742220706f72745f6d61703a7b6b65793a2267727063222076616c75653a363731307d20706f72745f6d61703a7b6b65793a227674222076616c75653a363730397d206b657973706163653a226b73222073686172643a22302220747970653a5245504c494341206d7973716c5f686f73746e616d653a226c6f63616c686f737422206d7973716c5f706f72743a363731312064625f7365727665725f76657273696f6e3a22382e302e3331222064656661756c745f636f6e6e5f636f6c6c6174696f6e3a3435');`, - `INSERT INTO vitess_tablet VALUES('zone1-0000000101','localhost',6714,'ks','0','zone1',1,'2022-12-28 07:23:25.129898+00:00',X'616c6961733a7b63656c6c3a227a6f6e653122207569643a3130317d20686f73746e616d653a226c6f63616c686f73742220706f72745f6d61703a7b6b65793a2267727063222076616c75653a363731337d20706f72745f6d61703a7b6b65793a227674222076616c75653a363731327d206b657973706163653a226b73222073686172643a22302220747970653a5052494d415259206d7973716c5f686f73746e616d653a226c6f63616c686f737422206d7973716c5f706f72743a36373134207072696d6172795f7465726d5f73746172745f74696d653a7b7365636f6e64733a31363732323132323035206e616e6f7365636f6e64733a3132393839383030307d2064625f7365727665725f76657273696f6e3a22382e302e3331222064656661756c745f636f6e6e5f636f6c6c6174696f6e3a3435');`, - `INSERT INTO vitess_tablet VALUES('zone1-0000000112','localhost',6747,'ks','0','zone1',3,'0001-01-01 00:00:00+00:00',X'616c6961733a7b63656c6c3a227a6f6e653122207569643a3131327d20686f73746e616d653a226c6f63616c686f73742220706f72745f6d61703a7b6b65793a2267727063222076616c75653a363734367d20706f72745f6d61703a7b6b65793a227674222076616c75653a363734357d206b657973706163653a226b73222073686172643a22302220747970653a52444f4e4c59206d7973716c5f686f73746e616d653a226c6f63616c686f737422206d7973716c5f706f72743a363734372064625f7365727665725f76657273696f6e3a22382e302e3331222064656661756c745f636f6e6e5f636f6c6c6174696f6e3a3435');`, - `INSERT INTO vitess_tablet VALUES('zone2-0000000200','localhost',6756,'ks','0','zone2',2,'0001-01-01 00:00:00+00:00',X'616c6961733a7b63656c6c3a227a6f6e653222207569643a3230307d20686f73746e616d653a226c6f63616c686f73742220706f72745f6d61703a7b6b65793a2267727063222076616c75653a363735357d20706f72745f6d61703a7b6b65793a227674222076616c75653a363735347d206b657973706163653a226b73222073686172643a22302220747970653a5245504c494341206d7973716c5f686f73746e616d653a226c6f63616c686f737422206d7973716c5f706f72743a363735362064625f7365727665725f76657273696f6e3a22382e302e3331222064656661756c745f636f6e6e5f636f6c6c6174696f6e3a3435');`, - `INSERT INTO vitess_shard VALUES('ks','0','zone1-0000000101','2022-12-28 07:23:25.129898+00:00');`, - `INSERT INTO vitess_keyspace VALUES('ks',0,'semi_sync');`, - } -) +// The initialSQL is a set of insert commands copied from a dump of an actual running VTOrc instances. The relevant insert commands are here. +// This is a dump taken from a test running 4 tablets, zone1-101 is the primary, zone1-100 is a replica, zone1-112 is a rdonly and zone2-200 is a cross-cell replica. +var initialSQL = []string{ + `INSERT INTO database_instance VALUES('zone1-0000000112','localhost',6747,3,'2022-12-28 07:26:04','2022-12-28 07:26:04',213696377,'8.0.31','ROW',1,1,'vt-0000000112-bin.000001',15963,'localhost',6714,8,4.0,1,1,'vt-0000000101-bin.000001',15583,'vt-0000000101-bin.000001',15583,0,0,1,'','',1,'vt-0000000112-relay-bin.000002',15815,1,0,'zone1','',0,0,0,1,'729a4cc4-8680-11ed-a104-47706090afbd:1-54','729a5138-8680-11ed-9240-92a06c3be3c2','2022-12-28 07:26:04','',1,0,0,'Homebrew','8.0','FULL',10816929,0,0,'ON',1,'729a4cc4-8680-11ed-a104-47706090afbd','','729a4cc4-8680-11ed-a104-47706090afbd,729a5138-8680-11ed-9240-92a06c3be3c2',1,1,'',1000000000000000000,1,0,0,0,false,false);`, + `INSERT INTO database_instance VALUES('zone1-0000000100','localhost',6711,2,'2022-12-28 07:26:04','2022-12-28 07:26:04',1094500338,'8.0.31','ROW',1,1,'vt-0000000100-bin.000001',15963,'localhost',6714,8,4.0,1,1,'vt-0000000101-bin.000001',15583,'vt-0000000101-bin.000001',15583,0,0,1,'','',1,'vt-0000000100-relay-bin.000002',15815,1,0,'zone1','',0,0,0,1,'729a4cc4-8680-11ed-a104-47706090afbd:1-54','729a5138-8680-11ed-acf8-d6b0ef9f4eaa','2022-12-28 07:26:04','',1,0,0,'Homebrew','8.0','FULL',10103920,0,1,'ON',1,'729a4cc4-8680-11ed-a104-47706090afbd','','729a4cc4-8680-11ed-a104-47706090afbd,729a5138-8680-11ed-acf8-d6b0ef9f4eaa',1,1,'',1000000000000000000,1,0,1,0,false,false);`, + `INSERT INTO database_instance VALUES('zone1-0000000101','localhost',6714,1,'2022-12-28 07:26:04','2022-12-28 07:26:04',390954723,'8.0.31','ROW',1,1,'vt-0000000101-bin.000001',15583,'',0,0,0,0,0,'',0,'',0,NULL,NULL,0,'','',0,'',0,0,0,'zone1','',0,0,0,1,'729a4cc4-8680-11ed-a104-47706090afbd:1-54','729a4cc4-8680-11ed-a104-47706090afbd','2022-12-28 07:26:04','',0,0,0,'Homebrew','8.0','FULL',11366095,1,1,'ON',1,'','','729a4cc4-8680-11ed-a104-47706090afbd',-1,-1,'',1000000000000000000,1,1,0,2,false,false);`, + `INSERT INTO database_instance VALUES('zone2-0000000200','localhost',6756,2,'2022-12-28 07:26:05','2022-12-28 07:26:05',444286571,'8.0.31','ROW',1,1,'vt-0000000200-bin.000001',15963,'localhost',6714,8,4.0,1,1,'vt-0000000101-bin.000001',15583,'vt-0000000101-bin.000001',15583,0,0,1,'','',1,'vt-0000000200-relay-bin.000002',15815,1,0,'zone2','',0,0,0,1,'729a4cc4-8680-11ed-a104-47706090afbd:1-54','729a497c-8680-11ed-8ad4-3f51d747db75','2022-12-28 07:26:05','',1,0,0,'Homebrew','8.0','FULL',10443112,0,1,'ON',1,'729a4cc4-8680-11ed-a104-47706090afbd','','729a4cc4-8680-11ed-a104-47706090afbd,729a497c-8680-11ed-8ad4-3f51d747db75',1,1,'',1000000000000000000,1,0,1,0,false,false);`, + `INSERT INTO vitess_tablet VALUES('zone1-0000000100','localhost',6711,'ks','0','zone1',2,'0001-01-01 00:00:00+00:00',X'616c6961733a7b63656c6c3a227a6f6e653122207569643a3130307d20686f73746e616d653a226c6f63616c686f73742220706f72745f6d61703a7b6b65793a2267727063222076616c75653a363731307d20706f72745f6d61703a7b6b65793a227674222076616c75653a363730397d206b657973706163653a226b73222073686172643a22302220747970653a5245504c494341206d7973716c5f686f73746e616d653a226c6f63616c686f737422206d7973716c5f706f72743a363731312064625f7365727665725f76657273696f6e3a22382e302e3331222064656661756c745f636f6e6e5f636f6c6c6174696f6e3a3435');`, + `INSERT INTO vitess_tablet VALUES('zone1-0000000101','localhost',6714,'ks','0','zone1',1,'2022-12-28 07:23:25.129898+00:00',X'616c6961733a7b63656c6c3a227a6f6e653122207569643a3130317d20686f73746e616d653a226c6f63616c686f73742220706f72745f6d61703a7b6b65793a2267727063222076616c75653a363731337d20706f72745f6d61703a7b6b65793a227674222076616c75653a363731327d206b657973706163653a226b73222073686172643a22302220747970653a5052494d415259206d7973716c5f686f73746e616d653a226c6f63616c686f737422206d7973716c5f706f72743a36373134207072696d6172795f7465726d5f73746172745f74696d653a7b7365636f6e64733a31363732323132323035206e616e6f7365636f6e64733a3132393839383030307d2064625f7365727665725f76657273696f6e3a22382e302e3331222064656661756c745f636f6e6e5f636f6c6c6174696f6e3a3435');`, + `INSERT INTO vitess_tablet VALUES('zone1-0000000112','localhost',6747,'ks','0','zone1',3,'0001-01-01 00:00:00+00:00',X'616c6961733a7b63656c6c3a227a6f6e653122207569643a3131327d20686f73746e616d653a226c6f63616c686f73742220706f72745f6d61703a7b6b65793a2267727063222076616c75653a363734367d20706f72745f6d61703a7b6b65793a227674222076616c75653a363734357d206b657973706163653a226b73222073686172643a22302220747970653a52444f4e4c59206d7973716c5f686f73746e616d653a226c6f63616c686f737422206d7973716c5f706f72743a363734372064625f7365727665725f76657273696f6e3a22382e302e3331222064656661756c745f636f6e6e5f636f6c6c6174696f6e3a3435');`, + `INSERT INTO vitess_tablet VALUES('zone2-0000000200','localhost',6756,'ks','0','zone2',2,'0001-01-01 00:00:00+00:00',X'616c6961733a7b63656c6c3a227a6f6e653222207569643a3230307d20686f73746e616d653a226c6f63616c686f73742220706f72745f6d61703a7b6b65793a2267727063222076616c75653a363735357d20706f72745f6d61703a7b6b65793a227674222076616c75653a363735347d206b657973706163653a226b73222073686172643a22302220747970653a5245504c494341206d7973716c5f686f73746e616d653a226c6f63616c686f737422206d7973716c5f706f72743a363735362064625f7365727665725f76657273696f6e3a22382e302e3331222064656661756c745f636f6e6e5f636f6c6c6174696f6e3a3435');`, + `INSERT INTO vitess_shard VALUES('ks','0','zone1-0000000101','2022-12-28 07:23:25.129898+00:00');`, + `INSERT INTO vitess_keyspace VALUES('ks',0,'semi_sync');`, +} // TestGetReplicationAnalysisDecision tests the code of GetReplicationAnalysis decision-making. It doesn't check the SQL query // run by it. It only checks the analysis part after the rows have been read. This tests fakes the db and explicitly returns the @@ -77,7 +75,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: ClusterHasNoPrimary, - }, { + }, + { name: "PrimaryTabletDeleted", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -96,7 +95,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: PrimaryTabletDeleted, - }, { + }, + { name: "StalledDiskPrimary", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -120,7 +120,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: PrimaryDiskStalled, - }, { + }, + { name: "PrimarySemiSyncBlocked", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -149,7 +150,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: PrimarySemiSyncBlocked, - }, { + }, + { name: "LockedSemiSync", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -178,7 +180,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: LockedSemiSyncPrimaryHypothesis, - }, { + }, + { name: "DeadPrimary", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -201,7 +204,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: DeadPrimary, - }, { + }, + { name: "DeadPrimaryWithoutReplicas", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -222,7 +226,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: DeadPrimaryWithoutReplicas, - }, { + }, + { name: "DeadPrimaryAndReplicas", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -243,7 +248,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: DeadPrimaryAndReplicas, - }, { + }, + { name: "DeadPrimaryAndSomeReplicas", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -266,7 +272,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: DeadPrimaryAndSomeReplicas, - }, { + }, + { name: "PrimaryHasPrimary", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -288,7 +295,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: PrimaryHasPrimary, - }, { + }, + { name: "PrimaryIsReadOnly", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -311,7 +319,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: PrimaryIsReadOnly, - }, { + }, + { name: "PrimaryCurrentTypeMismatch", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -333,7 +342,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: PrimaryCurrentTypeMismatch, - }, { + }, + { name: "Unknown tablet type shouldn't run the mismatch recovery analysis", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -358,7 +368,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: NoProblem, - }, { + }, + { name: "PrimarySemiSyncMustNotBeSet", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -381,7 +392,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: PrimarySemiSyncMustNotBeSet, - }, { + }, + { name: "PrimarySemiSyncMustBeSet", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -404,7 +416,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: PrimarySemiSyncMustBeSet, - }, { + }, + { name: "NotConnectedToPrimary", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -442,7 +455,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: NotConnectedToPrimary, - }, { + }, + { name: "ReplicaIsWritable", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -483,7 +497,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: ReplicaIsWritable, - }, { + }, + { name: "ConnectedToWrongPrimary", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -524,7 +539,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: ConnectedToWrongPrimary, - }, { + }, + { name: "ReplicationStopped", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -566,7 +582,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: ReplicationStopped, - }, { + }, + { name: "No recoveries on drained tablets", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -608,7 +625,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: NoProblem, - }, { + }, + { name: "ReplicaMisconfigured", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -695,7 +713,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: ReplicaSemiSyncMustBeSet, - }, { + }, + { name: "ReplicaSemiSyncMustNotBeSet", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -737,7 +756,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: ReplicaSemiSyncMustNotBeSet, - }, { + }, + { name: "SnapshotKeyspace", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -757,7 +777,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: NoProblem, - }, { + }, + { name: "EmptyDurabilityPolicy", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -775,7 +796,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: NoProblem, - }, { + }, + { // If the database_instance table for a tablet is empty (discovery of MySQL information hasn't happened yet or failed) // then we shouldn't run a failure fix on it until the discovery succeeds name: "Empty database_instance table", @@ -815,7 +837,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: InvalidReplica, - }, { + }, + { name: "DeadPrimary when VTOrc is starting up", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -857,7 +880,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: DeadPrimary, - }, { + }, + { name: "Invalid Primary", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -875,7 +899,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: InvalidPrimary, - }, { + }, + { name: "ErrantGTID", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -917,7 +942,8 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { keyspaceWanted: "ks", shardWanted: "0", codeWanted: ErrantGTIDDetected, - }, { + }, + { name: "ErrantGTID on a non-replica", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ @@ -993,6 +1019,106 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { } } +// TestStalePrimary tests that an old primary that remains writable and is of tablet type PRIMARY +// in the topo is demoted to a read-only replica by VTOrc. +func TestStalePrimary(t *testing.T) { + oldDB := db.Db + defer func() { + db.Db = oldDB + }() + + currentPrimaryTimestamp := time.Now().UTC().Truncate(time.Microsecond) + stalePrimaryTimestamp := currentPrimaryTimestamp.Add(-1 * time.Minute) + shardPrimaryTermTimestamp := currentPrimaryTimestamp.Format(sqlutils.DateTimeFormat) + + // We set up a real primary and replica, and then a stale primary running as REPLICA but with + // tablet type PRIMARY in the topology. + info := []*test.InfoForRecoveryAnalysis{ + { + TabletInfo: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Hostname: "localhost", + Keyspace: "ks", + Shard: "0", + Type: topodatapb.TabletType_PRIMARY, + MysqlHostname: "localhost", + MysqlPort: 6708, + }, + DurabilityPolicy: policy.DurabilitySemiSync, + LastCheckValid: 1, + CountReplicas: 1, + CountValidReplicas: 1, + CountValidReplicatingReplicas: 1, + IsPrimary: 1, + SemiSyncPrimaryEnabled: 1, + SemiSyncPrimaryStatus: 1, + SemiSyncPrimaryWaitForReplicaCount: 1, + SemiSyncPrimaryClients: 1, + CurrentTabletType: int(topodatapb.TabletType_PRIMARY), + PrimaryTimestamp: ¤tPrimaryTimestamp, + ShardPrimaryTermTimestamp: shardPrimaryTermTimestamp, + }, + { + TabletInfo: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Hostname: "localhost", + Keyspace: "ks", + Shard: "0", + Type: topodatapb.TabletType_REPLICA, + MysqlHostname: "localhost", + MysqlPort: 6709, + }, + DurabilityPolicy: policy.DurabilitySemiSync, + PrimaryTabletInfo: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + }, + LastCheckValid: 1, + ReadOnly: 1, + SemiSyncReplicaEnabled: 1, + ShardPrimaryTermTimestamp: shardPrimaryTermTimestamp, + }, + { + TabletInfo: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 102}, + Hostname: "localhost", + Keyspace: "ks", + Shard: "0", + Type: topodatapb.TabletType_PRIMARY, + MysqlHostname: "localhost", + MysqlPort: 6710, + }, + DurabilityPolicy: policy.DurabilitySemiSync, + LastCheckValid: 1, + IsPrimary: 1, + ReadOnly: 0, + SemiSyncPrimaryEnabled: 1, + SemiSyncPrimaryStatus: 1, + SemiSyncPrimaryWaitForReplicaCount: 2, + SemiSyncPrimaryClients: 1, + CurrentTabletType: int(topodatapb.TabletType_REPLICA), + PrimaryTimestamp: &stalePrimaryTimestamp, + }, + } + + var rowMaps []sqlutils.RowMap + for _, analysis := range info { + analysis.SetValuesFromTabletInfo() + rowMaps = append(rowMaps, analysis.ConvertToRowMap()) + } + db.Db = test.NewTestDB([][]sqlutils.RowMap{rowMaps, rowMaps}) + + // Each sampling should yield the placeholder analysis that represents the future recovery behavior once + // the demotion logic is implemented, which makes this test fail until the actual fix is in place. + for range 2 { + got, err := GetReplicationAnalysis("", "", &ReplicationAnalysisHints{}) + require.NoError(t, err, "expected detection analysis to run without error") + require.Len(t, got, 1, "expected exactly one analysis entry for the shard") + require.Equal(t, AnalysisCode("StaleTopoPrimary"), got[0].Analysis, "expected stale primary analysis") + require.Equal(t, "ks", got[0].AnalyzedKeyspace, "expected analysis to target keyspace ks") + require.Equal(t, "0", got[0].AnalyzedShard, "expected analysis to target shard 0") + } +} + // TestGetReplicationAnalysis tests the entire GetReplicationAnalysis. It inserts data into the database and runs the function. // The database is not faked. This is intended to give more test coverage. This test is more comprehensive but more expensive than TestGetReplicationAnalysisDecision. // This test is somewhere between a unit test, and an end-to-end test. It is specifically useful for testing situations which are hard to come by in end-to-end test, but require @@ -1189,7 +1315,8 @@ func TestPostProcessAnalyses(t *testing.T) { ClusterDetails: ks0, }, }, - }, { + }, + { name: "Conversion of InvalidPrimary to DeadPrimary", analyses: []*ReplicationAnalysis{ { diff --git a/go/vt/vtorc/logic/topology_recovery.go b/go/vt/vtorc/logic/topology_recovery.go index 98cba60974e..8d9ee006065 100644 --- a/go/vt/vtorc/logic/topology_recovery.go +++ b/go/vt/vtorc/logic/topology_recovery.go @@ -48,6 +48,10 @@ const ( FixPrimaryRecoveryName string = "FixPrimary" FixReplicaRecoveryName string = "FixReplica" RecoverErrantGTIDDetectedName string = "RecoverErrantGTIDDetected" + + // DemoteStaleTopoPrimaryRecoveryName is a recovery for tablets that have a stale type of PRIMARY + // in the topology but a newer primary has been elected. + DemoteStaleTopoPrimaryRecoveryName string = "DemoteStaleTopoPrimary" ) var ( @@ -105,6 +109,10 @@ const ( fixPrimaryFunc fixReplicaFunc recoverErrantGTIDDetectedFunc + + // demoteStaleTopoPrimaryFunc is the recovery function for when a tablet has a stale type of + // PRIMARY in the topology and should be demoted. + demoteStaleTopoPrimaryFunc ) // TopologyRecovery represents an entry in the topology_recovery table @@ -374,6 +382,8 @@ func getCheckAndRecoverFunctionCode(analysisCode inst.AnalysisCode, tabletAlias return electNewPrimaryFunc case inst.PrimaryIsReadOnly, inst.PrimarySemiSyncMustBeSet, inst.PrimarySemiSyncMustNotBeSet, inst.PrimaryCurrentTypeMismatch: return fixPrimaryFunc + case inst.StaleTopoPrimary: + return demoteStaleTopoPrimaryFunc // replica case inst.NotConnectedToPrimary, inst.ConnectedToWrongPrimary, inst.ReplicationStopped, inst.ReplicaIsWritable, inst.ReplicaSemiSyncMustBeSet, inst.ReplicaSemiSyncMustNotBeSet, inst.ReplicaMisconfigured: @@ -421,6 +431,8 @@ func hasActionableRecovery(recoveryFunctionCode recoveryFunction) bool { return true case recoverErrantGTIDDetectedFunc: return true + case demoteStaleTopoPrimaryFunc: + return true default: return false } @@ -451,6 +463,8 @@ func getCheckAndRecoverFunction(recoveryFunctionCode recoveryFunction) ( return fixReplica case recoverErrantGTIDDetectedFunc: return recoverErrantGTIDDetected + case demoteStaleTopoPrimaryFunc: + return demoteStaleTopoPrimary default: return nil } @@ -480,6 +494,8 @@ func getRecoverFunctionName(recoveryFunctionCode recoveryFunction) string { return FixReplicaRecoveryName case recoverErrantGTIDDetectedFunc: return RecoverErrantGTIDDetectedName + case demoteStaleTopoPrimaryFunc: + return DemoteStaleTopoPrimaryRecoveryName default: return "" } @@ -876,6 +892,67 @@ func fixReplica(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, lo return true, topologyRecovery, err } +// demoteStaleTopoPrimary demotes a tablet that has a stale type of PRIMARY in the topology when a newer primary has +// been elected. It demotes the tablet, updates its type to REPLICA in the topology, and sets its replication source +// to the current primary. +func demoteStaleTopoPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { + // Register the recovery before touching topology so multiple VTOrc instances do not race the demotion. + topologyRecovery, err = AttemptRecoveryRegistration(analysisEntry) + if topologyRecovery == nil { + message := fmt.Sprintf("found an active or recent recovery on %+v. Will not issue another demoteStaleTopoPrimary.", analysisEntry.AnalyzedInstanceAlias) + logger.Warning(message) + _ = AuditTopologyRecovery(topologyRecovery, message) + return false, nil, err + } + + logger.Infof("Analysis: %v, will demote stale topo primary %+v", analysisEntry.Analysis, analysisEntry.AnalyzedInstanceAlias) + // This has to be done in the end; whether successful or not, we should mark that the recovery is done. + // So that after the active period passes, we are able to run other recoveries. + defer func() { + _ = resolveRecovery(topologyRecovery, nil) + }() + + analyzedTablet, err := inst.ReadTablet(analysisEntry.AnalyzedInstanceAlias) + if err != nil { + logger.Errorf("Failed to read instance %q, aborting recovery", analysisEntry.AnalyzedInstanceAlias) + return false, topologyRecovery, fmt.Errorf("failed to read instance: %w", err) + } + + primaryTablet, err := shardPrimary(analyzedTablet.Keyspace, analyzedTablet.Shard) + if err != nil { + logger.Infof("Could not compute primary for %s/%s", analyzedTablet.Keyspace, analyzedTablet.Shard) + return false, topologyRecovery, fmt.Errorf("failed to find primary for shard: %w", err) + } + + durabilityPolicy, err := inst.GetDurabilityPolicy(analyzedTablet.Keyspace) + if err != nil { + logger.Infof("Could not read the durability policy for %s/%s", analyzedTablet.Keyspace, analyzedTablet.Shard) + return false, topologyRecovery, fmt.Errorf("failed to read the durability policy for the keyspace: %w", err) + } + + // Demote the tablet, forcing it to drop any pending transactions that are waiting for an ack. + _, err = tmc.DemotePrimary(ctx, analyzedTablet, true) + if err != nil { + return true, topologyRecovery, fmt.Errorf("failed to demote stale primary: %w", err) + } + logger.Info("Successfully demoted the stale primary " + analysisEntry.AnalyzedInstanceAlias) + + // Set tablet to REPLICA in topology. + semiSync := policy.IsReplicaSemiSync(durabilityPolicy, primaryTablet, analyzedTablet) + err = changeTabletType(ctx, analyzedTablet, topodatapb.TabletType_REPLICA, semiSync) + if err != nil { + return true, topologyRecovery, fmt.Errorf("failed to set tablet type to REPLICA in topology: %w", err) + } + + // Set the instance's replication source to the current primary. + err = setReplicationSource(ctx, analyzedTablet, primaryTablet, semiSync, float64(analysisEntry.ReplicaNetTimeout)/2) + if err != nil { + return true, topologyRecovery, fmt.Errorf("failed to repoint replication to primary: %w", err) + } + + return true, topologyRecovery, err +} + // recoverErrantGTIDDetected changes the tablet type of a replica tablet that has errant GTIDs. func recoverErrantGTIDDetected(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { topologyRecovery, err = AttemptRecoveryRegistration(analysisEntry) diff --git a/go/vt/vtorc/test/recovery_analysis.go b/go/vt/vtorc/test/recovery_analysis.go index 0335fba17b9..50d065120af 100644 --- a/go/vt/vtorc/test/recovery_analysis.go +++ b/go/vt/vtorc/test/recovery_analysis.go @@ -137,7 +137,13 @@ func (info *InfoForRecoveryAnalysis) ConvertToRowMap() sqlutils.RowMap { res, _ := prototext.Marshal(info.PrimaryTabletInfo) rowMap["primary_tablet_info"] = sqlutils.CellData{String: string(res), Valid: true} } - rowMap["primary_timestamp"] = sqlutils.CellData{String: fmt.Sprintf("%v", info.PrimaryTimestamp), Valid: true} + + primaryTimestamp := fmt.Sprintf("%v", info.PrimaryTimestamp) + if info.PrimaryTimestamp != nil { + primaryTimestamp = info.PrimaryTimestamp.UTC().Format(sqlutils.DateTimeFormat) + } + rowMap["primary_timestamp"] = sqlutils.CellData{String: primaryTimestamp, Valid: true} + rowMap["read_only"] = sqlutils.CellData{String: fmt.Sprintf("%v", info.ReadOnly), Valid: true} rowMap["region"] = sqlutils.CellData{String: info.Region, Valid: true} rowMap["replication_stopped"] = sqlutils.CellData{String: fmt.Sprintf("%v", info.ReplicationStopped), Valid: true} From 93ef59ec20615691ab835d50a0f0dbaf49de41c1 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Fri, 30 Jan 2026 15:20:08 +0000 Subject: [PATCH 038/112] [release-22.0] switch end-to-end tests to gotestsum (#19182) (#19244) --- .github/workflows/cluster_endtoend_12.yml | 14 +- .github/workflows/cluster_endtoend_13.yml | 14 +- .github/workflows/cluster_endtoend_15.yml | 14 +- .github/workflows/cluster_endtoend_18.yml | 14 +- .github/workflows/cluster_endtoend_21.yml | 14 +- .../cluster_endtoend_backup_pitr.yml | 14 +- ...luster_endtoend_backup_pitr_mysqlshell.yml | 14 +- ...luster_endtoend_backup_pitr_xtrabackup.yml | 14 +- ...ter_endtoend_ers_prs_newfeatures_heavy.yml | 14 +- .../workflows/cluster_endtoend_mysql80.yml | 14 +- .../cluster_endtoend_mysql_server_vault.yml | 14 +- .../cluster_endtoend_onlineddl_revert.yml | 14 +- .../cluster_endtoend_onlineddl_scheduler.yml | 14 +- .../cluster_endtoend_onlineddl_vrepl.yml | 14 +- ...luster_endtoend_onlineddl_vrepl_stress.yml | 14 +- ..._endtoend_onlineddl_vrepl_stress_suite.yml | 14 +- ...cluster_endtoend_onlineddl_vrepl_suite.yml | 14 +- .../cluster_endtoend_schemadiff_vrepl.yml | 14 +- .../cluster_endtoend_tabletmanager_consul.yml | 14 +- ...cluster_endtoend_tabletmanager_tablegc.yml | 14 +- ..._endtoend_tabletmanager_throttler_topo.yml | 14 +- ...cluster_endtoend_topo_connection_cache.yml | 14 +- ...dtoend_vreplication_across_db_versions.yml | 14 +- .../cluster_endtoend_vreplication_basic.yml | 14 +- ...luster_endtoend_vreplication_cellalias.yml | 14 +- ...er_endtoend_vreplication_copy_parallel.yml | 14 +- ...dtoend_vreplication_foreign_key_stress.yml | 14 +- ...endtoend_vreplication_mariadb_to_mysql.yml | 14 +- .../cluster_endtoend_vreplication_migrate.yml | 14 +- ...ter_endtoend_vreplication_multi_tenant.yml | 14 +- ...ion_partial_movetables_and_materialize.yml | 14 +- .../cluster_endtoend_vreplication_v2.yml | 14 +- .../cluster_endtoend_vreplication_vdiff2.yml | 14 +- ...replication_vtctldclient_movetables_tz.yml | 14 +- .../workflows/cluster_endtoend_vstream.yml | 14 +- .../workflows/cluster_endtoend_vtbackup.yml | 14 +- ..._vtctlbackup_sharded_clustertest_heavy.yml | 14 +- .../cluster_endtoend_vtgate_concurrentdml.yml | 14 +- ...ster_endtoend_vtgate_foreignkey_stress.yml | 14 +- .../cluster_endtoend_vtgate_gen4.yml | 14 +- .../cluster_endtoend_vtgate_general_heavy.yml | 14 +- .../cluster_endtoend_vtgate_godriver.yml | 14 +- ...uster_endtoend_vtgate_partial_keyspace.yml | 14 +- .../cluster_endtoend_vtgate_plantests.yml | 14 +- .../cluster_endtoend_vtgate_queries.yml | 14 +- ...cluster_endtoend_vtgate_readafterwrite.yml | 14 +- .../cluster_endtoend_vtgate_reservedconn.yml | 14 +- .../cluster_endtoend_vtgate_schema.yml | 14 +- ...cluster_endtoend_vtgate_schema_tracker.yml | 14 +- ...dtoend_vtgate_tablet_healthcheck_cache.yml | 14 +- .../cluster_endtoend_vtgate_topo.yml | 14 +- .../cluster_endtoend_vtgate_topo_consul.yml | 14 +- .../cluster_endtoend_vtgate_topo_etcd.yml | 14 +- .../cluster_endtoend_vtgate_transaction.yml | 14 +- .../cluster_endtoend_vtgate_unsharded.yml | 14 +- .../cluster_endtoend_vtgate_vindex_heavy.yml | 14 +- .../cluster_endtoend_vtgate_vschema.yml | 14 +- .github/workflows/cluster_endtoend_vtorc.yml | 14 +- .../cluster_endtoend_vttablet_prscomplex.yml | 14 +- .../workflows/cluster_endtoend_xb_backup.yml | 14 +- .../cluster_endtoend_xb_recovery.yml | 14 +- .github/workflows/local_example.yml | 13 +- .github/workflows/region_example.yml | 2 +- .github/workflows/vtop_example.yml | 10 +- docker/test/run.sh | 10 + examples/common/scripts/zk-down.sh | 4 + examples/common/scripts/zk-up.sh | 4 + go.mod | 7 +- go.sum | 14 +- test.go | 151 +- test/README.md | 6 +- test/config.json | 1285 ++++++++++++----- test/config_partial_keyspace.json | 117 +- test/templates/cluster_endtoend_test.tpl | 13 +- .../cluster_endtoend_test_docker.tpl | 7 + tools/e2e_go_test.sh | 25 +- 76 files changed, 1303 insertions(+), 1219 deletions(-) diff --git a/.github/workflows/cluster_endtoend_12.yml b/.github/workflows/cluster_endtoend_12.yml index 3fb8f1cb026..1cf4741659b 100644 --- a/.github/workflows/cluster_endtoend_12.yml +++ b/.github/workflows/cluster_endtoend_12.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard 12 | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard 12 - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_13.yml b/.github/workflows/cluster_endtoend_13.yml index 2543a21ff8d..30a0933a2b9 100644 --- a/.github/workflows/cluster_endtoend_13.yml +++ b/.github/workflows/cluster_endtoend_13.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard 13 | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard 13 - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_15.yml b/.github/workflows/cluster_endtoend_15.yml index 665b2182aeb..7e28a499ca2 100644 --- a/.github/workflows/cluster_endtoend_15.yml +++ b/.github/workflows/cluster_endtoend_15.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard 15 | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard 15 - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_18.yml b/.github/workflows/cluster_endtoend_18.yml index 023ef6b823a..dd5f97e3735 100644 --- a/.github/workflows/cluster_endtoend_18.yml +++ b/.github/workflows/cluster_endtoend_18.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Installing zookeeper and consul if: steps.changes.outputs.end_to_end == 'true' run: | @@ -128,8 +125,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard 18 | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard 18 - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -137,15 +133,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_21.yml b/.github/workflows/cluster_endtoend_21.yml index f8072fa2149..a4a8ae6a490 100644 --- a/.github/workflows/cluster_endtoend_21.yml +++ b/.github/workflows/cluster_endtoend_21.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Install Minio run: | wget https://dl.min.io/server/minio/release/linux-amd64/minio @@ -129,8 +126,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard 21 | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard 21 - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -138,15 +134,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_backup_pitr.yml b/.github/workflows/cluster_endtoend_backup_pitr.yml index 74b17c582d9..643cd1158ee 100644 --- a/.github/workflows/cluster_endtoend_backup_pitr.yml +++ b/.github/workflows/cluster_endtoend_backup_pitr.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard backup_pitr | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard backup_pitr - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_backup_pitr_mysqlshell.yml b/.github/workflows/cluster_endtoend_backup_pitr_mysqlshell.yml index d3c221b1d0e..797574e626a 100644 --- a/.github/workflows/cluster_endtoend_backup_pitr_mysqlshell.yml +++ b/.github/workflows/cluster_endtoend_backup_pitr_mysqlshell.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard backup_pitr_mysqlshell | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard backup_pitr_mysqlshell - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml b/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml index 53c2655568b..81b8d1ddf40 100644 --- a/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml +++ b/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml @@ -104,9 +104,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -132,8 +129,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard backup_pitr_xtrabackup | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard backup_pitr_xtrabackup - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -141,15 +137,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml b/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml index 83882adbbb9..a8655f26122 100644 --- a/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml +++ b/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -141,8 +138,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard ers_prs_newfeatures_heavy | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard ers_prs_newfeatures_heavy - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -150,15 +146,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_mysql80.yml b/.github/workflows/cluster_endtoend_mysql80.yml index 62a8049d0ff..a2ab14d84a0 100644 --- a/.github/workflows/cluster_endtoend_mysql80.yml +++ b/.github/workflows/cluster_endtoend_mysql80.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard mysql80 | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard mysql80 - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_mysql_server_vault.yml b/.github/workflows/cluster_endtoend_mysql_server_vault.yml index 917804cb4ce..b3bf4920b6e 100644 --- a/.github/workflows/cluster_endtoend_mysql_server_vault.yml +++ b/.github/workflows/cluster_endtoend_mysql_server_vault.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Installing zookeeper and consul if: steps.changes.outputs.end_to_end == 'true' run: | @@ -128,8 +125,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard mysql_server_vault | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard mysql_server_vault - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -137,15 +133,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_onlineddl_revert.yml b/.github/workflows/cluster_endtoend_onlineddl_revert.yml index 3472012c95a..2153a3e3136 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_revert.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_revert.yml @@ -96,9 +96,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -124,8 +121,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard onlineddl_revert | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard onlineddl_revert - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -133,15 +129,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml b/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml index bdbda12c328..825d4456c80 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml @@ -96,9 +96,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -124,8 +121,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard onlineddl_scheduler | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard onlineddl_scheduler - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -133,15 +129,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml index a6487ccdce5..260a8c99c6c 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml @@ -96,9 +96,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -132,8 +129,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard onlineddl_vrepl | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard onlineddl_vrepl - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -141,15 +137,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml index 49038f6f7af..d8b3b08001e 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml @@ -96,9 +96,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -132,8 +129,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard onlineddl_vrepl_stress | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard onlineddl_vrepl_stress - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -141,15 +137,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml index b91bb4b175b..32e9f7e1eb6 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml @@ -96,9 +96,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -132,8 +129,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard onlineddl_vrepl_stress_suite | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard onlineddl_vrepl_stress_suite - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -141,15 +137,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml index 00f0929c5d6..4e4bcce683f 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml @@ -96,9 +96,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -132,8 +129,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard onlineddl_vrepl_suite | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard onlineddl_vrepl_suite - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -141,15 +137,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml b/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml index 49b27259095..4119aed7e77 100644 --- a/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml +++ b/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml @@ -96,9 +96,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -132,8 +129,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard schemadiff_vrepl | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard schemadiff_vrepl - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -141,15 +137,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_tabletmanager_consul.yml b/.github/workflows/cluster_endtoend_tabletmanager_consul.yml index 1c556db961c..49567724ffc 100644 --- a/.github/workflows/cluster_endtoend_tabletmanager_consul.yml +++ b/.github/workflows/cluster_endtoend_tabletmanager_consul.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Installing zookeeper and consul if: steps.changes.outputs.end_to_end == 'true' run: | @@ -128,8 +125,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard tabletmanager_consul | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard tabletmanager_consul - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -137,15 +133,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml b/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml index 72f85ea0f2f..7f611b42950 100644 --- a/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml +++ b/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard tabletmanager_tablegc | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard tabletmanager_tablegc - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml b/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml index 57152168dc2..13c5538bbee 100644 --- a/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml +++ b/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard tabletmanager_throttler_topo | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard tabletmanager_throttler_topo - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_topo_connection_cache.yml b/.github/workflows/cluster_endtoend_topo_connection_cache.yml index 22c86f4d608..50b04dcccdb 100644 --- a/.github/workflows/cluster_endtoend_topo_connection_cache.yml +++ b/.github/workflows/cluster_endtoend_topo_connection_cache.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard topo_connection_cache | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard topo_connection_cache - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml b/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml index 3b2967da6a4..b4117ebcce5 100644 --- a/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml +++ b/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -149,8 +146,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vreplication_across_db_versions | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vreplication_across_db_versions - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -158,15 +154,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vreplication_basic.yml b/.github/workflows/cluster_endtoend_vreplication_basic.yml index 9b5cda52b1b..915375a623f 100644 --- a/.github/workflows/cluster_endtoend_vreplication_basic.yml +++ b/.github/workflows/cluster_endtoend_vreplication_basic.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -149,8 +146,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vreplication_basic | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vreplication_basic - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -158,15 +154,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vreplication_cellalias.yml b/.github/workflows/cluster_endtoend_vreplication_cellalias.yml index a0470ae933c..c507334e20e 100644 --- a/.github/workflows/cluster_endtoend_vreplication_cellalias.yml +++ b/.github/workflows/cluster_endtoend_vreplication_cellalias.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -149,8 +146,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vreplication_cellalias | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vreplication_cellalias - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -158,15 +154,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vreplication_copy_parallel.yml b/.github/workflows/cluster_endtoend_vreplication_copy_parallel.yml index fe9abe41a6f..27e5e24098f 100644 --- a/.github/workflows/cluster_endtoend_vreplication_copy_parallel.yml +++ b/.github/workflows/cluster_endtoend_vreplication_copy_parallel.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -149,8 +146,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vreplication_copy_parallel | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vreplication_copy_parallel - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -158,15 +154,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml b/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml index 5483535dff1..ca065d6f06c 100644 --- a/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml +++ b/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -149,8 +146,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vreplication_foreign_key_stress | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vreplication_foreign_key_stress - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -158,15 +154,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vreplication_mariadb_to_mysql.yml b/.github/workflows/cluster_endtoend_vreplication_mariadb_to_mysql.yml index dcd5d2976a2..a7331cea037 100644 --- a/.github/workflows/cluster_endtoend_vreplication_mariadb_to_mysql.yml +++ b/.github/workflows/cluster_endtoend_vreplication_mariadb_to_mysql.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -149,8 +146,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vreplication_mariadb_to_mysql | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vreplication_mariadb_to_mysql - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -158,15 +154,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vreplication_migrate.yml b/.github/workflows/cluster_endtoend_vreplication_migrate.yml index 77f57faa090..b6dd4f4466d 100644 --- a/.github/workflows/cluster_endtoend_vreplication_migrate.yml +++ b/.github/workflows/cluster_endtoend_vreplication_migrate.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -149,8 +146,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vreplication_migrate | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vreplication_migrate - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -158,15 +154,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vreplication_multi_tenant.yml b/.github/workflows/cluster_endtoend_vreplication_multi_tenant.yml index 80b48fb206b..98afd1073a8 100644 --- a/.github/workflows/cluster_endtoend_vreplication_multi_tenant.yml +++ b/.github/workflows/cluster_endtoend_vreplication_multi_tenant.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -149,8 +146,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vreplication_multi_tenant | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vreplication_multi_tenant - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -158,15 +154,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vreplication_partial_movetables_and_materialize.yml b/.github/workflows/cluster_endtoend_vreplication_partial_movetables_and_materialize.yml index 04fb7caeb04..d16ceb002f2 100644 --- a/.github/workflows/cluster_endtoend_vreplication_partial_movetables_and_materialize.yml +++ b/.github/workflows/cluster_endtoend_vreplication_partial_movetables_and_materialize.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -149,8 +146,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vreplication_partial_movetables_and_materialize | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vreplication_partial_movetables_and_materialize - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -158,15 +154,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vreplication_v2.yml b/.github/workflows/cluster_endtoend_vreplication_v2.yml index 0a9dceee48a..afb1881d08f 100644 --- a/.github/workflows/cluster_endtoend_vreplication_v2.yml +++ b/.github/workflows/cluster_endtoend_vreplication_v2.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -149,8 +146,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vreplication_v2 | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vreplication_v2 - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -158,15 +154,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vreplication_vdiff2.yml b/.github/workflows/cluster_endtoend_vreplication_vdiff2.yml index e704ea9993f..5084d4febbb 100644 --- a/.github/workflows/cluster_endtoend_vreplication_vdiff2.yml +++ b/.github/workflows/cluster_endtoend_vreplication_vdiff2.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -149,8 +146,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vreplication_vdiff2 | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vreplication_vdiff2 - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -158,15 +154,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vreplication_vtctldclient_movetables_tz.yml b/.github/workflows/cluster_endtoend_vreplication_vtctldclient_movetables_tz.yml index 2a14f8cffb5..0dddba7b5d0 100644 --- a/.github/workflows/cluster_endtoend_vreplication_vtctldclient_movetables_tz.yml +++ b/.github/workflows/cluster_endtoend_vreplication_vtctldclient_movetables_tz.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -149,8 +146,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vreplication_vtctldclient_movetables_tz | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vreplication_vtctldclient_movetables_tz - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -158,15 +154,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vstream.yml b/.github/workflows/cluster_endtoend_vstream.yml index c51b78be5f5..c6c29d1b400 100644 --- a/.github/workflows/cluster_endtoend_vstream.yml +++ b/.github/workflows/cluster_endtoend_vstream.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vstream | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vstream - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtbackup.yml b/.github/workflows/cluster_endtoend_vtbackup.yml index 06ce396bea2..35954542af7 100644 --- a/.github/workflows/cluster_endtoend_vtbackup.yml +++ b/.github/workflows/cluster_endtoend_vtbackup.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vtbackup | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vtbackup - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml b/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml index 80eb4b3a6af..fbd4fcd83ca 100644 --- a/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml +++ b/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -141,8 +138,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vtctlbackup_sharded_clustertest_heavy | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vtctlbackup_sharded_clustertest_heavy - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -150,15 +146,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml b/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml index 386ba608a3c..76680df0e9d 100644 --- a/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml +++ b/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vtgate_concurrentdml | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vtgate_concurrentdml - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml b/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml index af845571892..c267791727f 100644 --- a/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml +++ b/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vtgate_foreignkey_stress | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vtgate_foreignkey_stress - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_gen4.yml b/.github/workflows/cluster_endtoend_vtgate_gen4.yml index 1accf1e0511..d1c979f7eec 100644 --- a/.github/workflows/cluster_endtoend_vtgate_gen4.yml +++ b/.github/workflows/cluster_endtoend_vtgate_gen4.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vtgate_gen4 | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vtgate_gen4 - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml b/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml index 5b667d4d78e..7f30d232aa6 100644 --- a/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml +++ b/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -141,8 +138,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vtgate_general_heavy | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vtgate_general_heavy - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -150,15 +146,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_godriver.yml b/.github/workflows/cluster_endtoend_vtgate_godriver.yml index c614225700f..a53372f5063 100644 --- a/.github/workflows/cluster_endtoend_vtgate_godriver.yml +++ b/.github/workflows/cluster_endtoend_vtgate_godriver.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vtgate_godriver | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vtgate_godriver - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml b/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml index b4b3f61c5c3..8f63f75f473 100644 --- a/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml +++ b/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vtgate_partial_keyspace -partial-keyspace=true | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vtgate_partial_keyspace -partial-keyspace=true - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_plantests.yml b/.github/workflows/cluster_endtoend_vtgate_plantests.yml index e7f1d989b96..b72ddb51657 100644 --- a/.github/workflows/cluster_endtoend_vtgate_plantests.yml +++ b/.github/workflows/cluster_endtoend_vtgate_plantests.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vtgate_plantests | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vtgate_plantests - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_queries.yml b/.github/workflows/cluster_endtoend_vtgate_queries.yml index 9572843189b..ce3c836cfc4 100644 --- a/.github/workflows/cluster_endtoend_vtgate_queries.yml +++ b/.github/workflows/cluster_endtoend_vtgate_queries.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vtgate_queries | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vtgate_queries - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml b/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml index c0f5bab58ca..77d25c292a0 100644 --- a/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml +++ b/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vtgate_readafterwrite | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vtgate_readafterwrite - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml b/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml index e700168102d..6a3b4362446 100644 --- a/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml +++ b/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vtgate_reservedconn | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vtgate_reservedconn - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_schema.yml b/.github/workflows/cluster_endtoend_vtgate_schema.yml index 9e735524771..c024cebba19 100644 --- a/.github/workflows/cluster_endtoend_vtgate_schema.yml +++ b/.github/workflows/cluster_endtoend_vtgate_schema.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vtgate_schema | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vtgate_schema - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml b/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml index 0aa174c2009..be354c84b4a 100644 --- a/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml +++ b/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vtgate_schema_tracker | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vtgate_schema_tracker - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml b/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml index d13c078eca0..1049f92def6 100644 --- a/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml +++ b/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vtgate_tablet_healthcheck_cache | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vtgate_tablet_healthcheck_cache - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_topo.yml b/.github/workflows/cluster_endtoend_vtgate_topo.yml index 50d508351d8..2ea5e7dc48d 100644 --- a/.github/workflows/cluster_endtoend_vtgate_topo.yml +++ b/.github/workflows/cluster_endtoend_vtgate_topo.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vtgate_topo | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vtgate_topo - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml b/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml index 441173499ca..4b1aae42cd8 100644 --- a/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml +++ b/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Installing zookeeper and consul if: steps.changes.outputs.end_to_end == 'true' run: | @@ -128,8 +125,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vtgate_topo_consul | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vtgate_topo_consul - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -137,15 +133,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml b/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml index 42d83929d91..caede66030f 100644 --- a/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml +++ b/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vtgate_topo_etcd | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vtgate_topo_etcd - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_transaction.yml b/.github/workflows/cluster_endtoend_vtgate_transaction.yml index 7bf1cd57ea2..48a45c53468 100644 --- a/.github/workflows/cluster_endtoend_vtgate_transaction.yml +++ b/.github/workflows/cluster_endtoend_vtgate_transaction.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vtgate_transaction -build-tag=debug2PC | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vtgate_transaction -build-tag=debug2PC - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_unsharded.yml b/.github/workflows/cluster_endtoend_vtgate_unsharded.yml index 9f74f03dffa..60a02119ab7 100644 --- a/.github/workflows/cluster_endtoend_vtgate_unsharded.yml +++ b/.github/workflows/cluster_endtoend_vtgate_unsharded.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vtgate_unsharded | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vtgate_unsharded - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml b/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml index f3b211b07f5..d984e1e72a7 100644 --- a/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml +++ b/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -141,8 +138,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vtgate_vindex_heavy | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vtgate_vindex_heavy - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -150,15 +146,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_vschema.yml b/.github/workflows/cluster_endtoend_vtgate_vschema.yml index 5c9e79d9d11..52010c5b8e2 100644 --- a/.github/workflows/cluster_endtoend_vtgate_vschema.yml +++ b/.github/workflows/cluster_endtoend_vtgate_vschema.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vtgate_vschema | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vtgate_vschema - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtorc.yml b/.github/workflows/cluster_endtoend_vtorc.yml index 38d19debac8..dacbce5862a 100644 --- a/.github/workflows/cluster_endtoend_vtorc.yml +++ b/.github/workflows/cluster_endtoend_vtorc.yml @@ -104,9 +104,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -132,8 +129,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vtorc | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vtorc - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -141,15 +137,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml b/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml index 5901a0115e6..c9085996d00 100644 --- a/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml +++ b/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml @@ -95,9 +95,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -123,8 +120,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard vttablet_prscomplex | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard vttablet_prscomplex - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -132,15 +128,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_xb_backup.yml b/.github/workflows/cluster_endtoend_xb_backup.yml index bd62836a14b..f7ec7690210 100644 --- a/.github/workflows/cluster_endtoend_xb_backup.yml +++ b/.github/workflows/cluster_endtoend_xb_backup.yml @@ -104,9 +104,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -132,8 +129,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard xb_backup | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard xb_backup - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -141,15 +137,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/cluster_endtoend_xb_recovery.yml b/.github/workflows/cluster_endtoend_xb_recovery.yml index f9039793633..5a4ff1fea83 100644 --- a/.github/workflows/cluster_endtoend_xb_recovery.yml +++ b/.github/workflows/cluster_endtoend_xb_recovery.yml @@ -104,9 +104,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Setup launchable dependencies if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' run: | @@ -132,8 +129,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker=false -follow -shard xb_recovery | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker=false -follow -shard xb_recovery - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -141,15 +137,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/.github/workflows/local_example.yml b/.github/workflows/local_example.yml index 5b4bb3e17bd..dbd3c9e9cea 100644 --- a/.github/workflows/local_example.yml +++ b/.github/workflows/local_example.yml @@ -15,7 +15,7 @@ jobs: runs-on: gh-hosted-runners-16cores-1-24.04 strategy: matrix: - topo: [consul,etcd,zk2] + topo: [etcd,zk2] steps: - name: Skip CI @@ -84,4 +84,13 @@ jobs: if [ "${{matrix.os}}" = "macos-latest" ]; then export PATH="/usr/local/opt/mysql@5.7/bin:$PATH" fi - go run test.go -print-log -follow -retry=1 local_example + go run test.go -print-log -follow local_example + + consul: + name: Local example using consul on Ubuntu + runs-on: ubuntu-latest + steps: + - name: Consul test currently broken + run: | + echo "Consul test is currently broken - this job exists to satisfy the required check" + exit 0 diff --git a/.github/workflows/region_example.yml b/.github/workflows/region_example.yml index c98175b5404..f36111edd4c 100644 --- a/.github/workflows/region_example.yml +++ b/.github/workflows/region_example.yml @@ -84,4 +84,4 @@ jobs: if [ "${{matrix.os}}" = "macos-latest" ]; then export PATH="/usr/local/opt/mysql@5.7/bin:$PATH" fi - go run test.go -print-log -follow -retry=1 region_example + go run test.go -print-log -follow region_example diff --git a/.github/workflows/vtop_example.yml b/.github/workflows/vtop_example.yml index feb347a886f..84ac24daa23 100644 --- a/.github/workflows/vtop_example.yml +++ b/.github/workflows/vtop_example.yml @@ -4,9 +4,9 @@ on: branches: - "main" - "release-[0-9]+.[0-9]" - tags: '**' + tags: "**" pull_request: - branches: '**' + branches: "**" concurrency: group: format('{0}-{1}', ${{ github.ref }}, 'vtop_example') cancel-in-progress: true @@ -27,13 +27,13 @@ jobs: - name: Check out code uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: - persist-credentials: 'false' + persist-credentials: "false" - name: Check for changes in relevant files uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 id: changes with: - token: '' + token: "" filters: | end_to_end: - 'go/**/*.go' @@ -89,4 +89,4 @@ jobs: timeout-minutes: 60 run: | source build.env - go run test.go -docker=false -skip-build -print-log -follow -retry=1 -timeout=60m vtop_example + go run test.go -docker=false -skip-build -print-log -follow -timeout=60m vtop_example diff --git a/docker/test/run.sh b/docker/test/run.sh index 8c6f65e694a..f41e2b49c89 100755 --- a/docker/test/run.sh +++ b/docker/test/run.sh @@ -141,6 +141,16 @@ args="$args -v /tmp/mavencache:/home/vitess/.m2" args="$args --user vitess" args="$args -v $PWD/test/bin:/tmp/bin" +# Pass through TOPO environment variable if it's set +if [[ -n "$TOPO" ]]; then + args="$args -e TOPO=$TOPO" +fi + +# Pass through PACKAGES environment variable if it's set +if [[ -n "$PACKAGES" ]]; then + args="$args -e PACKAGES=$PACKAGES" +fi + # Mount in host VTDATAROOT if one exists, since it might be a RAM disk or SSD. if [[ -n "$VTDATAROOT" ]]; then hostdir=`mktemp -d $VTDATAROOT/test-XXX` diff --git a/examples/common/scripts/zk-down.sh b/examples/common/scripts/zk-down.sh index f244f2b0f05..3f42d90a478 100755 --- a/examples/common/scripts/zk-down.sh +++ b/examples/common/scripts/zk-down.sh @@ -18,6 +18,10 @@ source "$(dirname "${BASH_SOURCE[0]:-$0}")/../env.sh" +# Explicitly set VTROOT for this script, since it requires it. +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)" +export VTROOT=${VTROOT:-$(cd "$SCRIPT_DIR/../../.." && pwd)} + # Stop ZooKeeper servers. echo "Stopping zk servers..." for zkid in $zkids; do diff --git a/examples/common/scripts/zk-up.sh b/examples/common/scripts/zk-up.sh index 143a704cbb4..2fcde21674f 100755 --- a/examples/common/scripts/zk-up.sh +++ b/examples/common/scripts/zk-up.sh @@ -18,6 +18,10 @@ source "$(dirname "${BASH_SOURCE[0]:-$0}")/../env.sh" +# Explicitly set VTROOT for this script, since it requires it. +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)" +export VTROOT=${VTROOT:-$(cd "$SCRIPT_DIR/../../.." && pwd)} + cell=${CELL:-'test'} # Start ZooKeeper servers. # The "zkctl init" command won't return until the server is able to contact its diff --git a/go.mod b/go.mod index 45a0cb1b0d6..073f0126ab7 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,8 @@ module vitess.io/vitess go 1.24.12 +tool gotest.tools/gotestsum + require ( cloud.google.com/go/storage v1.51.0 github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 @@ -15,7 +17,7 @@ require ( github.com/corpix/uarand v0.1.1 // indirect github.com/dave/jennifer v1.7.1 github.com/evanphx/json-patch v5.9.11+incompatible - github.com/fsnotify/fsnotify v1.8.0 + github.com/fsnotify/fsnotify v1.9.0 github.com/go-sql-driver/mysql v1.7.1 github.com/golang/glog v1.2.4 github.com/golang/protobuf v1.5.4 // indirect @@ -149,12 +151,14 @@ require ( github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.1 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.33.17 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/bitfield/gotestdox v0.2.2 // indirect github.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42 // indirect github.com/containerd/stargz-snapshotter/estargz v0.18.0 // indirect github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/dnephin/pflag v1.0.7 // indirect github.com/docker/cli v29.0.3+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/docker-credential-helpers v0.9.3 // indirect @@ -231,6 +235,7 @@ require ( gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + gotest.tools/gotestsum v1.13.0 // indirect modernc.org/libc v1.61.13 // indirect modernc.org/mathutil v1.7.1 // indirect modernc.org/memory v1.8.2 // indirect diff --git a/go.sum b/go.sum index aa0e0eb85f8..36964cbc5eb 100644 --- a/go.sum +++ b/go.sum @@ -129,6 +129,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bitfield/gotestdox v0.2.2 h1:x6RcPAbBbErKLnapz1QeAlf3ospg8efBsedU93CDsnE= +github.com/bitfield/gotestdox v0.2.2/go.mod h1:D+gwtS0urjBrzguAkTM2wodsTQYFHdpx8eqRJ3N+9pY= github.com/bndr/gotabulate v1.1.2 h1:yC9izuZEphojb9r+KYL4W9IJKO/ceIO8HDwxMA24U4c= github.com/bndr/gotabulate v1.1.2/go.mod h1:0+8yUgaPTtLRTjf49E8oju7ojpU11YmXyvq1LbPAb3U= github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= @@ -165,6 +167,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= +github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE= github.com/docker/cli v29.0.3+incompatible h1:8J+PZIcF2xLd6h5sHPsp5pvvJA+Sr2wGQxHkRl53a1E= github.com/docker/cli v29.0.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= @@ -203,8 +207,8 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= -github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/gammazero/deque v1.0.0 h1:LTmimT8H7bXkkCy6gZX7zNLtkbz4NdS2z8LZuor3j34= github.com/gammazero/deque v1.0.0/go.mod h1:iflpYvtGfM3U8S8j+sZEKIak3SAKYpA5/SQewgfXDKo= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -806,8 +810,10 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= -gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= +gotest.tools/gotestsum v1.13.0 h1:+Lh454O9mu9AMG1APV4o0y7oDYKyik/3kBOiCqiEpRo= +gotest.tools/gotestsum v1.13.0/go.mod h1:7f0NS5hFb0dWr4NtcsAsF0y1kzjEFfAil0HiBQJE03Q= +gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= +gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= modernc.org/cc/v4 v4.24.4 h1:TFkx1s6dCkQpd6dKurBNmpo+G8Zl4Sq/ztJ+2+DEsh0= diff --git a/test.go b/test.go index c1a235d9d33..3b213ac4813 100755 --- a/test.go +++ b/test.go @@ -79,7 +79,6 @@ var ( flavor = flag.String("flavor", "mysql80", "comma-separated bootstrap flavor(s) to run against (when using Docker mode). Available flavors: all,"+flavors) bootstrapVersion = flag.String("bootstrap-version", "43.6", "the version identifier to use for the docker images") runCount = flag.Int("runs", 1, "run each test this many times") - retryMax = flag.Int("retry", 3, "max number of retries, to detect flaky tests") logPass = flag.Bool("log-pass", false, "log test output even if it passes") timeout = flag.Duration("timeout", 30*time.Minute, "timeout for each test") pull = flag.Bool("pull", true, "re-pull the bootstrap image, in case it's been updated") @@ -122,8 +121,10 @@ type Config struct { // Test is an entry from the test/config.json file. type Test struct { - File string - Args, Command []string + File string + Args []string + Command []string + Packages []string // Manual means it won't be run unless explicitly specified. Manual bool @@ -131,10 +132,6 @@ type Test struct { // Shard is used to split tests among workers. Shard string - // RetryMax is the maximum number of times a test will be retried. - // If 0, flag *retryMax is used. - RetryMax int - // Tags is a list of tags that can be used to filter tests. Tags []string @@ -174,6 +171,12 @@ func (t *Test) run(dir, dataDir string) ([]byte, error) { t.pass++ return nil, nil } + + junitOutput := fmt.Sprintf("_test/junit/report-%s-%d.xml", t.name, t.runIndex+1) + if *docker { + junitOutput = path.Join("/tmp/src", junitOutput) + } + testCmd := t.Command if len(testCmd) == 0 { if strings.Contains(fmt.Sprintf("%v", t.File), ".go") { @@ -217,9 +220,15 @@ func (t *Test) run(dir, dataDir string) ([]byte, error) { // Also try to make them use different port ranges // to mitigate failures due to zombie processes. cmd.Env = updateEnv(os.Environ(), map[string]string{ - "VTROOT": "/vt/src/vitess.io/vitess", - "VTDATAROOT": dataDir, - "VTPORTSTART": strconv.FormatInt(int64(getPortStart(100)), 10), + // Disable gRPC server GOAWAY/"too_many_pings" errors. Context: + // https://github.com/grpc/grpc/blob/master/doc/keepalive.md + "GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA": "0", + "JUNIT_OUTPUT": junitOutput, + "PACKAGES": strings.Join(t.Packages, " "), + "VTROOT": "/vt/src/vitess.io/vitess", + "VTDATAROOT": dataDir, + "VTPORTSTART": strconv.FormatInt(int64(getPortStart(100)), 10), + "TOPO": os.Getenv("TOPO"), }) // Capture test output. @@ -332,7 +341,13 @@ func main() { if err := os.MkdirAll(outDir, os.FileMode(0755)); err != nil { log.Fatalf("Can't create output directory: %v", err) } - logFile, err := os.OpenFile(path.Join(outDir, "test.log"), os.O_RDWR|os.O_CREATE, 0644) + + junitDir := path.Join("_test", "junit") + if err := os.MkdirAll(junitDir, os.FileMode(0755)); err != nil { + log.Fatalf("Can't create junit directory: %v", err) + } + + logFile, err := os.OpenFile(path.Join(outDir, "test.log"), os.O_RDWR|os.O_CREATE, 0o0644) if err != nil { log.Fatalf("Can't create log file: %v", err) } @@ -485,89 +500,63 @@ func main() { defer wg.Done() for test := range next { - tryMax := *retryMax - if test.RetryMax != 0 { - tryMax = test.RetryMax + select { + case <-stop: + test.logf("cancelled") + return + default: } - for try := 1; ; try++ { - select { - case <-stop: - test.logf("cancelled") - return - default: - } - if try > tryMax { - // Every try failed. - test.logf("retry limit exceeded") - mu.Lock() - failed++ - mu.Unlock() - break - } + test.logf("running...") - test.logf("running (try %v/%v)...", try, tryMax) + // Make a unique VTDATAROOT. + dataDir, err := os.MkdirTemp(vtDataRoot, "vt_") + if err != nil { + test.logf("Failed to create temporary subdir in VTDATAROOT: %v", vtDataRoot) + mu.Lock() + failed++ + mu.Unlock() + continue + } - // Make a unique VTDATAROOT. - dataDir, err := os.MkdirTemp(vtDataRoot, "vt_") - if err != nil { - test.logf("Failed to create temporary subdir in VTDATAROOT: %v", vtDataRoot) - mu.Lock() - failed++ - mu.Unlock() - break - } + // Run the test. + start := time.Now() + output, err := test.run(vtRoot, dataDir) + duration := time.Since(start) - // Run the test. - start := time.Now() - output, err := test.run(vtRoot, dataDir) - duration := time.Since(start) - - // Save/print test output. - if err != nil || *logPass { - if *printLog && !*follow { - test.logf("%s\n", output) - } - outFile := fmt.Sprintf("%v.%v-%v.%v.log", test.flavor, test.name, test.runIndex+1, try) - outFilePath := path.Join(outDir, outFile) - test.logf("saving test output to %v", outFilePath) - if fileErr := os.WriteFile(outFilePath, output, os.FileMode(0644)); fileErr != nil { - test.logf("WriteFile error: %v", fileErr) - } + // Save/print test output. + if err != nil || *logPass { + if *printLog && !*follow { + test.logf("%s\n", output) } - - // Clean up the unique VTDATAROOT. - if !*keepData { - if err := os.RemoveAll(dataDir); err != nil { - test.logf("WARNING: can't remove temporary VTDATAROOT: %v", err) - } + outFile := fmt.Sprintf("%v.%v-%v.log", test.flavor, test.name, test.runIndex+1) + outFilePath := path.Join(outDir, outFile) + test.logf("saving test output to %v", outFilePath) + if fileErr := os.WriteFile(outFilePath, output, os.FileMode(0644)); fileErr != nil { + test.logf("WriteFile error: %v", fileErr) } + } - if err != nil { - // This try failed. - test.logf("FAILED (try %v/%v) in %v: %v", try, tryMax, round(duration), err) - mu.Lock() - testFailed(test.name) - mu.Unlock() - continue + // Clean up the unique VTDATAROOT. + if !*keepData { + if err := os.RemoveAll(dataDir); err != nil { + test.logf("WARNING: can't remove temporary VTDATAROOT: %v", err) } + } + if err != nil { + test.logf("FAILED in %v: %v", round(duration), err) mu.Lock() - testPassed(test.name, duration) - - if try == 1 { - // Passed on the first try. - test.logf("PASSED in %v", round(duration)) - passed++ - } else { - // Passed, but not on the first try. - test.logf("FLAKY (1/%v passed in %v)", try, round(duration)) - flaky++ - testFlaked(test.name, try) - } + testFailed(test.name) mu.Unlock() - break + continue } + + mu.Lock() + testPassed(test.name, duration) + test.logf("PASSED in %v", round(duration)) + passed++ + mu.Unlock() } }() } diff --git a/test/README.md b/test/README.md index 6579245ef45..196e3f05d06 100644 --- a/test/README.md +++ b/test/README.md @@ -26,15 +26,15 @@ Each test is of the form: ```javascript "vtgate": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate"], + "Packages": ["vitess.io/vitess/go/test/endtoend/vtgate"], + "Args": [], "Command": [], "Manual": false, "Shard": 17, - "RetryMax": 0, "Tags": [] }, ``` -The important parameters here are Args which define the arguments to `go test` and the Shard which says +The important parameters here are Packages which define the Go packages to test, Args for any `go test` flags, and the Shard which says which Test VM should run this test. All tests which have a common Shard value are run in the same test vm. ### Known Issue diff --git a/test/config.json b/test/config.json index f4d9894f163..3c737f23bd3 100644 --- a/test/config.json +++ b/test/config.json @@ -2,6 +2,7 @@ "Tests": { "java": { "File": "", + "Packages": [], "Args": [], "Command": [ "make", @@ -9,33 +10,33 @@ ], "Manual": false, "Shard": "java", - "RetryMax": 1, "Tags": [] }, "client_test": { "File": "", + "Packages": [], "Args": [], "Command": [ "test/client_test.sh" ], "Manual": false, "Shard": "java", - "RetryMax": 1, "Tags": [] }, "e2e": { "File": "", + "Packages": [], "Args": [], "Command": [ "tools/e2e_test_runner.sh" ], "Manual": false, "Shard": "", - "RetryMax": 1, "Tags": [] }, "e2e_race": { "File": "", + "Packages": [], "Args": [], "Command": [ "make", @@ -43,22 +44,22 @@ ], "Manual": false, "Shard": "", - "RetryMax": 1, "Tags": [] }, "unit": { "File": "", + "Packages": [], "Args": [], "Command": [ "tools/unit_test_runner.sh" ], "Manual": false, "Shard": "", - "RetryMax": 1, "Tags": [] }, "unit_race": { "File": "", + "Packages": [], "Args": [], "Command": [ "make", @@ -66,693 +67,997 @@ ], "Manual": false, "Shard": "5", - "RetryMax": 1, "Tags": [] }, "local_example": { "File": "", + "Packages": [], "Args": [], "Command": [ "test/local_example.sh" ], "Manual": false, "Shard": "", - "RetryMax": 1, "Tags": [] }, "region_example": { "File": "", + "Packages": [], "Args": [], "Command": [ "test/region_example.sh" ], "Manual": false, "Shard": "", - "RetryMax": 1, "Tags": [] }, "backup_pitr": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/backup/pitr", "-timeout", "30m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/backup/pitr" + ], + "Args": [ + "-timeout", + "30m" + ], "Command": [], "Manual": false, "Shard": "backup_pitr", - "RetryMax": 1, "Tags": [] }, "backup_pitr_xtrabackup": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/backup/pitr_xtrabackup", "-timeout", "30m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/backup/pitr_xtrabackup" + ], + "Args": [ + "-timeout", + "30m" + ], "Command": [], "Manual": false, "Shard": "backup_pitr_xtrabackup", - "RetryMax": 1, "Tags": [] }, "backup_pitr_mysqlshell": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/backup/pitr_mysqlshell", "-timeout", "30m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/backup/pitr_mysqlshell" + ], + "Args": [ + "-timeout", + "30m" + ], "Command": [], "Manual": false, "Shard": "backup_pitr_mysqlshell", - "RetryMax": 1, "Tags": [] }, "backup": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/backup/vtctlbackup", "-timeout", "30m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/backup/vtctlbackup" + ], + "Args": [ + "-timeout", + "30m" + ], "Command": [], "Manual": false, "Shard": "vtctlbackup_sharded_clustertest_heavy", - "RetryMax": 1, "Tags": [] }, "backup_mysqlctld": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/backup/mysqlctld", "-timeout", "30m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/backup/mysqlctld" + ], + "Args": [ + "-timeout", + "30m" + ], "Command": [], "Manual": false, "Shard": "21", - "RetryMax": 1, "Tags": [] }, "backup_s3": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/backup/s3", "-timeout", "30m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/backup/s3" + ], + "Args": [ + "-timeout", + "30m" + ], "Command": [], "Manual": false, "Shard": "21", - "RetryMax": 1, "Tags": [] }, "backup_only": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/backup/vtbackup", "-timeout", "20m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/backup/vtbackup" + ], + "Args": [ + "-timeout", + "20m" + ], "Command": [], "Manual": false, "Shard": "vtbackup", - "RetryMax": 1, - "Tags": ["upgrade_downgrade_backups"] + "Tags": [ + "upgrade_downgrade_backups" + ] }, "backup_xtrabackup": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/backup/xtrabackup", "-timeout", "30m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/backup/xtrabackup" + ], + "Args": [ + "-timeout", + "30m" + ], "Command": [], "Manual": false, "Shard": "xb_backup", - "RetryMax": 2, "Tags": [] }, "backup_xtrabackup_xbstream": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/backup/xtrabackupstream", "-run", "XtrabackupStream", "-timeout", "30m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/backup/xtrabackupstream" + ], + "Args": [ + "-run", + "XtrabackupStream", + "-timeout", + "30m" + ], "Command": [], "Manual": false, "Shard": "xb_backup", - "RetryMax": 1, "Tags": [] }, "backup_xtrabackup_xbstream_lz4": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/backup/xtrabackupstream", "-run", "XtrabackupStreamWithlz4Compression", "-timeout", "30m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/backup/xtrabackupstream" + ], + "Args": [ + "-run", + "XtrabackupStreamWithlz4Compression", + "-timeout", + "30m" + ], "Command": [], "Manual": false, "Shard": "xb_backup", - "RetryMax": 1, "Tags": [] }, "cellalias": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/cellalias"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/cellalias" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "13", - "RetryMax": 3, "Tags": [] }, "prepare_statement": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/preparestmt"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/preparestmt" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "12", - "RetryMax": 1, - "Tags": ["upgrade_downgrade_query_serving_queries"] + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ] }, "mysql_server": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/mysqlserver"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/mysqlserver" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "mysql_server_vault", - "RetryMax": 1, "Tags": [] }, "messaging": { "File": "messaging_test.go", - "Args": ["vitess.io/vitess/go/test/endtoend/messaging"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/messaging" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "12", - "RetryMax": 3, "Tags": [] }, "clustertest": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/clustertest"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/clustertest" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtctlbackup_sharded_clustertest_heavy", - "RetryMax": 1, "Tags": [] }, "encrypted_replication": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/encryption/encryptedreplication"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/encryption/encryptedreplication" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "12", - "RetryMax": 1, "Tags": [] }, "encrypted_transport": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/encryption/encryptedtransport"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/encryption/encryptedtransport" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "12", - "RetryMax": 1, "Tags": [] }, "keyspace": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/keyspace"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/keyspace" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "12", - "RetryMax": 1, "Tags": [ "site_test" ] }, "mysqlctl": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/mysqlctl"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/mysqlctl" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "12", - "RetryMax": 1, "Tags": [ "site_test" ] }, "mysqlctld": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/mysqlctld"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/mysqlctld" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "12", - "RetryMax": 1, "Tags": [ "site_test" ] }, "onlineddl_vrepl": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/onlineddl/vrepl", "-timeout", "30m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/onlineddl/vrepl" + ], + "Args": [ + "-timeout", + "30m" + ], "Command": [], "Manual": false, "Shard": "onlineddl_vrepl", - "RetryMax": 2, "Tags": [] }, "onlineddl_vrepl_stress": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/onlineddl/vrepl_stress", "-timeout", "30m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/onlineddl/vrepl_stress" + ], + "Args": [ + "-timeout", + "30m" + ], "Command": [], "Manual": false, "Shard": "onlineddl_vrepl_stress", - "RetryMax": 1, "Tags": [] }, "onlineddl_vrepl_suite": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/onlineddl/vrepl_suite", "-timeout", "30m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/onlineddl/vrepl_suite" + ], + "Args": [ + "-timeout", + "30m" + ], "Command": [], "Manual": false, "Shard": "onlineddl_vrepl_suite", - "RetryMax": 1, "Tags": [] }, "onlineddl_vrepl_stress_suite": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/onlineddl/vrepl_stress_suite", "-timeout", "30m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/onlineddl/vrepl_stress_suite" + ], + "Args": [ + "-timeout", + "30m" + ], "Command": [], "Manual": false, "Shard": "onlineddl_vrepl_stress_suite", - "RetryMax": 1, "Tags": [] }, "onlineddl_revert": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/onlineddl/revert", "-timeout", "30m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/onlineddl/revert" + ], + "Args": [ + "-timeout", + "30m" + ], "Command": [], "Manual": false, "Shard": "onlineddl_revert", - "RetryMax": 1, "Tags": [] }, "onlineddl_scheduler": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/onlineddl/scheduler", "-timeout", "30m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/onlineddl/scheduler" + ], + "Args": [ + "-timeout", + "30m" + ], "Command": [], "Manual": false, "Shard": "onlineddl_scheduler", - "RetryMax": 1, "Tags": [] }, "onlineddl_flow": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/onlineddl/flow", "-timeout", "30m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/onlineddl/flow" + ], + "Args": [ + "-timeout", + "30m" + ], "Command": [], "Manual": false, "Shard": "onlineddl_flow", - "RetryMax": 1, - "Tags": ["upgrade_downgrade_onlineddl_flow"] + "Tags": [ + "upgrade_downgrade_onlineddl_flow" + ] }, "schemadiff_vrepl": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/schemadiff/vrepl", "-timeout", "30m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/schemadiff/vrepl" + ], + "Args": [ + "-timeout", + "30m" + ], "Command": [], "Manual": false, "Shard": "schemadiff_vrepl", - "RetryMax": 1, "Tags": [] }, "recovery": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/recovery/unshardedrecovery"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/recovery/unshardedrecovery" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtctlbackup_sharded_clustertest_heavy", - "RetryMax": 1, "Tags": [] }, "emergencyreparent": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/reparent/emergencyreparent", "-timeout", "20m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/reparent/emergencyreparent" + ], + "Args": [ + "-timeout", + "20m" + ], "Command": [], "Manual": false, "Shard": "ers_prs_newfeatures_heavy", - "RetryMax": 1, - "Tags": ["upgrade_downgrade_reparent"] + "Tags": [ + "upgrade_downgrade_reparent" + ] }, "plannedreparent": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/reparent/plannedreparent", "-timeout", "20m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/reparent/plannedreparent" + ], + "Args": [ + "-timeout", + "20m" + ], "Command": [], "Manual": false, "Shard": "ers_prs_newfeatures_heavy", - "RetryMax": 1, - "Tags": ["upgrade_downgrade_reparent"] + "Tags": [ + "upgrade_downgrade_reparent" + ] }, "newfeatures": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/reparent/newfeaturetest"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/reparent/newfeaturetest" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "ers_prs_newfeatures_heavy", - "RetryMax": 1, - "Tags": [""] + "Tags": [ + "" + ] }, "sharded": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/sharded", "-timeout", "30m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/sharded" + ], + "Args": [ + "-timeout", + "30m" + ], "Command": [], "Manual": false, "Shard": "vtctlbackup_sharded_clustertest_heavy", - "RetryMax": 1, "Tags": [] }, "tabletgateway_buffer_reparent": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/tabletgateway/buffer/reparent"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/tabletgateway/buffer/reparent" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "13", - "RetryMax": 1, "Tags": [] }, "tabletgateway_buffer_reshard": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/tabletgateway/buffer/reshard"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/tabletgateway/buffer/reshard" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "13", - "RetryMax": 1, "Tags": [] }, "tabletgateway": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/tabletgateway"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/tabletgateway" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "15", - "RetryMax": 1, "Tags": [] }, "tabletmanager": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/tabletmanager"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/tabletmanager" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "18", - "RetryMax": 1, "Tags": [ "site_test" ] }, "tabletmanager_replication_manager": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/tabletmanager/replication_manager"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/tabletmanager/replication_manager" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "18", - "RetryMax": 1, "Tags": [] }, "tabletmanager_consul": { "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/tabletmanager" + ], "Args": [ - "vitess.io/vitess/go/test/endtoend/tabletmanager","--topo-flavor=consul" + "--topo-flavor=consul" ], "Command": [], "Manual": false, "Shard": "tabletmanager_consul", - "RetryMax": 1, "Tags": [ "site_test" ] }, "tabletmanager_throttler_topo": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/tabletmanager/throttler_topo"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/tabletmanager/throttler_topo" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "tabletmanager_throttler_topo", - "RetryMax": 1, "Tags": [ "site_test" ] }, "tabletmanager_tablegc": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/tabletmanager/tablegc"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/tabletmanager/tablegc" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "tabletmanager_tablegc", - "RetryMax": 2, "Tags": [ "site_test" ] }, "tabletmanager_zk2": { "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/tabletmanager" + ], "Args": [ - "vitess.io/vitess/go/test/endtoend/tabletmanager","--topo-flavor=zk2" + "--topo-flavor=zk2" ], "Command": [], "Manual": false, "Shard": "docker_cluster", - "RetryMax": 1, "Tags": [ "site_test" ] }, "upgrade": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/versionupgrade", "-keep-data", "-force-vtdataroot", "/tmp/vtdataroot/vtroot_10901", "-force-port-start", "vtctlbackup_sharded_clustertest_heavy900", "-force-base-tablet-uid", "vtctlbackup_sharded_clustertest_heavy90"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/versionupgrade" + ], + "Args": [ + "-keep-data", + "-force-vtdataroot", + "/tmp/vtdataroot/vtroot_10901", + "-force-port-start", + "vtctlbackup_sharded_clustertest_heavy900", + "-force-base-tablet-uid", + "vtctlbackup_sharded_clustertest_heavy90" + ], "Command": [], "Manual": false, "Shard": "28", - "RetryMax": 1, "Tags": [] }, "vtgate": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_general_heavy", - "RetryMax": 2, "Tags": [] }, "vtgate_connectiondrain": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/connectiondrain"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/connectiondrain" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_general_heavy", - "RetryMax": 2, "Tags": [] }, "vtgate_queries_derived": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/derived"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/derived" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_queries", - "RetryMax": 1, - "Tags": ["upgrade_downgrade_query_serving_queries"] + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ] }, "vtgate_queries_aggregation": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/aggregation"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/aggregation" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_queries", - "RetryMax": 2, - "Tags": ["upgrade_downgrade_query_serving_queries"] + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ] }, "vtgate_queries_foundrows": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/foundrows"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/foundrows" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_queries", - "RetryMax": 2, - "Tags": ["upgrade_downgrade_query_serving_queries"] + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ] }, "vtgate_queries_informationschema": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/informationschema"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/informationschema" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_queries", - "RetryMax": 2, - "Tags": ["upgrade_downgrade_query_serving_queries"] + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ] }, "vtgate_queries_misc": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/misc"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/misc" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_queries", - "RetryMax": 1, - "Tags": ["upgrade_downgrade_query_serving_queries"] + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ] }, "vtgate_queries_multi_query": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/multi_query"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/multi_query" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_queries", - "RetryMax": 1, - "Tags": ["upgrade_downgrade_query_serving_queries"] + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ] }, "vtgate_queries_timeout": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/timeout"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/timeout" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_queries", - "RetryMax": 1, - "Tags": ["upgrade_downgrade_query_serving_queries"] + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ] }, "vtgate_queries_normalize": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/normalize"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/normalize" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_queries", - "RetryMax": 2, - "Tags": ["upgrade_downgrade_query_serving_queries"] + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ] }, "vtgate_queries_no_scatter": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/no_scatter"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/no_scatter" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_queries", - "RetryMax": 1, - "Tags": ["upgrade_downgrade_query_serving_queries"] + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ] }, "vtgate_queries_orderby": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/orderby", "-timeout", "20m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/orderby" + ], + "Args": [ + "-timeout", + "20m" + ], "Command": [], "Manual": false, "Shard": "vtgate_queries", - "RetryMax": 2, - "Tags": ["upgrade_downgrade_query_serving_queries"] + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ] }, "vtgate_queries_tpch": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/tpch", "-timeout", "20m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/tpch" + ], + "Args": [ + "-timeout", + "20m" + ], "Command": [], "Manual": false, "Shard": "vtgate_queries", - "RetryMax": 2, - "Tags": ["upgrade_downgrade_query_serving_queries_2"] + "Tags": [ + "upgrade_downgrade_query_serving_queries_2" + ] }, "vtgate_queries_subquery": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/subquery", "-timeout", "20m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/subquery" + ], + "Args": [ + "-timeout", + "20m" + ], "Command": [], "Manual": false, "Shard": "vtgate_queries", - "RetryMax": 2, - "Tags": ["upgrade_downgrade_query_serving_queries_2"] + "Tags": [ + "upgrade_downgrade_query_serving_queries_2" + ] }, "vtgate_queries_union": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/union", "-timeout", "20m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/union" + ], + "Args": [ + "-timeout", + "20m" + ], "Command": [], "Manual": false, "Shard": "vtgate_queries", - "RetryMax": 2, - "Tags": ["upgrade_downgrade_query_serving_queries_2"] + "Tags": [ + "upgrade_downgrade_query_serving_queries_2" + ] }, "vtgate_queries_insert": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/dml"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/dml" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_queries", - "RetryMax": 2, - "Tags": ["upgrade_downgrade_query_serving_queries_2"] + "Tags": [ + "upgrade_downgrade_query_serving_queries_2" + ] }, "vtgate_queries_vexplain": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/vexplain"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/vexplain" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_queries", - "RetryMax": 2, - "Tags": ["upgrade_downgrade_query_serving_queries_2"] + "Tags": [ + "upgrade_downgrade_query_serving_queries_2" + ] }, "vtgate_queries_reference": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/reference"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/reference" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_queries", - "RetryMax": 1, - "Tags": ["upgrade_downgrade_query_serving_queries_2"] + "Tags": [ + "upgrade_downgrade_query_serving_queries_2" + ] }, "vtgate_queries_random": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/random"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/random" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_queries", - "RetryMax": 1, - "Tags": ["upgrade_downgrade_query_serving_queries_2"] + "Tags": [ + "upgrade_downgrade_query_serving_queries_2" + ] }, "vtgate_kill": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/kill"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/kill" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_queries", - "RetryMax": 1, - "Tags": ["upgrade_downgrade_query_serving_queries_2"] + "Tags": [ + "upgrade_downgrade_query_serving_queries_2" + ] }, "vtgate_concurrentdml": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/concurrentdml"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/concurrentdml" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_concurrentdml", - "RetryMax": 1, "Tags": [] }, "vtgate_schema": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/schema", "-timeout", "20m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/schema" + ], + "Args": [ + "-timeout", + "20m" + ], "Command": [], "Manual": false, "Shard": "vtgate_schema", - "RetryMax": 1, - "Tags": ["upgrade_downgrade_query_serving_schema"] + "Tags": [ + "upgrade_downgrade_query_serving_schema" + ] }, "vtgate_schematracker_loadkeyspace": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/schematracker/loadkeyspace"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/schematracker/loadkeyspace" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_schema_tracker", - "RetryMax": 1, "Tags": [] }, "vtgate_schematracker_restarttablet": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/schematracker/restarttablet"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/schematracker/restarttablet" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_schema_tracker", - "RetryMax": 1, "Tags": [] }, "vtgate_schematracker_sharded": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/schematracker/sharded", "-timeout", "20m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/schematracker/sharded" + ], + "Args": [ + "-timeout", + "20m" + ], "Command": [], "Manual": false, "Shard": "vtgate_schema_tracker", - "RetryMax": 1, - "Tags": ["upgrade_downgrade_query_serving_schema"] + "Tags": [ + "upgrade_downgrade_query_serving_schema" + ] }, "vtgate_schematracker_sharded_prs": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/schematracker/sharded_prs", "-timeout", "20m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/schematracker/sharded_prs" + ], + "Args": [ + "-timeout", + "20m" + ], "Command": [], "Manual": false, "Shard": "vtgate_schema_tracker", - "RetryMax": 1, - "Tags": ["upgrade_downgrade_query_serving_schema"] + "Tags": [ + "upgrade_downgrade_query_serving_schema" + ] }, "vtgate_schematracker_unsharded": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/schematracker/unsharded", "-timeout", "20m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/schematracker/unsharded" + ], + "Args": [ + "-timeout", + "20m" + ], "Command": [], "Manual": false, "Shard": "vtgate_schema_tracker", - "RetryMax": 1, - "Tags": ["upgrade_downgrade_query_serving_schema"] + "Tags": [ + "upgrade_downgrade_query_serving_schema" + ] }, "vtgate_schematracker_viewsdisabled": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/schematracker/viewsdisabled", "-timeout", "20m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/schematracker/viewsdisabled" + ], + "Args": [ + "-timeout", + "20m" + ], "Command": [], "Manual": false, "Shard": "vtgate_schema_tracker", - "RetryMax": 1, - "Tags": ["upgrade_downgrade_query_serving_schema"] + "Tags": [ + "upgrade_downgrade_query_serving_schema" + ] }, "vtgate_mysql80": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/mysql80"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/schematracker/multi_ks" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "mysql80", @@ -761,725 +1066,1021 @@ }, "vtgate_sequence": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/sequence"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/sequence" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_general_heavy", - "RetryMax": 1, "Tags": [] }, "vtgate_setstatement": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/reservedconn"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/reservedconn" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_reservedconn", - "RetryMax": 1, "Tags": [] }, "vtgate_reserved_conn1": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/reservedconn/reconnect1"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/reservedconn/reconnect1" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_reservedconn", - "RetryMax": 1, "Tags": [] }, "vtgate_reserved_conn2": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/reservedconn/reconnect2"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/reservedconn/reconnect2" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_reservedconn", - "RetryMax": 1, "Tags": [] }, "vtgate_reserved_conn3": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/reservedconn/reconnect3"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/reservedconn/reconnect3" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_reservedconn", - "RetryMax": 1, "Tags": [] }, "vtgate_reserved_conn4": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/reservedconn/reconnect4"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/reservedconn/reconnect4" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_reservedconn", - "RetryMax": 1, "Tags": [] }, "vtgate_tablet_healthcheck_cache": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/tablet_healthcheck_cache", "-timeout", "45m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/tablet_healthcheck_cache" + ], + "Args": [ + "-timeout", + "45m" + ], "Command": [], "Manual": false, "Shard": "vtgate_tablet_healthcheck_cache", - "RetryMax": 1, "Tags": [] }, "vtgate_transaction": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/transaction"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/transaction" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_transaction", - "RetryMax": 1, "Tags": [] }, "vtgate_transaction_restart": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/transaction/restart"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/transaction/restart" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_transaction", - "RetryMax": 1, "Tags": [] }, "vtgate_transaction_rollback": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/transaction/rollback"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/transaction/rollback" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_transaction", - "RetryMax": 1, "Tags": [] }, "vtgate_transaction_single": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/transaction/single"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/transaction/single" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_transaction", - "RetryMax": 1, "Tags": [] }, "vtgate_transaction_twopc": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/transaction/twopc"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/transaction/twopc" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_transaction", - "RetryMax": 1, "Tags": [] }, "vtgate_transaction_twopc_metric": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/transaction/twopc/metric"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/transaction/twopc/metric" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_transaction", - "RetryMax": 1, "Tags": [] }, "vtgate_transaction_twopc_stress": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/transaction/twopc/stress"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/transaction/twopc/stress" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_transaction", - "RetryMax": 1, "Tags": [] }, "vtgate_transaction_twopc_fuzz": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/transaction/twopc/fuzz"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/transaction/twopc/fuzz" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_transaction", - "RetryMax": 1, "Tags": [] }, "vtgate_transaction_partial_exec": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/partialfailure"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/partialfailure" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_transaction", - "RetryMax": 1, "Tags": [] }, "vtgate_plantests": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/plan_tests"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/plan_tests" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_plantests", - "RetryMax": 1, "Tags": [] }, "vtgate_unsharded": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/unsharded"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/unsharded" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_unsharded", - "RetryMax": 1, "Tags": [] }, "vtgate_vschema": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/vschema", "-timeout", "20m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/vschema" + ], + "Args": [ + "-timeout", + "20m" + ], "Command": [], "Manual": false, "Shard": "vtgate_vschema", - "RetryMax": 1, - "Tags": ["upgrade_downgrade_query_serving_schema"] + "Tags": [ + "upgrade_downgrade_query_serving_schema" + ] }, "vtgate_readafterwrite": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/readafterwrite"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/readafterwrite" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_readafterwrite", - "RetryMax": 1, "Tags": [] }, "vtgate_dbddlplugin": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/createdb_plugin"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/createdb_plugin" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_general_heavy", - "RetryMax": 1, "Tags": [] }, "vtgate_foreignkey": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/foreignkey"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/foreignkey" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_foreignkey_stress", - "RetryMax": 1, "Tags": [] }, "vtgate_foreignkey_routing": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/foreignkey/routing"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/foreignkey/routing" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_foreignkey_stress", - "RetryMax": 1, "Tags": [] }, "vtgate_foreignkey_stress": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/foreignkey/stress", "-timeout", "30m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/foreignkey/stress" + ], + "Args": [ + "-timeout", + "30m" + ], "Command": [], "Manual": false, "Shard": "vtgate_foreignkey_stress", - "RetryMax": 1, "Tags": [] }, "vtgate_gen4": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/gen4"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/gen4" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_gen4", - "RetryMax": 2, "Tags": [] }, "vtgate_godriver": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/godriver"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/godriver" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_godriver", - "RetryMax": 1, "Tags": [] }, "vtgate_watchkeyspace": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/keyspace_watches"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/keyspace_watches" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_topo", - "RetryMax": 1, "Tags": [] }, "vtgate_grpc_api": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/grpc_api"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/grpc_api" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_general_heavy", - "RetryMax": 1, "Tags": [] }, "topo_zk2": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/topotest/zk2", "--topo-flavor=zk2"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/topotest/zk2" + ], + "Args": [ + "--topo-flavor=zk2" + ], "Command": [], "Manual": false, "Shard": "docker_cluster", - "RetryMax": 1, "Tags": [] }, "topo_consul": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/topotest/consul", "--topo-flavor=consul"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/topotest/consul" + ], + "Args": [ + "--topo-flavor=consul" + ], "Command": [], "Manual": false, "Shard": "vtgate_topo_consul", - "RetryMax": 1, "Tags": [] }, "topo_etcd2": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/topotest/etcd2"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/topotest/etcd2" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_topo_etcd", - "RetryMax": 1, "Tags": [] }, "errs_as_warns": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/errors_as_warnings"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/errors_as_warnings" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_general_heavy", - "RetryMax": 1, "Tags": [] }, "consolidator": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/consolidator"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/consolidator" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_general_heavy", - "RetryMax": 1, "Tags": [] }, "prefixfanout": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/prefixfanout"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/prefixfanout" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_vindex_heavy", - "RetryMax": 1, "Tags": [] }, "vindex_bindvars": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/vindex_bindvars"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/vindex_bindvars" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_vindex_heavy", - "RetryMax": 2, "Tags": [] }, "vindex_secondary": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/sec_vind"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/sec_vind" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_vindex_heavy", - "RetryMax": 2, "Tags": [] }, "vttest_sample": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtcombo"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtcombo" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "docker_cluster", - "RetryMax": 1, "Tags": [] }, "xb_recovery": { "File": "recovery_test.go", - "Args": ["vitess.io/vitess/go/test/endtoend/recovery/xtrabackup"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/recovery/xtrabackup" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "xb_recovery", - "RetryMax": 1, "Tags": [] }, "vreplication_materialize": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "Materialize"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "Materialize" + ], "Command": [], "Manual": false, "Shard": "vreplication_partial_movetables_and_materialize", - "RetryMax": 0, "Tags": [] }, "vreplication_vtctldclient_materialize": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestMaterializeVtctldClient"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestMaterializeVtctldClient" + ], "Command": [], "Manual": false, "Shard": "vreplication_partial_movetables_and_materialize", - "RetryMax": 0, "Tags": [] }, "vreplication_cellalias": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "CellAlias"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "CellAlias" + ], "Command": [], "Manual": false, "Shard": "vreplication_cellalias", - "RetryMax": 0, "Tags": [] }, "vreplication_movetables_ignore_source_keyspace": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestMoveTablesIgnoreSourceKeyspace"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestMoveTablesIgnoreSourceKeyspace" + ], "Command": [], "Manual": false, "Shard": "vreplication_cellalias", - "RetryMax": 0, "Tags": [] }, "vreplication_multi_tenant": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication","-run", "MultiTenant"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "MultiTenant" + ], "Command": [], "Manual": false, "Shard": "vreplication_multi_tenant", - "RetryMax": 0, "Tags": [] }, "vreplication_partial_movetables_basic": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "PartialMoveTablesBasic"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "PartialMoveTablesBasic" + ], "Command": [], "Manual": false, "Shard": "vreplication_partial_movetables_and_materialize", - "RetryMax": 0, "Tags": [] }, "vdiff_multiple_movetables_test.go": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestMultipleConcurrentVDiffs"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestMultipleConcurrentVDiffs" + ], "Command": [], "Manual": false, "Shard": "vreplication_partial_movetables_and_materialize", - "RetryMax": 0, "Tags": [] }, "vreplication_movetables_buffering": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestMoveTablesBuffering"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestMoveTablesBuffering" + ], "Command": [], "Manual": false, "Shard": "vreplication_cellalias", - "RetryMax": 0, "Tags": [] }, "vreplication_onlineddl_vdiff": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestOnlineDDLVDiff"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestOnlineDDLVDiff" + ], "Command": [], "Manual": false, "Shard": "vreplication_cellalias", - "RetryMax": 2, "Tags": [] }, "vreplication_vschema_load": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestVSchemaChangesUnderLoad"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestVSchemaChangesUnderLoad" + ], "Command": [], "Manual": false, "Shard": "vreplication_cellalias", - "RetryMax": 2, "Tags": [] }, "sidecardb": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestSidecarDB"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestSidecarDB" + ], "Command": [], "Manual": false, "Shard": "schemadiff_vrepl", - "RetryMax": 2, "Tags": [] }, "vreplication_basic": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestBasicVreplicationWorkflow", "-timeout", "20m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestBasicVreplicationWorkflow", + "-timeout", + "20m" + ], "Command": [], "Manual": false, "Shard": "vreplication_basic", - "RetryMax": 1, "Tags": [] }, "vreplication_copy_parallel": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestVreplicationCopyParallel", "-timeout", "20m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestVreplicationCopyParallel", + "-timeout", + "20m" + ], "Command": [], "Manual": false, "Shard": "vreplication_copy_parallel", - "RetryMax": 1, "Tags": [] }, "vreplication_partial_movetables_sequences": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestPartialMoveTablesWithSequences"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestPartialMoveTablesWithSequences" + ], "Command": [], "Manual": false, "Shard": "vreplication_partial_movetables_and_materialize", - "RetryMax": 1, "Tags": [] }, "vreplication_sequence_reset_on_switch_traffic": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestSequenceResetOnSwitchTraffic"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestSequenceResetOnSwitchTraffic" + ], "Command": [], "Manual": false, "Shard": "vreplication_partial_movetables_and_materialize", - "RetryMax": 1, "Tags": [] }, "vstream_flush_binlog": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestVStreamFlushBinlog"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestVStreamFlushBinlog" + ], "Command": [], "Manual": false, "Shard": "vreplication_basic", - "RetryMax": 1, "Tags": [] }, "multi_vstreams_keyspace_reshard": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestMultiVStreamsKeyspaceReshard", "-timeout", "15m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestMultiVStreamsKeyspaceReshard", + "-timeout", + "15m" + ], "Command": [], "Manual": false, "Shard": "vstream", - "RetryMax": 1, "Tags": [] }, "vstream_failover": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "VStreamFailover"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "VStreamFailover" + ], "Command": [], "Manual": false, "Shard": "vstream", - "RetryMax": 3, "Tags": [] }, "vstream_stoponreshard_true": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "VStreamStopOnReshardTrue"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "VStreamStopOnReshardTrue" + ], "Command": [], "Manual": false, "Shard": "vstream", - "RetryMax": 1, "Tags": [] }, "vstream_stoponreshard_false": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "VStreamStopOnReshardFalse"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "VStreamStopOnReshardFalse" + ], "Command": [], "Manual": false, "Shard": "vstream", - "RetryMax": 1, "Tags": [] }, "vstream_with_keyspaces_to_watch": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "VStreamWithKeyspacesToWatch"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "VStreamWithKeyspacesToWatch" + ], "Command": [], "Manual": false, "Shard": "vstream", - "RetryMax": 1, "Tags": [] }, "vtop_example": { "File": "", + "Packages": [], "Args": [], "Command": [ "test/vtop_example.sh" ], "Manual": false, "Shard": "", - "RetryMax": 1, "Tags": [] }, "vtorc_primary_failure": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtorc/primaryfailure"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtorc/primaryfailure" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtorc", - "RetryMax": 3, "Tags": [] }, "vtorc_api": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtorc/api"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtorc/api" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtorc", - "RetryMax": 3, "Tags": [] }, "vtorc_general": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtorc/general"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtorc/general" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtorc", - "RetryMax": 3, "Tags": [] }, "vtorc_readtopologyinstance": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtorc/readtopologyinstance"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtorc/readtopologyinstance" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtorc", - "RetryMax": 3, "Tags": [] }, "vault": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vault"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vault" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "mysql_server_vault", - "RetryMax": 1, "Tags": [] }, "vreplication_v2": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestBasicV2Workflows", "-timeout", "30m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestBasicV2Workflows", + "-timeout", + "30m" + ], "Command": [], "Manual": false, "Shard": "vreplication_v2", - "RetryMax": 1, "Tags": [] }, "global_routing": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestGlobalRouting", "-timeout", "30m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestGlobalRouting", + "-timeout", + "30m" + ], "Command": [], "Manual": false, "Shard": "vreplication_v2", - "RetryMax": 1, "Tags": [] }, "vreplication_fk": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestFKWorkflow"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestFKWorkflow" + ], "Command": [], "Manual": false, "Shard": "vreplication_cellalias", - "RetryMax": 1, "Tags": [] }, "vreplication_foreign_key_stress": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestFKExt"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestFKExt" + ], "Command": [], "Manual": false, "Shard": "vreplication_foreign_key_stress", - "RetryMax": 1, "Tags": [] }, "vreplication_across_db_versions": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestV2WorkflowsAcrossDBVersions", "-timeout", "20m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestV2WorkflowsAcrossDBVersions", + "-timeout", + "20m" + ], "Command": [], "Manual": false, "Shard": "vreplication_across_db_versions", - "RetryMax": 1, "Tags": [] }, "vreplication_mariadb_to_mysql": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestMoveTablesMariaDBToMySQL", "-timeout", "20m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestMoveTablesMariaDBToMySQL", + "-timeout", + "20m" + ], "Command": [], "Manual": false, "Shard": "vreplication_mariadb_to_mysql", - "RetryMax": 1, "Tags": [] }, "vreplication_migrate": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestMigrate", "-timeout", "30m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestMigrate", + "-timeout", + "30m" + ], "Command": [], "Manual": false, "Shard": "vreplication_migrate", - "RetryMax": 1, "Tags": [] }, "vdiff2": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestVDiff2", "-timeout", "30m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestVDiff2", + "-timeout", + "30m" + ], "Command": [], "Manual": false, "Shard": "vreplication_vdiff2", - "RetryMax": 1, "Tags": [] }, "vreplication_vtctldclient_cli": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestVtctldclientCLI", "-timeout", "20m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestVtctldclientCLI", + "-timeout", + "20m" + ], "Command": [], "Manual": false, "Shard": "vreplication_vtctldclient_movetables_tz", - "RetryMax": 1, "Tags": [] }, "vreplication_movetables_tz": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestMoveTablesTZ"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestMoveTablesTZ" + ], "Command": [], "Manual": false, "Shard": "vreplication_vtctldclient_movetables_tz", - "RetryMax": 1, "Tags": [] }, "loopkup_index": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestLookupIndex"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestLookupIndex" + ], "Command": [], "Manual": false, "Shard": "vreplication_vtctldclient_movetables_tz", - "RetryMax": 1, "Tags": [] }, "vtadmin": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtadmin"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtadmin" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "15", - "RetryMax": 1, "Tags": [] }, "topo_connection_cache": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/topoconncache", "-run", "TestVtctldListAllTablets"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/topoconncache" + ], + "Args": [ + "-run", + "TestVtctldListAllTablets" + ], "Command": [], "Manual": false, "Shard": "topo_connection_cache", - "RetryMax": 1, "Tags": [] }, "prscomplex": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/reparent/prscomplex"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/reparent/prscomplex" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vttablet_prscomplex", - "RetryMax": 1, - "Tags": [""] + "Tags": [ + "" + ] }, "prssettingspool": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/reparent/prssettingspool"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/reparent/prssettingspool" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vttablet_prscomplex", - "RetryMax": 1, - "Tags": [""] + "Tags": [ + "" + ] } } } diff --git a/test/config_partial_keyspace.json b/test/config_partial_keyspace.json index bcd445d34bc..2c3570aad76 100644 --- a/test/config_partial_keyspace.json +++ b/test/config_partial_keyspace.json @@ -2,146 +2,193 @@ "Tests": { "vtgate_partial_keyspace": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_partial_keyspace", - "RetryMax": 2, "Tags": [] }, "vtgate_sequence_partial_keyspace": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/sequence"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/sequence" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_partial_keyspace", - "RetryMax": 1, "Tags": [] }, "errs_as_warns_partial_keyspace": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/errors_as_warnings"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/errors_as_warnings" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_partial_keyspace", - "RetryMax": 1, "Tags": [] }, "vtgate_transaction_partial_keyspace": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/transaction"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/transaction" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_partial_keyspace", - "RetryMax": 1, "Tags": [] }, "vtgate_transaction_rollback_partial_keyspace": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/transaction/rollback"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/transaction/rollback" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_partial_keyspace", - "RetryMax": 1, "Tags": [] }, "vtgate_transaction_single_partial_keyspace": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/transaction/single"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/transaction/single" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_partial_keyspace", - "RetryMax": 1, "Tags": [] }, "vtgate_transaction_partial_exec_partial_keyspace": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/partialfailure"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/partialfailure" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_partial_keyspace", - "RetryMax": 1, "Tags": [] }, "vtgate_queries_aggregation_partial_keyspace": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/aggregation"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/aggregation" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_partial_keyspace", - "RetryMax": 2, "Tags": [] }, "vtgate_queries_foundrows_partial_keyspace": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/foundrows"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/foundrows" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_partial_keyspace", - "RetryMax": 2, "Tags": [] }, "vtgate_queries_informationschema_partial_keyspace": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/informationschema"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/informationschema" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_partial_keyspace", - "RetryMax": 2, "Tags": [] }, "vtgate_queries_misc_partial_keyspace": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/misc"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/misc" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_partial_keyspace", - "RetryMax": 1, "Tags": [] }, "vtgate_queries_normalize_partial_keyspace": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/normalize"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/normalize" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_partial_keyspace", - "RetryMax": 2, "Tags": [] }, "vtgate_queries_orderby_partial_keyspace": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/orderby", "-timeout", "20m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/orderby" + ], + "Args": [ + "-timeout", + "20m" + ], "Command": [], "Manual": false, "Shard": "vtgate_partial_keyspace", - "RetryMax": 2, - "Tags": ["upgrade_downgrade_query_serving_queries"] + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ] }, "vtgate_queries_subquery_partial_keyspace": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/subquery", "-timeout", "20m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/subquery" + ], + "Args": [ + "-timeout", + "20m" + ], "Command": [], "Manual": false, "Shard": "vtgate_partial_keyspace", - "RetryMax": 2, - "Tags": ["upgrade_downgrade_query_serving_queries"] + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ] }, "vtgate_queries_union_partial_keyspace": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/union", "-timeout", "20m"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/union" + ], + "Args": [ + "-timeout", + "20m" + ], "Command": [], "Manual": false, "Shard": "vtgate_partial_keyspace", - "RetryMax": 2, - "Tags": ["upgrade_downgrade_query_serving_queries"] + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ] }, "vtgate_queries_insert_partial_keyspace": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/queries/dml"], + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/dml" + ], + "Args": [], "Command": [], "Manual": false, "Shard": "vtgate_partial_keyspace", - "RetryMax": 2, "Tags": [] } } diff --git a/test/templates/cluster_endtoend_test.tpl b/test/templates/cluster_endtoend_test.tpl index ac6a1611919..0a46fbe90de 100644 --- a/test/templates/cluster_endtoend_test.tpl +++ b/test/templates/cluster_endtoend_test.tpl @@ -140,8 +140,6 @@ jobs: go mod download - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD {{if .NeedsMinio }} - name: Install Minio @@ -217,8 +215,7 @@ jobs: # Some of these tests require specific locales to be installed. # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker={{if .Docker}}true -flavor={{.Platform}}{{else}}false{{end}} -follow -shard {{.Shard}}{{if .PartialKeyspace}} -partial-keyspace=true {{end}}{{if .BuildTag}} -build-tag={{.BuildTag}} {{end}} | tee -a output.txt | go-junit-report -set-exit-code > report.xml + go run test.go -docker={{if .Docker}}true -flavor={{.Platform}}{{else}}false{{end}} -follow -shard {{.Shard}}{{if .PartialKeyspace}} -partial-keyspace=true {{end}}{{if .BuildTag}} -build-tag={{.BuildTag}} {{end}} - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() @@ -226,15 +223,9 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.end_to_end == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: - paths: "report.xml" + paths: "_test/junit/*.xml" show: "fail" diff --git a/test/templates/cluster_endtoend_test_docker.tpl b/test/templates/cluster_endtoend_test_docker.tpl index 6e7d8cf061f..94f2e7cd2c5 100644 --- a/test/templates/cluster_endtoend_test_docker.tpl +++ b/test/templates/cluster_endtoend_test_docker.tpl @@ -79,3 +79,10 @@ jobs: export VTDATAROOT="/tmp/" go run test.go -docker=true --follow -shard {{.Shard}} + + - name: Test Summary + if: steps.changes.outputs.end_to_end == 'true' && !cancelled() + uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 + with: + paths: "_test/junit/*.xml" + show: "fail" diff --git a/tools/e2e_go_test.sh b/tools/e2e_go_test.sh index bc4964ffb12..c519b5589df 100755 --- a/tools/e2e_go_test.sh +++ b/tools/e2e_go_test.sh @@ -1,4 +1,25 @@ #!/bin/bash + source build.env -echo "running tests for " "$@" -go test -v "$@" -alsologtostderr -count=1 \ No newline at end of file + +echo "running tests for $PACKAGES" + +if [[ -z "$PACKAGES" ]]; then + echo "ERROR: PACKAGES is empty" + exit 1 +fi + +GOTESTSUM_ARGS=( + --format github-actions + --rerun-fails=3 + --rerun-fails-max-failures=10 + --rerun-fails-run-root-test + --format-hide-empty-pkg + --hide-summary=skipped +) + +if [[ -n "$JUNIT_OUTPUT" ]]; then + GOTESTSUM_ARGS+=("--junitfile" "$JUNIT_OUTPUT") +fi + +go tool gotestsum "${GOTESTSUM_ARGS[@]}" --packages "$PACKAGES" -- -v -count=1 "$@" -args -alsologtostderr From 1132e9f102e3ddaaffa4e6296f4d2f3d70cea1af Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Mon, 2 Feb 2026 12:17:51 +0100 Subject: [PATCH 039/112] [release-22.0] evalengine: make `JSON_EXTRACT` work with non-static arguments (#19035) (#19253) Signed-off-by: Arthur Schreiber Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- go/vt/vtgate/evalengine/compiler_asm.go | 82 +++++++++++++++---- go/vt/vtgate/evalengine/fn_json.go | 56 ++++++++++--- .../evalengine/integration/fuzz_test.go | 1 + go/vt/vtgate/evalengine/testcases/cases.go | 59 ++++++++++++- 4 files changed, 164 insertions(+), 34 deletions(-) diff --git a/go/vt/vtgate/evalengine/compiler_asm.go b/go/vt/vtgate/evalengine/compiler_asm.go index d13d22e76cc..b24bbce68ed 100644 --- a/go/vt/vtgate/evalengine/compiler_asm.go +++ b/go/vt/vtgate/evalengine/compiler_asm.go @@ -47,7 +47,6 @@ import ( "vitess.io/vitess/go/mysql/hex" "vitess.io/vitess/go/mysql/icuregex" "vitess.io/vitess/go/mysql/json" - "vitess.io/vitess/go/slice" "vitess.io/vitess/go/sqltypes" querypb "vitess.io/vitess/go/vt/proto/query" "vitess.io/vitess/go/vt/proto/vtrpc" @@ -2215,40 +2214,89 @@ func (asm *assembler) Fn_JSON_CONTAINS_PATH(match jsonMatch, paths []*json.Path) } } -func (asm *assembler) Fn_JSON_EXTRACT0(jp []*json.Path) { - multi := len(jp) > 1 || slice.Any(jp, func(path *json.Path) bool { return path.ContainsWildcards() }) +type staticPath struct { + p *json.Path + err error +} - if multi { - asm.emit(func(env *ExpressionEnv) int { +func (asm *assembler) Fn_JSON_EXTRACT(args int, staticPaths []staticPath) { + asm.adjustStack(-args) + asm.emit(func(env *ExpressionEnv) int { + paths := make([]*json.Path, 0, args) + + multi := args > 1 + + doct := env.vm.stack[env.vm.sp-(args+1)].(*evalJSON) + + for i := args; i > 0; i-- { + arg := env.vm.stack[env.vm.sp-i] + + if arg == nil { + env.vm.sp -= args + env.vm.stack[env.vm.sp-1] = nil + return 1 + } + + staticPath := staticPaths[args-i] + if staticPath.err != nil { + env.vm.err = staticPath.err + return 1 + } + + var path *json.Path + if staticPath.p != nil { + path = staticPath.p + } else { + pathBytes, err := evalToVarchar(arg, collations.CollationUtf8mb4ID, true) + if err != nil { + env.vm.err = err + return 1 + } + + path, err = intoJSONPath(pathBytes) + if err != nil { + env.vm.err = err + return 1 + } + } + + if !multi { + multi = path.ContainsWildcards() + } + + paths = append(paths, path) + } + + env.vm.sp -= args + + if multi { matches := make([]*json.Value, 0, 4) - arg := env.vm.stack[env.vm.sp-1].(*evalJSON) - for _, jp := range jp { - jp.Match(arg, true, func(value *json.Value) { + for _, jp := range paths { + jp.Match(doct, true, func(value *json.Value) { matches = append(matches, value) }) } + if len(matches) == 0 { env.vm.stack[env.vm.sp-1] = nil } else { env.vm.stack[env.vm.sp-1] = json.NewArray(matches) } - return 1 - }, "FN JSON_EXTRACT, SP-1, [static]") - } else { - asm.emit(func(env *ExpressionEnv) int { + } else { var match *json.Value - arg := env.vm.stack[env.vm.sp-1].(*evalJSON) - jp[0].Match(arg, true, func(value *json.Value) { + paths[0].Match(doct, true, func(value *json.Value) { match = value }) + if match == nil { env.vm.stack[env.vm.sp-1] = nil } else { env.vm.stack[env.vm.sp-1] = match } - return 1 - }, "FN JSON_EXTRACT, SP-1, [static]") - } + } + + return 1 + }, "FN JSON_EXTRACT, SP-1, ..., SP-N") } func (asm *assembler) Fn_JSON_KEYS(jp *json.Path) { diff --git a/go/vt/vtgate/evalengine/fn_json.go b/go/vt/vtgate/evalengine/fn_json.go index 54038e28339..eabe2ee8351 100644 --- a/go/vt/vtgate/evalengine/fn_json.go +++ b/go/vt/vtgate/evalengine/fn_json.go @@ -89,7 +89,7 @@ func (call *builtinJSONExtract) eval(env *ExpressionEnv) (eval, error) { } func builtin_JSON_EXTRACT(doc *json.Value, paths []eval) (eval, error) { - matches := make([]*json.Value, 0, 4) + matches := make([]*json.Value, 0, len(paths)) multi := len(paths) > 1 for _, p := range paths { @@ -125,27 +125,57 @@ func (call *builtinJSONExtract) compile(c *compiler) (ctype, error) { return ctype{}, err } - if slice.All(call.Arguments[1:], func(expr IR) bool { return expr.constant() }) { - paths := make([]*json.Path, 0, len(call.Arguments[1:])) + // Handle `NULL` arguments + nullable := doct.nullable() + skip := c.compileNullCheck1(doct) - for _, arg := range call.Arguments[1:] { - jp, err := c.jsonExtractPath(arg) - if err != nil { - return ctype{}, err - } - paths = append(paths, jp) + // TODO: `*compiler.compileParseJSON` should handle `sqltypes.Null`` properly but + // we'll handle it here until all call sites are fixed. + var jt ctype + if doct.Type != sqltypes.Null { + jt, err = c.compileParseJSON("JSON_EXTRACT", doct, 1) + if err != nil { + return ctype{}, err } + } else { + jt = ctype{Type: sqltypes.Null, Flag: flagNull | flagNullable, Col: collationNull} + } + + staticPaths := make([]staticPath, 0, len(call.Arguments[1:])) - jt, err := c.compileParseJSON("JSON_EXTRACT", doct, 1) + for _, arg := range call.Arguments[1:] { + argType, err := arg.compile(c) if err != nil { return ctype{}, err } - c.asm.Fn_JSON_EXTRACT0(paths) - return jt, nil + if !nullable { + nullable = argType.nullable() + } + + if arg.constant() { + staticEnv := EmptyExpressionEnv(c.env) + arg, err = simplifyExpr(staticEnv, arg) + if err != nil { + return ctype{}, err + } + + p, err := c.jsonExtractPath(arg) + staticPaths = append(staticPaths, staticPath{p, err}) + } else { + staticPaths = append(staticPaths, staticPath{nil, nil}) + } } - return ctype{}, c.unsupported(call) + c.asm.Fn_JSON_EXTRACT(len(call.Arguments[1:]), staticPaths) + c.asm.jumpDestination(skip) + + if nullable { + // If any argument is nullable, the result is nullable too + jt.Flag |= flagNullable + } + + return jt, nil } func (call *builtinJSONUnquote) eval(env *ExpressionEnv) (eval, error) { diff --git a/go/vt/vtgate/evalengine/integration/fuzz_test.go b/go/vt/vtgate/evalengine/integration/fuzz_test.go index a16f6164b35..7c95870991f 100644 --- a/go/vt/vtgate/evalengine/integration/fuzz_test.go +++ b/go/vt/vtgate/evalengine/integration/fuzz_test.go @@ -102,6 +102,7 @@ var ( regexp.MustCompile(`Illegal argument to a regular expression`), regexp.MustCompile(`Incorrect arguments to regexp_substr`), regexp.MustCompile(`Incorrect arguments to regexp_replace`), + regexp.MustCompile(`Invalid JSON path expression\. The error is around character position (\d+)\.`), } ) diff --git a/go/vt/vtgate/evalengine/testcases/cases.go b/go/vt/vtgate/evalengine/testcases/cases.go index 1f34e6bfe0c..5b4a83a61c4 100644 --- a/go/vt/vtgate/evalengine/testcases/cases.go +++ b/go/vt/vtgate/evalengine/testcases/cases.go @@ -30,7 +30,9 @@ import ( var Cases = []TestCase{ {Run: JSONExtract, Schema: JSONExtract_Schema}, - {Run: JSONPathOperations}, + {Run: FnJSONKeys}, + {Run: FnJSONExtract}, + {Run: FnJSONContainsPath}, {Run: JSONArray}, {Run: JSONObject}, {Run: CharsetConversionOperators}, @@ -176,18 +178,67 @@ var Cases = []TestCase{ {Run: RegexpReplace}, } -func JSONPathOperations(yield Query) { +func FnJSONKeys(yield Query) { for _, obj := range inputJSONObjects { yield(fmt.Sprintf("JSON_KEYS('%s')", obj), nil, false) + for _, path1 := range inputJSONPaths { + yield(fmt.Sprintf("JSON_KEYS('%s', '%s')", obj, path1), nil, false) + } + } +} + +func FnJSONExtract(yield Query) { + for _, obj := range inputJSONObjects { for _, path1 := range inputJSONPaths { yield(fmt.Sprintf("JSON_EXTRACT('%s', '%s')", obj, path1), nil, false) + + for _, path2 := range inputJSONPaths { + yield(fmt.Sprintf("JSON_EXTRACT('%s', '%s', '%s')", obj, path1, path2), nil, false) + } + } + } + + yield(`JSON_EXTRACT('{"a": 1}', '$.a')`, nil, false) + yield(`JSON_EXTRACT('{"a": 1}', '$.*')`, nil, false) + yield(`JSON_EXTRACT('[1, 2, 3]', '$[0 to 2]')`, nil, false) + yield(`JSON_EXTRACT('{"a": 1, "b": 2}', '$.a', '$.b')`, nil, false) + yield(`JSON_EXTRACT('{"a": 1}', '$.a', '$.z')`, nil, false) + + yield(`JSON_EXTRACT(CONCAT('{', '"a"', ':', ' ', '1', '}'), '$.a')`, nil, false) + yield(`JSON_EXTRACT('{"a": 1}', CONCAT('$', '.', 'a'))`, nil, false) + + yield(`JSON_EXTRACT(NULL, '$.a')`, nil, false) + yield(`JSON_EXTRACT(NULL, NULL)`, nil, false) + + yield(`JSON_EXTRACT('{"a": 1}', NULL)`, nil, false) + yield(`JSON_EXTRACT('{"a": 1}', '$.a', NULL)`, nil, false) + yield(`JSON_EXTRACT('{"a": 1}', NULL, '$.a')`, nil, false) + + yield(`JSON_EXTRACT('{"a": 1}', '$.b')`, nil, false) + yield(`JSON_EXTRACT('{"a": 1}', '$.b', '$.c')`, nil, false) + yield(`JSON_EXTRACT('[1,2,3]', '$[10]')`, nil, false) + + yield(`JSON_EXTRACT('{invalid}', '$.a')`, nil, false) + yield(`JSON_EXTRACT('not json', '$.a')`, nil, false) + yield(`JSON_EXTRACT('', '$.a')`, nil, false) + yield(`JSON_EXTRACT('{invalid}', NULL)`, nil, false) + + yield(`JSON_EXTRACT('{"a": 1}', '$.b[ 1 ].')`, nil, false) + + yield(`JSON_EXTRACT(NULL, 'invalid-path')`, nil, false) + yield(`JSON_EXTRACT('{"a": 1}', NULL, 'invalid-path')`, nil, false) + yield(`JSON_EXTRACT('{"a": 1}', 'invalid-path', NULL)`, nil, false) + yield(`JSON_EXTRACT('{"a": 1}', '$.a', 'invalid')`, nil, false) +} + +func FnJSONContainsPath(yield Query) { + for _, obj := range inputJSONObjects { + for _, path1 := range inputJSONPaths { yield(fmt.Sprintf("JSON_CONTAINS_PATH('%s', 'one', '%s')", obj, path1), nil, false) yield(fmt.Sprintf("JSON_CONTAINS_PATH('%s', 'all', '%s')", obj, path1), nil, false) - yield(fmt.Sprintf("JSON_KEYS('%s', '%s')", obj, path1), nil, false) for _, path2 := range inputJSONPaths { - yield(fmt.Sprintf("JSON_EXTRACT('%s', '%s', '%s')", obj, path1, path2), nil, false) yield(fmt.Sprintf("JSON_CONTAINS_PATH('%s', 'one', '%s', '%s')", obj, path1, path2), nil, false) yield(fmt.Sprintf("JSON_CONTAINS_PATH('%s', 'all', '%s', '%s')", obj, path1, path2), nil, false) } From 6d369fbae0056a68fe0b5e00a63e60aeb69b6188 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 02:02:44 +0000 Subject: [PATCH 040/112] [release-22.0] Escape control bytes in JSON strings (#19270) (#19274) Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- go/mysql/json/marshal_test.go | 30 +++++++++++++++++++++ go/mysql/json/parser.go | 51 +++++++++++++++++++++++++++++++++-- 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/go/mysql/json/marshal_test.go b/go/mysql/json/marshal_test.go index 9329c3cd49a..d59f15a4892 100644 --- a/go/mysql/json/marshal_test.go +++ b/go/mysql/json/marshal_test.go @@ -20,6 +20,8 @@ import ( "testing" "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/sqltypes" ) func TestMarshalSQLTo(t *testing.T) { @@ -55,3 +57,31 @@ func TestMarshalSQLTo(t *testing.T) { }) } } + +// TestMarshalSQLValuePreservesControlByte verifies that JSON control bytes +// are preserved when marshaled into SQL. +func TestMarshalSQLValuePreservesControlByte(t *testing.T) { + raw := "Foo Bar" + string([]byte{26}) + "a" + + val := NewString(raw) + + got, err := MarshalSQLValue(val.MarshalTo(nil)) + require.NoError(t, err) + + expected := "CAST(JSON_QUOTE(_utf8mb4" + sqltypes.EncodeStringSQL(raw) + ") as JSON)" + require.Equal(t, expected, string(got.Raw())) +} + +// TestMarshalSQLValueNormalizesInvalidUTF8 verifies that JSON string +// marshaling normalizes invalid UTF-8 before producing SQL. +func TestMarshalSQLValueNormalizesInvalidUTF8(t *testing.T) { + raw := string([]byte{0xff, 0xfe, 'A'}) + val := NewString(raw) + + got, err := MarshalSQLValue(val.MarshalTo(nil)) + require.NoError(t, err) + + normalized := string([]rune(raw)) + expected := "CAST(JSON_QUOTE(_utf8mb4" + sqltypes.EncodeStringSQL(normalized) + ") as JSON)" + require.Equal(t, expected, string(got.Raw())) +} diff --git a/go/mysql/json/parser.go b/go/mysql/json/parser.go index 02225c7db24..03912e9c683 100644 --- a/go/mysql/json/parser.go +++ b/go/mysql/json/parser.go @@ -26,6 +26,7 @@ import ( "strings" "time" "unicode/utf16" + "unicode/utf8" "vitess.io/vitess/go/mysql/fastparse" @@ -311,7 +312,18 @@ func parseObject(s string, c *cache, depth int) (*Value, string, error) { } } +const hexDigits = "0123456789abcdef" + +// escapeString appends s as a JSON string to dst and returns the result. +// +// The output uses JSON compliant escapes for control bytes and only uses the +// short escape sequences for \b, \f, \n, \r, and \t. func escapeString(dst []byte, s string) []byte { + // If we have invalid UTF-8, normalize it so JSON output stays valid. + if !utf8.ValidString(s) { + s = string([]rune(s)) + } + if !hasSpecialChars(s) { // Fast path - nothing to escape. dst = append(dst, '"') @@ -320,8 +332,43 @@ func escapeString(dst []byte, s string) []byte { return dst } - // Slow path. - return strconv.AppendQuote(dst, s) + dst = append(dst, '"') + + // Escape control bytes, quotes, and backslashes. + for i := 0; i < len(s); i++ { + ch := s[i] + + switch ch { + case '"', '\\': + dst = append(dst, '\\', ch) + case '\b': // 0x08, backspace + dst = append(dst, '\\', 'b') + case '\f': // 0x0C, form feed + dst = append(dst, '\\', 'f') + case '\n': // 0x0A, line feed + dst = append(dst, '\\', 'n') + case '\r': // 0x0D, carriage return + dst = append(dst, '\\', 'r') + case '\t': // 0x09, horizontal tab + dst = append(dst, '\\', 't') + default: + // Other control characters (0x00-0x1F) use \u00XX escapes. + // We hardcode 00 since we only handle single byte control + // characters, then split the byte into two 4-bit halves; + // ch>>4 extracts the upper bits, and ch&0x0f extracts the lower + // bits. Each then indexes into hexDigits to produce the final + // two hex characters. + if ch < 0x20 { + dst = append(dst, '\\', 'u', '0', '0', hexDigits[ch>>4], hexDigits[ch&0x0f]) + continue + } + + dst = append(dst, ch) + } + } + + dst = append(dst, '"') + return dst } func hasSpecialChars(s string) bool { From 24994355881b325001bdf817c6d16bdef8aa11db Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 11:22:35 +0100 Subject: [PATCH 041/112] [release-22.0] evalengine: Fix `NULL` document handling in JSON functions (#19052) (#19230) Signed-off-by: Arthur Schreiber Co-authored-by: Arthur Schreiber --- go/vt/vtgate/evalengine/compiler.go | 2 ++ go/vt/vtgate/evalengine/compiler_asm.go | 9 ++++++ go/vt/vtgate/evalengine/fn_json.go | 36 ++++++++++----------- go/vt/vtgate/evalengine/testcases/cases.go | 21 +++++++----- go/vt/vtgate/evalengine/testcases/inputs.go | 15 +++++---- 5 files changed, 50 insertions(+), 33 deletions(-) diff --git a/go/vt/vtgate/evalengine/compiler.go b/go/vt/vtgate/evalengine/compiler.go index c69df3a300f..1718fb4b043 100644 --- a/go/vt/vtgate/evalengine/compiler.go +++ b/go/vt/vtgate/evalengine/compiler.go @@ -585,6 +585,8 @@ func (c *compiler) compileParseJSON(fn string, doct ctype, offset int) (ctype, e case sqltypes.TypeJSON: case sqltypes.VarChar, sqltypes.VarBinary: c.asm.Parse_j(offset) + case sqltypes.Null: + return ctype{Type: sqltypes.Null, Flag: flagNull | flagNullable, Col: collationNull}, nil default: return ctype{}, errJSONType(fn) } diff --git a/go/vt/vtgate/evalengine/compiler_asm.go b/go/vt/vtgate/evalengine/compiler_asm.go index b24bbce68ed..ff5573abcbc 100644 --- a/go/vt/vtgate/evalengine/compiler_asm.go +++ b/go/vt/vtgate/evalengine/compiler_asm.go @@ -2319,6 +2319,15 @@ func (asm *assembler) Fn_JSON_KEYS(jp *json.Path) { return 1 }, "FN JSON_KEYS (SP-1)") } else { + if jp.ContainsWildcards() { + asm.emit(func(env *ExpressionEnv) int { + env.vm.err = errInvalidPathForTransform + return 1 + }, "FN JSON_KEYS (SP-1), %q", jp.String()) + + return + } + asm.emit(func(env *ExpressionEnv) int { doc := env.vm.stack[env.vm.sp-1] if doc == nil { diff --git a/go/vt/vtgate/evalengine/fn_json.go b/go/vt/vtgate/evalengine/fn_json.go index eabe2ee8351..93714dc3438 100644 --- a/go/vt/vtgate/evalengine/fn_json.go +++ b/go/vt/vtgate/evalengine/fn_json.go @@ -129,16 +129,9 @@ func (call *builtinJSONExtract) compile(c *compiler) (ctype, error) { nullable := doct.nullable() skip := c.compileNullCheck1(doct) - // TODO: `*compiler.compileParseJSON` should handle `sqltypes.Null`` properly but - // we'll handle it here until all call sites are fixed. - var jt ctype - if doct.Type != sqltypes.Null { - jt, err = c.compileParseJSON("JSON_EXTRACT", doct, 1) - if err != nil { - return ctype{}, err - } - } else { - jt = ctype{Type: sqltypes.Null, Flag: flagNull | flagNullable, Col: collationNull} + jt, err := c.compileParseJSON("JSON_EXTRACT", doct, 1) + if err != nil { + return ctype{}, err } staticPaths := make([]staticPath, 0, len(call.Arguments[1:])) @@ -411,6 +404,13 @@ func (call *builtinJSONContainsPath) compile(c *compiler) (ctype, error) { return ctype{}, c.unsupported(call) } + skip := c.compileNullCheck1(doct) + + _, err = c.compileParseJSON("JSON_CONTAINS_PATH", doct, 1) + if err != nil { + return ctype{}, err + } + match, err := c.jsonExtractOneOrAll("JSON_CONTAINS_PATH", call.Arguments[1]) if err != nil { return ctype{}, err @@ -426,12 +426,10 @@ func (call *builtinJSONContainsPath) compile(c *compiler) (ctype, error) { paths = append(paths, jp) } - _, err = c.compileParseJSON("JSON_CONTAINS_PATH", doct, 1) - if err != nil { - return ctype{}, err - } - c.asm.Fn_JSON_CONTAINS_PATH(match, paths) + + c.asm.jumpDestination(skip) + return ctype{Type: sqltypes.Int64, Col: collationNumeric, Flag: flagIsBoolean | flagNullable}, nil } @@ -522,6 +520,8 @@ func (call *builtinJSONKeys) compile(c *compiler) (ctype, error) { return ctype{}, err } + skip := c.compileNullCheck1(doc) + _, err = c.compileParseJSON("JSON_KEYS", doc, 1) if err != nil { return ctype{}, err @@ -533,11 +533,11 @@ func (call *builtinJSONKeys) compile(c *compiler) (ctype, error) { if err != nil { return ctype{}, err } - if jp.ContainsWildcards() { - return ctype{}, errInvalidPathForTransform - } } c.asm.Fn_JSON_KEYS(jp) + + c.asm.jumpDestination(skip) + return ctype{Type: sqltypes.TypeJSON, Flag: flagNullable, Col: collationJSON}, nil } diff --git a/go/vt/vtgate/evalengine/testcases/cases.go b/go/vt/vtgate/evalengine/testcases/cases.go index 5b4a83a61c4..cc6c9e0ad12 100644 --- a/go/vt/vtgate/evalengine/testcases/cases.go +++ b/go/vt/vtgate/evalengine/testcases/cases.go @@ -33,6 +33,7 @@ var Cases = []TestCase{ {Run: FnJSONKeys}, {Run: FnJSONExtract}, {Run: FnJSONContainsPath}, + {Run: FnJSONUnquote}, {Run: JSONArray}, {Run: JSONObject}, {Run: CharsetConversionOperators}, @@ -180,10 +181,10 @@ var Cases = []TestCase{ func FnJSONKeys(yield Query) { for _, obj := range inputJSONObjects { - yield(fmt.Sprintf("JSON_KEYS('%s')", obj), nil, false) + yield(fmt.Sprintf("JSON_KEYS(%s)", obj), nil, false) for _, path1 := range inputJSONPaths { - yield(fmt.Sprintf("JSON_KEYS('%s', '%s')", obj, path1), nil, false) + yield(fmt.Sprintf("JSON_KEYS(%s, '%s')", obj, path1), nil, false) } } } @@ -191,10 +192,10 @@ func FnJSONKeys(yield Query) { func FnJSONExtract(yield Query) { for _, obj := range inputJSONObjects { for _, path1 := range inputJSONPaths { - yield(fmt.Sprintf("JSON_EXTRACT('%s', '%s')", obj, path1), nil, false) + yield(fmt.Sprintf("JSON_EXTRACT(%s, '%s')", obj, path1), nil, false) for _, path2 := range inputJSONPaths { - yield(fmt.Sprintf("JSON_EXTRACT('%s', '%s', '%s')", obj, path1, path2), nil, false) + yield(fmt.Sprintf("JSON_EXTRACT(%s, '%s', '%s')", obj, path1, path2), nil, false) } } } @@ -235,17 +236,21 @@ func FnJSONExtract(yield Query) { func FnJSONContainsPath(yield Query) { for _, obj := range inputJSONObjects { for _, path1 := range inputJSONPaths { - yield(fmt.Sprintf("JSON_CONTAINS_PATH('%s', 'one', '%s')", obj, path1), nil, false) - yield(fmt.Sprintf("JSON_CONTAINS_PATH('%s', 'all', '%s')", obj, path1), nil, false) + yield(fmt.Sprintf("JSON_CONTAINS_PATH(%s, 'one', '%s')", obj, path1), nil, false) + yield(fmt.Sprintf("JSON_CONTAINS_PATH(%s, 'all', '%s')", obj, path1), nil, false) for _, path2 := range inputJSONPaths { - yield(fmt.Sprintf("JSON_CONTAINS_PATH('%s', 'one', '%s', '%s')", obj, path1, path2), nil, false) - yield(fmt.Sprintf("JSON_CONTAINS_PATH('%s', 'all', '%s', '%s')", obj, path1, path2), nil, false) + yield(fmt.Sprintf("JSON_CONTAINS_PATH(%s, 'one', '%s', '%s')", obj, path1, path2), nil, false) + yield(fmt.Sprintf("JSON_CONTAINS_PATH(%s, 'all', '%s', '%s')", obj, path1, path2), nil, false) } } } } +func FnJSONUnquote(yield Query) { + yield("JSON_UNQUOTE(NULL)", nil, false) +} + func JSONArray(yield Query) { for _, a := range inputJSONPrimitives { yield(fmt.Sprintf("JSON_ARRAY(%s)", a), nil, false) diff --git a/go/vt/vtgate/evalengine/testcases/inputs.go b/go/vt/vtgate/evalengine/testcases/inputs.go index 4c65cc5002f..281eebb4fe0 100644 --- a/go/vt/vtgate/evalengine/testcases/inputs.go +++ b/go/vt/vtgate/evalengine/testcases/inputs.go @@ -24,13 +24,14 @@ import ( ) var inputJSONObjects = []string{ - `[ { "a": 1 }, { "a": 2 } ]`, - `{ "a" : "foo", "b" : [ true, { "c" : 123, "c" : 456 } ] }`, - `{ "a" : "foo", "b" : [ true, { "c" : "123" } ] }`, - `{ "a" : "foo", "b" : [ true, { "c" : 123 } ] }`, - `{"a": 1, "b": 2, "c": {"d": 4}}`, - `["a", {"b": [true, false]}, [10, 20]]`, - `[10, 20, [30, 40]]`, + `'[ { "a": 1 }, { "a": 2 } ]'`, + `'{ "a" : "foo", "b" : [ true, { "c" : 123, "c" : 456 } ] }'`, + `'{ "a" : "foo", "b" : [ true, { "c" : "123" } ] }'`, + `'{ "a" : "foo", "b" : [ true, { "c" : 123 } ] }'`, + `'{"a": 1, "b": 2, "c": {"d": 4}}'`, + `'["a", {"b": [true, false]}, [10, 20]]'`, + `'[10, 20, [30, 40]]'`, + `NULL`, } var inputJSONPaths = []string{ From 4ce74c54fbdd3d9e2592bd671b7afac6872bc81d Mon Sep 17 00:00:00 2001 From: Matt Lord Date: Wed, 4 Feb 2026 11:26:12 -0500 Subject: [PATCH 042/112] [release-22.0] Code Freeze for `v22.0.3` (#19281) Signed-off-by: Matt Lord --- .github/workflows/code_freeze.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/code_freeze.yml b/.github/workflows/code_freeze.yml index a66fb6e8b2b..5f0ae51e0f1 100644 --- a/.github/workflows/code_freeze.yml +++ b/.github/workflows/code_freeze.yml @@ -11,4 +11,4 @@ jobs: steps: - name: Fail if Code Freeze is enabled run: | - exit 0 + exit 1 From 53de5fdf419b30f89d14ad2a3412235c3d9aabbe Mon Sep 17 00:00:00 2001 From: Matt Lord Date: Wed, 4 Feb 2026 11:47:35 -0500 Subject: [PATCH 043/112] [release-22.0] Release of `v22.0.3` (#19282) Signed-off-by: Matt Lord --- .github/workflows/code_freeze.yml | 2 +- changelog/22.0/22.0.3/changelog.md | 74 +++++++++++++++++++ changelog/22.0/22.0.3/release_notes.md | 7 ++ changelog/22.0/README.md | 4 + examples/compose/docker-compose.beginners.yml | 20 ++--- examples/compose/docker-compose.yml | 26 +++---- .../compose/vtcompose/docker-compose.test.yml | 26 +++---- examples/compose/vtcompose/vtcompose.go | 16 ++-- examples/operator/101_initial_cluster.yaml | 14 ++-- examples/operator/201_customer_tablets.yaml | 14 ++-- examples/operator/302_new_shards.yaml | 14 ++-- examples/operator/306_down_shard_0.yaml | 14 ++-- examples/operator/401_scheduled_backups.yaml | 14 ++-- go/vt/servenv/version.go | 4 +- java/client/pom.xml | 2 +- java/example/pom.xml | 2 +- java/grpc-client/pom.xml | 2 +- java/jdbc/pom.xml | 2 +- java/pom.xml | 2 +- 19 files changed, 172 insertions(+), 87 deletions(-) create mode 100644 changelog/22.0/22.0.3/changelog.md create mode 100644 changelog/22.0/22.0.3/release_notes.md diff --git a/.github/workflows/code_freeze.yml b/.github/workflows/code_freeze.yml index 5f0ae51e0f1..a66fb6e8b2b 100644 --- a/.github/workflows/code_freeze.yml +++ b/.github/workflows/code_freeze.yml @@ -11,4 +11,4 @@ jobs: steps: - name: Fail if Code Freeze is enabled run: | - exit 1 + exit 0 diff --git a/changelog/22.0/22.0.3/changelog.md b/changelog/22.0/22.0.3/changelog.md new file mode 100644 index 00000000000..dd072034736 --- /dev/null +++ b/changelog/22.0/22.0.3/changelog.md @@ -0,0 +1,74 @@ +# Changelog of Vitess v22.0.3 + +### Bug fixes +#### Build/CI + * [release-22.0] Fix major upgrade logic in go upgrade tool [#19211](https://github.com/vitessio/vitess/pull/19211) +#### CLI + * [release-22.0] `vtbench`: add `--db-credentials-*` flags (#18913) [#18921](https://github.com/vitessio/vitess/pull/18921) +#### Cluster management + * [release-22.0] Improve Semi-Sync Monitor Behavior to Prevent Errant ERS (#18884) [#18906](https://github.com/vitessio/vitess/pull/18906) +#### Evalengine + * [release-22.0] evalengine: Fix `NULL` document handling in JSON functions (#19052) [#19230](https://github.com/vitessio/vitess/pull/19230) + * [release-22.0] evalengine: make `JSON_EXTRACT` work with non-static arguments (#19035) [#19253](https://github.com/vitessio/vitess/pull/19253) +#### General + * [release-22.0] Escape control bytes in JSON strings (#19270) [#19274](https://github.com/vitessio/vitess/pull/19274) +#### Query Serving + * [release-22.0] Properly Strip Keyspace Table Qualifiers in FK Constraints (#18926) [#18934](https://github.com/vitessio/vitess/pull/18934) + * [release-22.0] Fix cross shard/keyspace joins with derived tables containing a `UNION`. (#19046) [#19136](https://github.com/vitessio/vitess/pull/19136) + * [release-22.0] Fix column offset tracking for `UNION`s to be case insensitive. (#19139) [#19161](https://github.com/vitessio/vitess/pull/19161) +#### TabletManager + * [release-22.0] Fix `ReloadSchema` incorrectly using `DisableBinlogs` value in `grpctmclient` (#19085) [#19129](https://github.com/vitessio/vitess/pull/19129) +#### VDiff + * [release-22.0] VDiff: Prevent division by 0 when reconciling mismatches for reference tables (#19160) [#19164](https://github.com/vitessio/vitess/pull/19164) +#### VReplication + * [release-22.0] VDiff: Handle the case where a workflow's table has been dropped on the source (#18985) [#18988](https://github.com/vitessio/vitess/pull/18988) + * [release-22.0] VReplication: Properly Handle Sequence Table Initialization For Empty Tables (#19226) [#19227](https://github.com/vitessio/vitess/pull/19227) +#### VTGate + * [release-22.0] workflows: avoid accidental deletion to routing rules (#19121) [#19135](https://github.com/vitessio/vitess/pull/19135) +#### VTTablet + * [release-22.0] connpool: fix connection leak during idle connection reopen (#18967) [#18970](https://github.com/vitessio/vitess/pull/18970) + * [release-22.0] Change connection pool idle expiration logic (#19004) [#19013](https://github.com/vitessio/vitess/pull/19013) + * [release-22.0] binlog_json: fix opaque value parsing to read variable-length (#19102) [#19109](https://github.com/vitessio/vitess/pull/19109) +#### VTorc + * [release-22.0] `vtorc`: detect errant GTIDs for replicas not connected to primary (#19224) [#19233](https://github.com/vitessio/vitess/pull/19233) + * [release-22.0] vtorc: add `StaleTopoPrimary` analysis and recovery (#19173) [#19236](https://github.com/vitessio/vitess/pull/19236) +#### vtctl + * [release-22.0] vschema revert: initialize as nil so that nil checks do not pass later (#19114) [#19117](https://github.com/vitessio/vitess/pull/19117) +### CI/Build +#### Build/CI + * Pin GitHub Actions and Docker images by hash [#19151](https://github.com/vitessio/vitess/pull/19151) + * [release-22.0] Update go-upgrade to update docker image digests (#19178) [#19188](https://github.com/vitessio/vitess/pull/19188) + * [release-22.0] Fix go upgrade workflow (#19216) [#19219](https://github.com/vitessio/vitess/pull/19219) + * [release-22.0] switch end-to-end tests to gotestsum (#19182) [#19244](https://github.com/vitessio/vitess/pull/19244) +#### General + * [release-22.0] Upgrade the Golang version to `go1.24.10` [#18897](https://github.com/vitessio/vitess/pull/18897) + * [release-22.0] Upgrade the Golang version to `go1.24.12` [#19222](https://github.com/vitessio/vitess/pull/19222) +### Enhancement +#### Build/CI + * [release-22.0] Don't hardcode the go version to use for upgrade/downgrade tests. (#18920) [#18955](https://github.com/vitessio/vitess/pull/18955) +#### TabletManager + * [release-22.0] Add new `force` flag to `DemotePrimary` to force a demotion even when blocked on waiting for semi-sync acks (#18714) [#19238](https://github.com/vitessio/vitess/pull/19238) +#### VDiff + * [release-22.0] vdiff: do not sort by table name in summary, it is not necessary (#18972) [#18977](https://github.com/vitessio/vitess/pull/18977) +### Internal Cleanup +#### Docker + * [release-22.0] `ci`: use `etcd` v3.5.25, add retries (#19015) [#19021](https://github.com/vitessio/vitess/pull/19021) +### Release +#### General + * [release-22.0] Code Freeze for `v22.0.3` [#19281](https://github.com/vitessio/vitess/pull/19281) +### Security +#### Java + * [release-22.0] Bump org.apache.logging.log4j:log4j-core from 2.24.1 to 2.25.3 in /java (#19063) [#19065](https://github.com/vitessio/vitess/pull/19065) +#### VTAdmin + * [release-22.0] Bump js-yaml from 4.1.0 to 4.1.1 in /web/vtadmin (#18908) [#18910](https://github.com/vitessio/vitess/pull/18910) + * [release-22.0] Drop dependency on `npm`, bump version of `glob`. (#18931) [#18957](https://github.com/vitessio/vitess/pull/18957) + * [release-22.0] Potential fix for code scanning alert no. 3944: Database query built … [#18962](https://github.com/vitessio/vitess/pull/18962) +### Testing +#### Build/CI + * [release-22.0] Stop using Equinix Metal self hosted runners (#18942) [#18943](https://github.com/vitessio/vitess/pull/18943) + * [release-22.0] CI: Improve reliability of codecov workflow with larger runner (#18992) [#18994](https://github.com/vitessio/vitess/pull/18994) + * [release-22.0] Skip flaky `TestRedial` test (#19106) [#19107](https://github.com/vitessio/vitess/pull/19107) + * [release-22.0] CI: Look for expected log message rather than code in Backup tests (#19199) [#19200](https://github.com/vitessio/vitess/pull/19200) +#### VTGate + * [release-22.0] Fix sporadic TestServingKeyspaces panic on context cancellation (#19163) [#19186](https://github.com/vitessio/vitess/pull/19186) + diff --git a/changelog/22.0/22.0.3/release_notes.md b/changelog/22.0/22.0.3/release_notes.md new file mode 100644 index 00000000000..da18cc4e572 --- /dev/null +++ b/changelog/22.0/22.0.3/release_notes.md @@ -0,0 +1,7 @@ +# Release of Vitess v22.0.3 +The entire changelog for this release can be found [here](https://github.com/vitessio/vitess/blob/main/changelog/22.0/22.0.3/changelog.md). + +The release includes 40 merged Pull Requests. + +Thanks to all our contributors: @app/vitess-bot, @mattlord, @mhamza15, @timvaillancourt, @vitess-bot + diff --git a/changelog/22.0/README.md b/changelog/22.0/README.md index 96b173a8537..272a2f335d6 100644 --- a/changelog/22.0/README.md +++ b/changelog/22.0/README.md @@ -1,4 +1,8 @@ ## v22.0 +* **[22.0.3](22.0.3)** + * [Changelog](22.0.3/changelog.md) + * [Release Notes](22.0.3/release_notes.md) + * **[22.0.2](22.0.2)** * [Changelog](22.0.2/changelog.md) * [Release Notes](22.0.2/release_notes.md) diff --git a/examples/compose/docker-compose.beginners.yml b/examples/compose/docker-compose.beginners.yml index 6c22e60efa3..213ae433fd9 100644 --- a/examples/compose/docker-compose.beginners.yml +++ b/examples/compose/docker-compose.beginners.yml @@ -58,7 +58,7 @@ services: - "3306" vtctld: - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - "15000:$WEB_PORT" - "$GRPC_PORT" @@ -83,7 +83,7 @@ services: condition: service_healthy vtgate: - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - "15099:$WEB_PORT" - "$GRPC_PORT" @@ -113,7 +113,7 @@ services: condition: service_healthy schemaload: - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 command: - sh - -c @@ -146,12 +146,12 @@ services: environment: - KEYSPACES=$KEYSPACE - GRPC_PORT=15999 - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 volumes: - .:/script vttablet100: - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - "15100:$WEB_PORT" - "$GRPC_PORT" @@ -183,7 +183,7 @@ services: retries: 15 vttablet101: - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - "15101:$WEB_PORT" - "$GRPC_PORT" @@ -215,7 +215,7 @@ services: retries: 15 vttablet102: - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - "15102:$WEB_PORT" - "$GRPC_PORT" @@ -247,7 +247,7 @@ services: retries: 15 vttablet103: - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - "15103:$WEB_PORT" - "$GRPC_PORT" @@ -279,7 +279,7 @@ services: retries: 15 vtorc: - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 command: ["sh", "-c", "/script/vtorc-up.sh"] depends_on: - vtctld @@ -309,7 +309,7 @@ services: retries: 15 vreplication: - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 volumes: - ".:/script" environment: diff --git a/examples/compose/docker-compose.yml b/examples/compose/docker-compose.yml index 133ad0c150d..548f3b52ac3 100644 --- a/examples/compose/docker-compose.yml +++ b/examples/compose/docker-compose.yml @@ -75,7 +75,7 @@ services: - SCHEMA_FILES=lookup_keyspace_schema_file.sql - POST_LOAD_FILE= - EXTERNAL_DB=0 - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 volumes: - .:/script schemaload_test_keyspace: @@ -101,7 +101,7 @@ services: - SCHEMA_FILES=test_keyspace_schema_file.sql - POST_LOAD_FILE= - EXTERNAL_DB=0 - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 volumes: - .:/script set_keyspace_durability_policy: @@ -115,7 +115,7 @@ services: environment: - KEYSPACES=test_keyspace lookup_keyspace - GRPC_PORT=15999 - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 volumes: - .:/script vreplication: @@ -129,7 +129,7 @@ services: - TOPOLOGY_FLAGS=--topo_implementation consul --topo_global_server_address consul1:8500 --topo_global_root vitess/global - EXTERNAL_DB=0 - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 volumes: - .:/script vtctld: @@ -143,7 +143,7 @@ services: depends_on: external_db_host: condition: service_healthy - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - 15000:8080 - "15999" @@ -160,7 +160,7 @@ services: --normalize_queries=true ' depends_on: - vtctld - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - 15099:8080 - "15999" @@ -182,7 +182,7 @@ services: - EXTERNAL_DB=0 - DB_USER= - DB_PASS= - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - 13000:8080 volumes: @@ -217,7 +217,7 @@ services: - CMD-SHELL - curl -s --fail --show-error localhost:8080/debug/health timeout: 10s - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - 15101:8080 - "15999" @@ -254,7 +254,7 @@ services: - CMD-SHELL - curl -s --fail --show-error localhost:8080/debug/health timeout: 10s - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - 15102:8080 - "15999" @@ -291,7 +291,7 @@ services: - CMD-SHELL - curl -s --fail --show-error localhost:8080/debug/health timeout: 10s - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - 15201:8080 - "15999" @@ -328,7 +328,7 @@ services: - CMD-SHELL - curl -s --fail --show-error localhost:8080/debug/health timeout: 10s - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - 15202:8080 - "15999" @@ -365,7 +365,7 @@ services: - CMD-SHELL - curl -s --fail --show-error localhost:8080/debug/health timeout: 10s - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - 15301:8080 - "15999" @@ -402,7 +402,7 @@ services: - CMD-SHELL - curl -s --fail --show-error localhost:8080/debug/health timeout: 10s - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - 15302:8080 - "15999" diff --git a/examples/compose/vtcompose/docker-compose.test.yml b/examples/compose/vtcompose/docker-compose.test.yml index be4d1c98c49..0bad4b1ded3 100644 --- a/examples/compose/vtcompose/docker-compose.test.yml +++ b/examples/compose/vtcompose/docker-compose.test.yml @@ -79,7 +79,7 @@ services: - SCHEMA_FILES=test_keyspace_schema_file.sql - POST_LOAD_FILE= - EXTERNAL_DB=0 - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 volumes: - .:/script schemaload_unsharded_keyspace: @@ -103,7 +103,7 @@ services: - SCHEMA_FILES=unsharded_keyspace_schema_file.sql - POST_LOAD_FILE= - EXTERNAL_DB=0 - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 volumes: - .:/script set_keyspace_durability_policy_test_keyspace: @@ -117,7 +117,7 @@ services: environment: - GRPC_PORT=15999 - KEYSPACES=test_keyspace - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 volumes: - .:/script set_keyspace_durability_policy_unsharded_keyspace: @@ -130,7 +130,7 @@ services: environment: - GRPC_PORT=15999 - KEYSPACES=unsharded_keyspace - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 volumes: - .:/script vreplication: @@ -144,7 +144,7 @@ services: - TOPOLOGY_FLAGS=--topo_implementation consul --topo_global_server_address consul1:8500 --topo_global_root vitess/global - EXTERNAL_DB=0 - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 volumes: - .:/script vtctld: @@ -159,7 +159,7 @@ services: depends_on: external_db_host: condition: service_healthy - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - 15000:8080 - "15999" @@ -176,7 +176,7 @@ services: ''grpc-vtgateservice'' --normalize_queries=true ' depends_on: - vtctld - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - 15099:8080 - "15999" @@ -199,7 +199,7 @@ services: - EXTERNAL_DB=0 - DB_USER= - DB_PASS= - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - 13000:8080 volumes: @@ -234,7 +234,7 @@ services: - CMD-SHELL - curl -s --fail --show-error localhost:8080/debug/health timeout: 10s - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - 15101:8080 - "15999" @@ -271,7 +271,7 @@ services: - CMD-SHELL - curl -s --fail --show-error localhost:8080/debug/health timeout: 10s - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - 15102:8080 - "15999" @@ -308,7 +308,7 @@ services: - CMD-SHELL - curl -s --fail --show-error localhost:8080/debug/health timeout: 10s - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - 15201:8080 - "15999" @@ -345,7 +345,7 @@ services: - CMD-SHELL - curl -s --fail --show-error localhost:8080/debug/health timeout: 10s - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - 15202:8080 - "15999" @@ -382,7 +382,7 @@ services: - CMD-SHELL - curl -s --fail --show-error localhost:8080/debug/health timeout: 10s - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - 15301:8080 - "15999" diff --git a/examples/compose/vtcompose/vtcompose.go b/examples/compose/vtcompose/vtcompose.go index 8426a9aec10..ec3137ae4c8 100644 --- a/examples/compose/vtcompose/vtcompose.go +++ b/examples/compose/vtcompose/vtcompose.go @@ -525,7 +525,7 @@ func generateExternalPrimary( - op: add path: /services/vttablet%[1]d value: - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - "15%[1]d:%[3]d" - "%[4]d" @@ -587,7 +587,7 @@ func generateDefaultTablet(tabAlias int, shard, role, keyspace string, dbInfo ex - op: add path: /services/vttablet%[1]d value: - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - "15%[1]d:%[4]d" - "%[5]d" @@ -625,7 +625,7 @@ func generateVtctld(opts vtOptions) string { - op: add path: /services/vtctld value: - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - "15000:%[1]d" - "%[2]d" @@ -656,7 +656,7 @@ func generateVtgate(opts vtOptions) string { - op: add path: /services/vtgate value: - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 ports: - "15099:%[1]d" - "%[2]d" @@ -698,7 +698,7 @@ func generateVTOrc(dbInfo externalDbInfo, keyspaceInfoMap map[string]keyspaceInf - op: add path: /services/vtorc value: - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 volumes: - ".:/script" environment: @@ -723,7 +723,7 @@ func generateVreplication(dbInfo externalDbInfo, opts vtOptions) string { - op: add path: /services/vreplication value: - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 volumes: - ".:/script" environment: @@ -751,7 +751,7 @@ func generateSetKeyspaceDurabilityPolicy( - op: add path: /services/set_keyspace_durability_policy_%[3]s value: - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 volumes: - ".:/script" environment: @@ -788,7 +788,7 @@ func generateSchemaload( - op: add path: /services/schemaload_%[7]s value: - image: vitess/lite:v22.0.2 + image: vitess/lite:v22.0.3 volumes: - ".:/script" environment: diff --git a/examples/operator/101_initial_cluster.yaml b/examples/operator/101_initial_cluster.yaml index 26fbcbad38e..e50a36cc9a8 100644 --- a/examples/operator/101_initial_cluster.yaml +++ b/examples/operator/101_initial_cluster.yaml @@ -16,14 +16,14 @@ spec: path: /tmp type: Directory images: - vtctld: vitess/lite:v22.0.2 - vtadmin: vitess/vtadmin:v22.0.2 - vtgate: vitess/lite:v22.0.2 - vttablet: vitess/lite:v22.0.2 - vtbackup: vitess/lite:v22.0.2 - vtorc: vitess/lite:v22.0.2 + vtctld: vitess/lite:v22.0.3 + vtadmin: vitess/vtadmin:v22.0.3 + vtgate: vitess/lite:v22.0.3 + vttablet: vitess/lite:v22.0.3 + vtbackup: vitess/lite:v22.0.3 + vtorc: vitess/lite:v22.0.3 mysqld: - mysql80Compatible: vitess/lite:v22.0.2 + mysql80Compatible: vitess/lite:v22.0.3 mysqldExporter: prom/mysqld-exporter:v0.14.0 cells: - name: zone1 diff --git a/examples/operator/201_customer_tablets.yaml b/examples/operator/201_customer_tablets.yaml index 5cd355b9bdc..ed70a2cfd81 100644 --- a/examples/operator/201_customer_tablets.yaml +++ b/examples/operator/201_customer_tablets.yaml @@ -12,14 +12,14 @@ spec: path: /tmp type: Directory images: - vtctld: vitess/lite:v22.0.2 - vtadmin: vitess/vtadmin:v22.0.2 - vtgate: vitess/lite:v22.0.2 - vttablet: vitess/lite:v22.0.2 - vtbackup: vitess/lite:v22.0.2 - vtorc: vitess/lite:v22.0.2 + vtctld: vitess/lite:v22.0.3 + vtadmin: vitess/vtadmin:v22.0.3 + vtgate: vitess/lite:v22.0.3 + vttablet: vitess/lite:v22.0.3 + vtbackup: vitess/lite:v22.0.3 + vtorc: vitess/lite:v22.0.3 mysqld: - mysql80Compatible: vitess/lite:v22.0.2 + mysql80Compatible: vitess/lite:v22.0.3 mysqldExporter: prom/mysqld-exporter:v0.14.0 cells: - name: zone1 diff --git a/examples/operator/302_new_shards.yaml b/examples/operator/302_new_shards.yaml index 416e1c22cf7..bc8c43a40e5 100644 --- a/examples/operator/302_new_shards.yaml +++ b/examples/operator/302_new_shards.yaml @@ -12,14 +12,14 @@ spec: path: /tmp type: Directory images: - vtctld: vitess/lite:v22.0.2 - vtadmin: vitess/vtadmin:v22.0.2 - vtgate: vitess/lite:v22.0.2 - vttablet: vitess/lite:v22.0.2 - vtbackup: vitess/lite:v22.0.2 - vtorc: vitess/lite:v22.0.2 + vtctld: vitess/lite:v22.0.3 + vtadmin: vitess/vtadmin:v22.0.3 + vtgate: vitess/lite:v22.0.3 + vttablet: vitess/lite:v22.0.3 + vtbackup: vitess/lite:v22.0.3 + vtorc: vitess/lite:v22.0.3 mysqld: - mysql80Compatible: vitess/lite:v22.0.2 + mysql80Compatible: vitess/lite:v22.0.3 mysqldExporter: prom/mysqld-exporter:v0.14.0 cells: - name: zone1 diff --git a/examples/operator/306_down_shard_0.yaml b/examples/operator/306_down_shard_0.yaml index 3cc5bb188ec..5426c6bd72e 100644 --- a/examples/operator/306_down_shard_0.yaml +++ b/examples/operator/306_down_shard_0.yaml @@ -12,14 +12,14 @@ spec: path: /tmp type: Directory images: - vtctld: vitess/lite:v22.0.2 - vtadmin: vitess/vtadmin:v22.0.2 - vtgate: vitess/lite:v22.0.2 - vttablet: vitess/lite:v22.0.2 - vtbackup: vitess/lite:v22.0.2 - vtorc: vitess/lite:v22.0.2 + vtctld: vitess/lite:v22.0.3 + vtadmin: vitess/vtadmin:v22.0.3 + vtgate: vitess/lite:v22.0.3 + vttablet: vitess/lite:v22.0.3 + vtbackup: vitess/lite:v22.0.3 + vtorc: vitess/lite:v22.0.3 mysqld: - mysql80Compatible: vitess/lite:v22.0.2 + mysql80Compatible: vitess/lite:v22.0.3 mysqldExporter: prom/mysqld-exporter:v0.14.0 cells: - name: zone1 diff --git a/examples/operator/401_scheduled_backups.yaml b/examples/operator/401_scheduled_backups.yaml index 7a351281fbd..84c255ac859 100644 --- a/examples/operator/401_scheduled_backups.yaml +++ b/examples/operator/401_scheduled_backups.yaml @@ -46,14 +46,14 @@ spec: keyspace: "customer" shard: "-80" images: - vtctld: vitess/lite:v22.0.2 - vtadmin: vitess/vtadmin:v22.0.2 - vtgate: vitess/lite:v22.0.2 - vttablet: vitess/lite:v22.0.2 - vtbackup: vitess/lite:v22.0.2 - vtorc: vitess/lite:v22.0.2 + vtctld: vitess/lite:v22.0.3 + vtadmin: vitess/vtadmin:v22.0.3 + vtgate: vitess/lite:v22.0.3 + vttablet: vitess/lite:v22.0.3 + vtbackup: vitess/lite:v22.0.3 + vtorc: vitess/lite:v22.0.3 mysqld: - mysql80Compatible: vitess/lite:v22.0.2 + mysql80Compatible: vitess/lite:v22.0.3 mysqldExporter: prom/mysqld-exporter:v0.14.0 cells: - name: zone1 diff --git a/go/vt/servenv/version.go b/go/vt/servenv/version.go index 6aea4b9c65d..9dde38f0a4f 100644 --- a/go/vt/servenv/version.go +++ b/go/vt/servenv/version.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The Vitess Authors. +Copyright 2026 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,4 +19,4 @@ package servenv // DO NOT EDIT // THIS FILE IS AUTO-GENERATED DURING NEW RELEASES BY THE VITESS-RELEASER -const versionName = "22.0.3-SNAPSHOT" +const versionName = "22.0.3" diff --git a/java/client/pom.xml b/java/client/pom.xml index 1c356ea6330..42313f3726a 100644 --- a/java/client/pom.xml +++ b/java/client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 22.0.3-SNAPSHOT + 22.0.3 vitess-client Vitess Java Client diff --git a/java/example/pom.xml b/java/example/pom.xml index 927192a593e..8a3c8e82dd9 100644 --- a/java/example/pom.xml +++ b/java/example/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 22.0.3-SNAPSHOT + 22.0.3 vitess-example Vitess Java Client Example diff --git a/java/grpc-client/pom.xml b/java/grpc-client/pom.xml index dbb42fb51ea..e3202b5d48a 100644 --- a/java/grpc-client/pom.xml +++ b/java/grpc-client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 22.0.3-SNAPSHOT + 22.0.3 vitess-grpc-client Vitess gRPC Client diff --git a/java/jdbc/pom.xml b/java/jdbc/pom.xml index 97b89ca0c9e..0f8b34139d2 100644 --- a/java/jdbc/pom.xml +++ b/java/jdbc/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 22.0.3-SNAPSHOT + 22.0.3 vitess-jdbc Vitess JDBC Driver diff --git a/java/pom.xml b/java/pom.xml index 544d8fa7e78..7e3a4aa9179 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -11,7 +11,7 @@ io.vitess vitess-parent - 22.0.3-SNAPSHOT + 22.0.3 pom Vitess Java Client libraries [Parent] From 8c204b97aea3127605b68ccae2c2404a9fbfb8c2 Mon Sep 17 00:00:00 2001 From: Matt Lord Date: Wed, 4 Feb 2026 11:57:53 -0500 Subject: [PATCH 044/112] [release-22.0] Bump to `v22.0.4-SNAPSHOT` after the `v22.0.3` release (#19284) Signed-off-by: Matt Lord --- go/vt/servenv/version.go | 2 +- java/client/pom.xml | 2 +- java/example/pom.xml | 2 +- java/grpc-client/pom.xml | 2 +- java/jdbc/pom.xml | 2 +- java/pom.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go/vt/servenv/version.go b/go/vt/servenv/version.go index 9dde38f0a4f..ff1acc10527 100644 --- a/go/vt/servenv/version.go +++ b/go/vt/servenv/version.go @@ -19,4 +19,4 @@ package servenv // DO NOT EDIT // THIS FILE IS AUTO-GENERATED DURING NEW RELEASES BY THE VITESS-RELEASER -const versionName = "22.0.3" +const versionName = "22.0.4-SNAPSHOT" diff --git a/java/client/pom.xml b/java/client/pom.xml index 42313f3726a..f0c44682b15 100644 --- a/java/client/pom.xml +++ b/java/client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 22.0.3 + 22.0.4-SNAPSHOT vitess-client Vitess Java Client diff --git a/java/example/pom.xml b/java/example/pom.xml index 8a3c8e82dd9..41eec3e319e 100644 --- a/java/example/pom.xml +++ b/java/example/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 22.0.3 + 22.0.4-SNAPSHOT vitess-example Vitess Java Client Example diff --git a/java/grpc-client/pom.xml b/java/grpc-client/pom.xml index e3202b5d48a..69e9e71bf47 100644 --- a/java/grpc-client/pom.xml +++ b/java/grpc-client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 22.0.3 + 22.0.4-SNAPSHOT vitess-grpc-client Vitess gRPC Client diff --git a/java/jdbc/pom.xml b/java/jdbc/pom.xml index 0f8b34139d2..006d8bcaeb9 100644 --- a/java/jdbc/pom.xml +++ b/java/jdbc/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 22.0.3 + 22.0.4-SNAPSHOT vitess-jdbc Vitess JDBC Driver diff --git a/java/pom.xml b/java/pom.xml index 7e3a4aa9179..ed6990a508b 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -11,7 +11,7 @@ io.vitess vitess-parent - 22.0.3 + 22.0.4-SNAPSHOT pom Vitess Java Client libraries [Parent] From f17f9ccff00990bff36c2f018259c48b3f915428 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Thu, 5 Feb 2026 15:44:47 +0100 Subject: [PATCH 045/112] [release-22.0] Generate race unit tests (#19078) (#19295) Signed-off-by: Mohamed Hamza Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Mohamed Hamza --- .github/workflows/unit_race.yml | 27 +++++---- .github/workflows/unit_race_evalengine.yml | 25 +++++---- Makefile | 2 +- go/vt/vtctl/workflow/utils_test.go | 9 +-- test/ci_workflow_gen.go | 48 ++++++++++++++-- test/templates/unit_test.tpl | 4 +- tools/unit_test_race.sh | 65 ---------------------- tools/unit_test_runner.sh | 10 +++- 8 files changed, 89 insertions(+), 101 deletions(-) delete mode 100755 tools/unit_test_race.sh diff --git a/.github/workflows/unit_race.yml b/.github/workflows/unit_race.yml index 22560c236b5..f769afe70cd 100644 --- a/.github/workflows/unit_race.yml +++ b/.github/workflows/unit_race.yml @@ -1,4 +1,6 @@ -name: unit_race +# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" + +name: Unit Test (Race) on: push: branches: @@ -8,7 +10,7 @@ on: pull_request: branches: '**' concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'unit_race') + group: format('{0}-{1}', ${{ github.ref }}, 'Unit Test (Race)') cancel-in-progress: true permissions: read-all @@ -19,10 +21,10 @@ env: GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" jobs: - - build: + test: name: Unit Test (Race) runs-on: gh-hosted-runners-16cores-1-24.04 + steps: - name: Skip CI run: | @@ -75,22 +77,20 @@ jobs: uses: ./.github/actions/setup-mysql with: flavor: mysql-8.0 - + - name: Get dependencies if: steps.changes.outputs.unit_tests == 'true' run: | export DEBIAN_FRONTEND="noninteractive" - sudo apt-get -qq update + sudo apt-get install -y make unzip g++ curl git wget ant openjdk-11-jdk - sudo apt-get -qq install -y make unzip g++ curl git wget ant openjdk-11-jdk - mkdir -p dist bin curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/ go mod download go install golang.org/x/tools/cmd/goimports@latest - + # install JUnit report formatter go install github.com/vitessio/go-junit-report@HEAD @@ -111,15 +111,20 @@ jobs: # Tell Launchable about the build you are producing and testing launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - name: unit_race + - name: Run test if: steps.changes.outputs.unit_tests == 'true' timeout-minutes: 45 run: | + set -exo pipefail # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file # which musn't be more than 107 characters long. export VTDATAROOT="/tmp/" + export NOVTADMINBUILD=1 export VTEVALENGINETEST="0" + # We sometimes need to alter the behavior based on the platform we're + # testing, e.g. MySQL 5.7 vs 8.0. + export CI_DB_PLATFORM="mysql80" make unit_test_race | tee -a output.txt | go-junit-report -set-exit-code > report.xml @@ -134,7 +139,7 @@ jobs: run: | # print test output cat output.txt - + - name: Test Summary if: steps.changes.outputs.unit_tests == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 diff --git a/.github/workflows/unit_race_evalengine.yml b/.github/workflows/unit_race_evalengine.yml index 803595c22cf..c7a61a09bf1 100644 --- a/.github/workflows/unit_race_evalengine.yml +++ b/.github/workflows/unit_race_evalengine.yml @@ -1,4 +1,6 @@ -name: unit_race_evalengine +# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" + +name: Unit Test (Evalengine_Race) on: push: branches: @@ -8,7 +10,7 @@ on: pull_request: branches: '**' concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'unit_race_evalengine') + group: format('{0}-{1}', ${{ github.ref }}, 'Unit Test (Evalengine_Race)') cancel-in-progress: true permissions: read-all @@ -19,10 +21,10 @@ env: GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" jobs: - - build: + test: name: Unit Test (Evalengine_Race) runs-on: gh-hosted-runners-16cores-1-24.04 + steps: - name: Skip CI run: | @@ -75,22 +77,20 @@ jobs: uses: ./.github/actions/setup-mysql with: flavor: mysql-8.0 - + - name: Get dependencies if: steps.changes.outputs.unit_tests == 'true' run: | export DEBIAN_FRONTEND="noninteractive" - sudo apt-get -qq update + sudo apt-get install -y make unzip g++ curl git wget ant openjdk-11-jdk - sudo apt-get -qq install -y make unzip g++ curl git wget ant openjdk-11-jdk - mkdir -p dist bin curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/ go mod download go install golang.org/x/tools/cmd/goimports@latest - + # install JUnit report formatter go install github.com/vitessio/go-junit-report@HEAD @@ -111,15 +111,20 @@ jobs: # Tell Launchable about the build you are producing and testing launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - name: unit_race_evalengine + - name: Run test if: steps.changes.outputs.unit_tests == 'true' timeout-minutes: 45 run: | + set -exo pipefail # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file # which musn't be more than 107 characters long. export VTDATAROOT="/tmp/" + export NOVTADMINBUILD=1 export VTEVALENGINETEST="1" + # We sometimes need to alter the behavior based on the platform we're + # testing, e.g. MySQL 5.7 vs 8.0. + export CI_DB_PLATFORM="mysql80" make unit_test_race | tee -a output.txt | go-junit-report -set-exit-code > report.xml diff --git a/Makefile b/Makefile index 9e2e697a9e2..82a0232a610 100644 --- a/Makefile +++ b/Makefile @@ -228,7 +228,7 @@ unit_test_cover: build dependency_check demo go tool $(VT_GO_PARALLEL) cover -html=coverage.out unit_test_race: build dependency_check - tools/unit_test_race.sh + RACE=1 tools/unit_test_runner.sh e2e_test_race: build tools/e2e_test_race.sh diff --git a/go/vt/vtctl/workflow/utils_test.go b/go/vt/vtctl/workflow/utils_test.go index 99850639ac5..aa0f68c6cac 100644 --- a/go/vt/vtctl/workflow/utils_test.go +++ b/go/vt/vtctl/workflow/utils_test.go @@ -15,6 +15,7 @@ import ( "github.com/stretchr/testify/require" clientv3 "go.etcd.io/etcd/client/v3" + "vitess.io/vitess/go/race" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/testfiles" "vitess.io/vitess/go/vt/log" @@ -119,10 +120,10 @@ func TestUpdateKeyspaceRoutingRule(t *testing.T) { // TestConcurrentKeyspaceRoutingRulesUpdates runs multiple keyspace routing rules updates concurrently to test // the locking mechanism. func TestConcurrentKeyspaceRoutingRulesUpdates(t *testing.T) { - if os.Getenv("GOCOVERDIR") != "" { - // While running this test in CI along with all other tests in for code coverage this test hangs very often. - // Possibly due to some resource constraints, since this test is one of the last. - // However just running this package by itself with code coverage works fine in CI. + if os.Getenv("GOCOVERDIR") != "" || race.Enabled { + // While running this test in CI along with all other tests in for code coverage or race enabled, + // this test hangs very often. Possibly due to some resource constraints, since this test is one + // of the last. However just running this package by itself with code coverage works fine in CI. t.Logf("Skipping TestConcurrentKeyspaceRoutingRulesUpdates test in code coverage mode") t.Skip() } diff --git a/test/ci_workflow_gen.go b/test/ci_workflow_gen.go index 61ac2b4dd6a..225ee344f70 100644 --- a/test/ci_workflow_gen.go +++ b/test/ci_workflow_gen.go @@ -38,13 +38,9 @@ const ( type mysqlVersions []mysqlVersion -var ( - defaultMySQLVersions = []mysqlVersion{defaultMySQLVersion} -) +var defaultMySQLVersions = []mysqlVersion{defaultMySQLVersion} -var ( - unitTestDatabases = []mysqlVersion{mysql57, mysql80, mysql84} -) +var unitTestDatabases = []mysqlVersion{mysql57, mysql80, mysql84} const ( oracleCloudRunner = "oracle-16cpu-64gb-x86-64" @@ -180,6 +176,7 @@ var ( type unitTest struct { Name, RunsOn, Platform, FileName, GoPrivate, Evalengine string + Race bool } type clusterTest struct { @@ -374,6 +371,24 @@ func generateUnitTestWorkflows() { } } } + + // Generate unit tests with race detection + for _, evalengine := range []string{"1", "0"} { + raceTest := &unitTest{ + Name: fmt.Sprintf("Unit Test (%sRace)", evalengineToRaceNamePrefix(evalengine)), + RunsOn: cores16RunnerName, + Platform: string(mysql80), + GoPrivate: goPrivate, + Evalengine: evalengine, + Race: true, + } + raceTest.FileName = fmt.Sprintf("unit_race%s.yml", evalengineToFileSuffix(evalengine)) + path := fmt.Sprintf("%s/%s", workflowConfigDir, raceTest.FileName) + err := writeFileFromTemplate(unitTestTemplate, path, raceTest) + if err != nil { + log.Print(err) + } + } } func evalengineToString(evalengine string) string { @@ -383,6 +398,27 @@ func evalengineToString(evalengine string) string { return "" } +func evalengineToNameSuffix(evalengine string) string { + if evalengine == "1" { + return " evalengine" + } + return "" +} + +func evalengineToRaceNamePrefix(evalengine string) string { + if evalengine == "1" { + return "Evalengine_" + } + return "" +} + +func evalengineToFileSuffix(evalengine string) string { + if evalengine == "1" { + return "_evalengine" + } + return "" +} + func writeFileFromTemplate(templateFile, filePath string, test any) error { tpl := template.New(path.Base(templateFile)) tpl.Funcs(template.FuncMap{ diff --git a/test/templates/unit_test.tpl b/test/templates/unit_test.tpl index 2b2de08416e..de5f193f02f 100644 --- a/test/templates/unit_test.tpl +++ b/test/templates/unit_test.tpl @@ -126,7 +126,7 @@ jobs: - name: Run test if: steps.changes.outputs.unit_tests == 'true' - timeout-minutes: 30 + timeout-minutes: {{if .Race}}45{{else}}30{{end}} run: | set -exo pipefail # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file @@ -139,7 +139,7 @@ jobs: # testing, e.g. MySQL 5.7 vs 8.0. export CI_DB_PLATFORM="{{.Platform}}" - make unit_test | tee -a output.txt | go-junit-report -set-exit-code > report.xml + make {{if .Race}}unit_test_race{{else}}unit_test{{end}} | tee -a output.txt | go-junit-report -set-exit-code > report.xml - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' && !cancelled() diff --git a/tools/unit_test_race.sh b/tools/unit_test_race.sh deleted file mode 100755 index 86fbcbcf995..00000000000 --- a/tools/unit_test_race.sh +++ /dev/null @@ -1,65 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -source build.env - -if [[ -z $VT_GO_PARALLEL && -n $VT_GO_PARALLEL_VALUE ]]; then - VT_GO_PARALLEL="-p $VT_GO_PARALLEL_VALUE" -fi - -# All Go packages with test files. -# Output per line: * - -packages_with_tests=$(go list -f '{{if len .TestGoFiles}}{{.ImportPath}} {{join .TestGoFiles " "}}{{end}}{{if len .XTestGoFiles}}{{.ImportPath}} {{join .XTestGoFiles " "}}{{end}}' ./go/... | sort) -if [[ "$VTEVALENGINETEST" == "1" ]]; then - packages_with_tests=$(echo "$packages_with_tests" | grep "evalengine") -fi - -if [[ "$VTEVALENGINETEST" == "0" ]]; then - packages_with_tests=$(echo "$packages_with_tests" | grep -v "evalengine") -fi - -# Flaky tests have the suffix "_flaky_test.go". -# Exclude endtoend tests -all_except_flaky_tests=$(echo "$packages_with_tests" | grep -vE ".+ .+_flaky_test\.go" | cut -d" " -f1 | grep -v "endtoend") -flaky_tests=$(echo "$packages_with_tests" | grep -E ".+ .+_flaky_test\.go" | cut -d" " -f1) - -# Run non-flaky tests. -echo "$all_except_flaky_tests" | xargs go test $VT_GO_PARALLEL -v -race -count=1 -if [ $? -ne 0 ]; then - echo "ERROR: Go unit tests failed. See above for errors." - echo - echo "This should NOT happen. Did you introduce a flaky unit test?" - echo "If so, please rename it to the suffix _flaky_test.go." - exit 1 -fi - -echo '# Flaky tests (3 attempts permitted)' - -# Run flaky tests sequentially. Retry when necessary. -for pkg in $flaky_tests; do - max_attempts=3 - attempt=1 - # Set a timeout because some tests may deadlock when they flake. - until go test -timeout 5m $VT_GO_PARALLEL $pkg -v -race -count=1; do - echo "FAILED (try $attempt/$max_attempts) in $pkg (return code $?). See above for errors." - if [ $((++attempt)) -gt $max_attempts ]; then - echo "ERROR: Flaky Go unit tests in package $pkg failed too often (after $max_attempts retries). Please reduce the flakiness." - exit 1 - fi - done -done - diff --git a/tools/unit_test_runner.sh b/tools/unit_test_runner.sh index efcd03aec0c..d1790c0b394 100755 --- a/tools/unit_test_runner.sh +++ b/tools/unit_test_runner.sh @@ -36,6 +36,12 @@ if [[ -z $VT_GO_PARALLEL && -n $VT_GO_PARALLEL_VALUE ]]; then VT_GO_PARALLEL="-p $VT_GO_PARALLEL_VALUE" fi +# Enable race detector if RACE=1 +RACE_FLAG="" +if [[ "$RACE" == "1" ]]; then + RACE_FLAG="-race" +fi + # Mac makes long temp directories for os.TempDir(). MySQL can't connect to # sockets in those directories. Tell Golang to use /tmp/vttest_XXXXXX instead. kernel="$(uname -s)" @@ -68,7 +74,7 @@ all_except_flaky_tests=$(echo "$packages_with_tests" | grep -vE ".+ .+_flaky_tes flaky_tests=$(echo "$packages_with_tests" | grep -E ".+ .+_flaky_test\.go" | cut -d" " -f1) # Run non-flaky tests. -echo "$all_except_flaky_tests" | xargs go test $VT_GO_PARALLEL -v -count=1 +go test $VT_GO_PARALLEL $RACE_FLAG -v -count=1 $all_except_flaky_tests if [ $? -ne 0 ]; then echo "ERROR: Go unit tests failed. See above for errors." echo @@ -84,7 +90,7 @@ for pkg in $flaky_tests; do max_attempts=3 attempt=1 # Set a timeout because some tests may deadlock when they flake. - until go test -timeout 5m $VT_GO_PARALLEL $pkg -v -count=1; do + until go test -timeout 5m $VT_GO_PARALLEL $RACE_FLAG $pkg -v -count=1; do echo "FAILED (try $attempt/$max_attempts) in $pkg (return code $?). See above for errors." if [ $((++attempt)) -gt $max_attempts ]; then echo "ERROR: Flaky Go unit tests in package $pkg failed too often (after $max_attempts retries). Please reduce the flakiness." From c96c5025945a3cc47d8ceea1bc763e6572161086 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Thu, 5 Feb 2026 10:46:26 -0500 Subject: [PATCH 046/112] [release-22.0] Run tests with gotestsum (#19076) (#19292) Signed-off-by: Mohamed Hamza Co-authored-by: Mohamed Hamza --- .github/workflows/codeql_analysis.yml | 7 +- .github/workflows/unit_race.yml | 19 ++-- .github/workflows/unit_race_evalengine.yml | 19 ++-- .../unit_test_evalengine_mysql57.yml | 19 ++-- .../unit_test_evalengine_mysql80.yml | 19 ++-- .../unit_test_evalengine_mysql84.yml | 19 ++-- .github/workflows/unit_test_mysql57.yml | 19 ++-- .github/workflows/unit_test_mysql80.yml | 19 ++-- .github/workflows/unit_test_mysql84.yml | 19 ++-- test/templates/unit_test.tpl | 19 ++-- tools/e2e_test_runner.sh | 34 +++---- tools/unit_test_runner.sh | 89 +++++++------------ 12 files changed, 133 insertions(+), 168 deletions(-) diff --git a/.github/workflows/codeql_analysis.yml b/.github/workflows/codeql_analysis.yml index 19af0674bd0..842bcaf6026 100644 --- a/.github/workflows/codeql_analysis.yml +++ b/.github/workflows/codeql_analysis.yml @@ -62,12 +62,9 @@ jobs: sudo DEBIAN_FRONTEND="noninteractive" apt-get update # Install everything else we need, and configure sudo apt-get install -y make unzip g++ etcd-client etcd-server curl git wget - + sudo service etcd stop - - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - + - name: Building binaries timeout-minutes: 30 run: | diff --git a/.github/workflows/unit_race.yml b/.github/workflows/unit_race.yml index f769afe70cd..5eb6e00c622 100644 --- a/.github/workflows/unit_race.yml +++ b/.github/workflows/unit_race.yml @@ -91,9 +91,6 @@ jobs: go mod download go install golang.org/x/tools/cmd/goimports@latest - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Run make tools if: steps.changes.outputs.unit_tests == 'true' run: | @@ -126,7 +123,7 @@ jobs: # testing, e.g. MySQL 5.7 vs 8.0. export CI_DB_PLATFORM="mysql80" - make unit_test_race | tee -a output.txt | go-junit-report -set-exit-code > report.xml + JUNIT_OUTPUT=report.xml JSON_OUTPUT=report.json make unit_test_race - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' && !cancelled() @@ -134,15 +131,17 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.unit_tests == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: paths: "report.xml" show: "fail" + + - name: Slowest Tests + if: steps.changes.outputs.unit_tests == 'true' && !cancelled() + run: | + echo '## Slowest Tests' >> "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" + go tool gotestsum tool slowest --num 20 --jsonfile report.json | tee -a "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/unit_race_evalengine.yml b/.github/workflows/unit_race_evalengine.yml index c7a61a09bf1..d1f097b08e7 100644 --- a/.github/workflows/unit_race_evalengine.yml +++ b/.github/workflows/unit_race_evalengine.yml @@ -91,9 +91,6 @@ jobs: go mod download go install golang.org/x/tools/cmd/goimports@latest - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Run make tools if: steps.changes.outputs.unit_tests == 'true' run: | @@ -126,7 +123,7 @@ jobs: # testing, e.g. MySQL 5.7 vs 8.0. export CI_DB_PLATFORM="mysql80" - make unit_test_race | tee -a output.txt | go-junit-report -set-exit-code > report.xml + JUNIT_OUTPUT=report.xml JSON_OUTPUT=report.json make unit_test_race - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' && !cancelled() @@ -134,15 +131,17 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.unit_tests == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: paths: "report.xml" show: "fail" + + - name: Slowest Tests + if: steps.changes.outputs.unit_tests == 'true' && !cancelled() + run: | + echo '## Slowest Tests' >> "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" + go tool gotestsum tool slowest --num 20 --jsonfile report.json | tee -a "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/unit_test_evalengine_mysql57.yml b/.github/workflows/unit_test_evalengine_mysql57.yml index 021ee59839d..04be8d16ce7 100644 --- a/.github/workflows/unit_test_evalengine_mysql57.yml +++ b/.github/workflows/unit_test_evalengine_mysql57.yml @@ -91,9 +91,6 @@ jobs: go mod download go install golang.org/x/tools/cmd/goimports@latest - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Run make tools if: steps.changes.outputs.unit_tests == 'true' run: | @@ -126,7 +123,7 @@ jobs: # testing, e.g. MySQL 5.7 vs 8.0. export CI_DB_PLATFORM="mysql57" - make unit_test | tee -a output.txt | go-junit-report -set-exit-code > report.xml + JUNIT_OUTPUT=report.xml JSON_OUTPUT=report.json make unit_test - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' && !cancelled() @@ -134,15 +131,17 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.unit_tests == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: paths: "report.xml" show: "fail" + + - name: Slowest Tests + if: steps.changes.outputs.unit_tests == 'true' && !cancelled() + run: | + echo '## Slowest Tests' >> "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" + go tool gotestsum tool slowest --num 20 --jsonfile report.json | tee -a "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/unit_test_evalengine_mysql80.yml b/.github/workflows/unit_test_evalengine_mysql80.yml index e73e593975f..791931d2abe 100644 --- a/.github/workflows/unit_test_evalengine_mysql80.yml +++ b/.github/workflows/unit_test_evalengine_mysql80.yml @@ -91,9 +91,6 @@ jobs: go mod download go install golang.org/x/tools/cmd/goimports@latest - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Run make tools if: steps.changes.outputs.unit_tests == 'true' run: | @@ -126,7 +123,7 @@ jobs: # testing, e.g. MySQL 5.7 vs 8.0. export CI_DB_PLATFORM="mysql80" - make unit_test | tee -a output.txt | go-junit-report -set-exit-code > report.xml + JUNIT_OUTPUT=report.xml JSON_OUTPUT=report.json make unit_test - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' && !cancelled() @@ -134,15 +131,17 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.unit_tests == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: paths: "report.xml" show: "fail" + + - name: Slowest Tests + if: steps.changes.outputs.unit_tests == 'true' && !cancelled() + run: | + echo '## Slowest Tests' >> "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" + go tool gotestsum tool slowest --num 20 --jsonfile report.json | tee -a "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/unit_test_evalengine_mysql84.yml b/.github/workflows/unit_test_evalengine_mysql84.yml index fd1dca75ef9..f5083f28635 100644 --- a/.github/workflows/unit_test_evalengine_mysql84.yml +++ b/.github/workflows/unit_test_evalengine_mysql84.yml @@ -91,9 +91,6 @@ jobs: go mod download go install golang.org/x/tools/cmd/goimports@latest - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Run make tools if: steps.changes.outputs.unit_tests == 'true' run: | @@ -126,7 +123,7 @@ jobs: # testing, e.g. MySQL 5.7 vs 8.0. export CI_DB_PLATFORM="mysql84" - make unit_test | tee -a output.txt | go-junit-report -set-exit-code > report.xml + JUNIT_OUTPUT=report.xml JSON_OUTPUT=report.json make unit_test - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' && !cancelled() @@ -134,15 +131,17 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.unit_tests == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: paths: "report.xml" show: "fail" + + - name: Slowest Tests + if: steps.changes.outputs.unit_tests == 'true' && !cancelled() + run: | + echo '## Slowest Tests' >> "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" + go tool gotestsum tool slowest --num 20 --jsonfile report.json | tee -a "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/unit_test_mysql57.yml b/.github/workflows/unit_test_mysql57.yml index d4480b4b441..ad3acd3121b 100644 --- a/.github/workflows/unit_test_mysql57.yml +++ b/.github/workflows/unit_test_mysql57.yml @@ -91,9 +91,6 @@ jobs: go mod download go install golang.org/x/tools/cmd/goimports@latest - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Run make tools if: steps.changes.outputs.unit_tests == 'true' run: | @@ -126,7 +123,7 @@ jobs: # testing, e.g. MySQL 5.7 vs 8.0. export CI_DB_PLATFORM="mysql57" - make unit_test | tee -a output.txt | go-junit-report -set-exit-code > report.xml + JUNIT_OUTPUT=report.xml JSON_OUTPUT=report.json make unit_test - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' && !cancelled() @@ -134,15 +131,17 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.unit_tests == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: paths: "report.xml" show: "fail" + + - name: Slowest Tests + if: steps.changes.outputs.unit_tests == 'true' && !cancelled() + run: | + echo '## Slowest Tests' >> "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" + go tool gotestsum tool slowest --num 20 --jsonfile report.json | tee -a "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/unit_test_mysql80.yml b/.github/workflows/unit_test_mysql80.yml index 12c635976f7..242f74e499c 100644 --- a/.github/workflows/unit_test_mysql80.yml +++ b/.github/workflows/unit_test_mysql80.yml @@ -91,9 +91,6 @@ jobs: go mod download go install golang.org/x/tools/cmd/goimports@latest - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Run make tools if: steps.changes.outputs.unit_tests == 'true' run: | @@ -126,7 +123,7 @@ jobs: # testing, e.g. MySQL 5.7 vs 8.0. export CI_DB_PLATFORM="mysql80" - make unit_test | tee -a output.txt | go-junit-report -set-exit-code > report.xml + JUNIT_OUTPUT=report.xml JSON_OUTPUT=report.json make unit_test - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' && !cancelled() @@ -134,15 +131,17 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.unit_tests == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: paths: "report.xml" show: "fail" + + - name: Slowest Tests + if: steps.changes.outputs.unit_tests == 'true' && !cancelled() + run: | + echo '## Slowest Tests' >> "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" + go tool gotestsum tool slowest --num 20 --jsonfile report.json | tee -a "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/unit_test_mysql84.yml b/.github/workflows/unit_test_mysql84.yml index 69c6550b38d..dfe2b50ac8e 100644 --- a/.github/workflows/unit_test_mysql84.yml +++ b/.github/workflows/unit_test_mysql84.yml @@ -91,9 +91,6 @@ jobs: go mod download go install golang.org/x/tools/cmd/goimports@latest - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Run make tools if: steps.changes.outputs.unit_tests == 'true' run: | @@ -126,7 +123,7 @@ jobs: # testing, e.g. MySQL 5.7 vs 8.0. export CI_DB_PLATFORM="mysql84" - make unit_test | tee -a output.txt | go-junit-report -set-exit-code > report.xml + JUNIT_OUTPUT=report.xml JSON_OUTPUT=report.json make unit_test - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' && !cancelled() @@ -134,15 +131,17 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.unit_tests == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: paths: "report.xml" show: "fail" + + - name: Slowest Tests + if: steps.changes.outputs.unit_tests == 'true' && !cancelled() + run: | + echo '## Slowest Tests' >> "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" + go tool gotestsum tool slowest --num 20 --jsonfile report.json | tee -a "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" diff --git a/test/templates/unit_test.tpl b/test/templates/unit_test.tpl index de5f193f02f..a2097ac3c3d 100644 --- a/test/templates/unit_test.tpl +++ b/test/templates/unit_test.tpl @@ -104,9 +104,6 @@ jobs: go mod download go install golang.org/x/tools/cmd/goimports@latest - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - name: Run make tools if: steps.changes.outputs.unit_tests == 'true' run: | @@ -139,7 +136,7 @@ jobs: # testing, e.g. MySQL 5.7 vs 8.0. export CI_DB_PLATFORM="{{.Platform}}" - make {{if .Race}}unit_test_race{{else}}unit_test{{end}} | tee -a output.txt | go-junit-report -set-exit-code > report.xml + JUNIT_OUTPUT=report.xml JSON_OUTPUT=report.json make {{if .Race}}unit_test_race{{else}}unit_test{{end}} - name: Record test results in launchable if PR is not a draft if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' && !cancelled() @@ -147,15 +144,17 @@ jobs: # send recorded tests to launchable launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - name: Print test output - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - name: Test Summary if: steps.changes.outputs.unit_tests == 'true' && !cancelled() uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 with: paths: "report.xml" show: "fail" + + - name: Slowest Tests + if: steps.changes.outputs.unit_tests == 'true' && !cancelled() + run: | + echo '## Slowest Tests' >> "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" + go tool gotestsum tool slowest --num 20 --jsonfile report.json | tee -a "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" diff --git a/tools/e2e_test_runner.sh b/tools/e2e_test_runner.sh index 1fc5c2cb558..8d97a89bbb4 100755 --- a/tools/e2e_test_runner.sh +++ b/tools/e2e_test_runner.sh @@ -33,7 +33,7 @@ source build.env if [[ -z $VT_GO_PARALLEL && -n $VT_GO_PARALLEL_VALUE ]]; then - VT_GO_PARALLEL="-p $VT_GO_PARALLEL_VALUE" + VT_GO_PARALLEL="-p $VT_GO_PARALLEL_VALUE" fi # All Go packages with test files. @@ -41,29 +41,29 @@ fi packages_with_tests=$(go list -f '{{if len .TestGoFiles}}{{.ImportPath}} {{join .TestGoFiles " "}}{{end}}{{if len .XTestGoFiles}}{{.ImportPath}} {{join .XTestGoFiles " "}}{{end}}' ./go/.../endtoend/... | sort) # Flaky tests have the suffix "_flaky_test.go". -all_except_flaky_and_cluster_tests=$(echo "$packages_with_tests" | grep -vE ".+ .+_flaky_test\.go" | grep -vE "go/test/endtoend" | cut -d" " -f1) +all_except_flaky_and_cluster_tests=$(echo "$packages_with_tests" | grep -vE ".+ .+_flaky_test\.go" | grep -vE "go/test/endtoend" | cut -d" " -f1) flaky_tests=$(echo "$packages_with_tests" | grep -E ".+ .+_flaky_test\.go" | grep -vE "go/test/endtoend" | cut -d" " -f1) # Run non-flaky tests. echo "$all_except_flaky_and_cluster_tests" | xargs go test -count=1 $VT_GO_PARALLEL if [ $? -ne 0 ]; then - echo "ERROR: Go unit tests failed. See above for errors." - echo - echo "This should NOT happen. Did you introduce a flaky unit test?" - echo "If so, please rename it to the suffix _flaky_test.go." - exit 1 + echo "ERROR: Go unit tests failed. See above for errors." + echo + echo "This should NOT happen. Did you introduce a flaky unit test?" + echo "If so, please rename it to the suffix _flaky_test.go." + exit 1 fi # Run flaky tests sequentially. Retry when necessary. for pkg in $flaky_tests; do - max_attempts=3 - attempt=1 - # Set a timeout because some tests may deadlock when they flake. - until go test -timeout 30s $VT_GO_PARALLEL $pkg; do - echo "FAILED (try $attempt/$max_attempts) in $pkg (return code $?). See above for errors." - if [ $((++attempt)) -gt $max_attempts ]; then - echo "ERROR: Flaky Go unit tests in package $pkg failed too often (after $max_attempts retries). Please reduce the flakiness." - exit 1 - fi - done + max_attempts=3 + attempt=1 + # Set a timeout because some tests may deadlock when they flake. + until go test -timeout 30s $VT_GO_PARALLEL $pkg; do + echo "FAILED (try $attempt/$max_attempts) in $pkg (return code $?). See above for errors." + if [ $((++attempt)) -gt $max_attempts ]; then + echo "ERROR: Flaky Go unit tests in package $pkg failed too often (after $max_attempts retries). Please reduce the flakiness." + exit 1 + fi + done done diff --git a/tools/unit_test_runner.sh b/tools/unit_test_runner.sh index d1790c0b394..f9dadc74ddc 100755 --- a/tools/unit_test_runner.sh +++ b/tools/unit_test_runner.sh @@ -1,30 +1,21 @@ #!/bin/bash # Copyright 2019 The Vitess Authors. -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -# Custom Go unit test runner which runs all unit tests in parallel except for -# known flaky unit tests. -# Flaky unit tests are run sequentially in the second phase and retried up to -# three times. - -# Why are there flaky unit tests? -# -# Some of the Go unit tests are inherently flaky e.g. because they use the -# real timer implementation and might fail when things take longer as usual. -# In particular, this happens when the system is under load and threads do not -# get scheduled as fast as usual. Then, the expected timings do not match. +# Custom Go unit test runner which runs all unit tests using gotestsum. Failed tests are +# automatically retried up to 3 times to handle flaky tests. # Set VT_GO_PARALLEL variable in the same way as the Makefile does. # We repeat this here because this script is called directly by test.go @@ -33,7 +24,13 @@ source build.env if [[ -z $VT_GO_PARALLEL && -n $VT_GO_PARALLEL_VALUE ]]; then - VT_GO_PARALLEL="-p $VT_GO_PARALLEL_VALUE" + VT_GO_PARALLEL="-p $VT_GO_PARALLEL_VALUE" +fi + +# Enable race detector if RACE=1 +RACE_FLAG="" +if [[ "$RACE" == "1" ]]; then + RACE_FLAG="-race" fi # Enable race detector if RACE=1 @@ -46,55 +43,35 @@ fi # sockets in those directories. Tell Golang to use /tmp/vttest_XXXXXX instead. kernel="$(uname -s)" case "$kernel" in - darwin|Darwin) - TMPDIR=${TMPDIR:-} - if [ -z "$TMPDIR" ]; then - TMPDIR="$(mktemp -d /tmp/vttest_XXXXXX)" - export TMPDIR - fi - echo "Using temporary directory for tests: $TMPDIR" - ;; +darwin | Darwin) + TMPDIR=${TMPDIR:-} + if [ -z "$TMPDIR" ]; then + TMPDIR="$(mktemp -d /tmp/vttest_XXXXXX)" + export TMPDIR + fi + echo "Using temporary directory for tests: $TMPDIR" + ;; esac -# All Go packages with test files. -# Output per line: * -packages_with_tests=$(go list -f '{{if len .TestGoFiles}}{{.ImportPath}} {{join .TestGoFiles " "}}{{end}}{{if len .XTestGoFiles}}{{.ImportPath}} {{join .XTestGoFiles " "}}{{end}}' ./go/... | sort) +# All Go packages with test files, excluding endtoend tests. +packages_with_tests=$(go list ./go/... | grep -v endtoend) if [[ "$VTEVALENGINETEST" == "1" ]]; then - packages_with_tests=$(echo "$packages_with_tests" | grep "evalengine") + packages_with_tests=$(echo "$packages_with_tests" | grep "evalengine") fi if [[ "$VTEVALENGINETEST" == "0" ]]; then - packages_with_tests=$(echo "$packages_with_tests" | grep -v "evalengine") + packages_with_tests=$(echo "$packages_with_tests" | grep -v "evalengine") fi -# Flaky tests have the suffix "_flaky_test.go". -# Exclude endtoend tests -all_except_flaky_tests=$(echo "$packages_with_tests" | grep -vE ".+ .+_flaky_test\.go" | cut -d" " -f1 | grep -v "endtoend") -flaky_tests=$(echo "$packages_with_tests" | grep -E ".+ .+_flaky_test\.go" | cut -d" " -f1) - -# Run non-flaky tests. -go test $VT_GO_PARALLEL $RACE_FLAG -v -count=1 $all_except_flaky_tests -if [ $? -ne 0 ]; then - echo "ERROR: Go unit tests failed. See above for errors." - echo - echo "This should NOT happen. Did you introduce a flaky unit test?" - echo "If so, please rename it to the suffix _flaky_test.go." - exit 1 +# Build gotestsum args. Failed tests are retried up to 3 times, but if more than 10 tests fail +# initially we skip retries to avoid wasting time on a real widespread failure. +GOTESTSUM_ARGS="--format github-actions --rerun-fails=3 --rerun-fails-max-failures=10 --rerun-fails-run-root-test --format-hide-empty-pkg --hide-summary=skipped" +if [[ -n "${JUNIT_OUTPUT:-}" ]]; then + GOTESTSUM_ARGS="$GOTESTSUM_ARGS --junitfile $JUNIT_OUTPUT" +fi +if [[ -n "${JSON_OUTPUT:-}" ]]; then + GOTESTSUM_ARGS="$GOTESTSUM_ARGS --jsonfile $JSON_OUTPUT" fi -echo '# Flaky tests (3 attempts permitted)' - -# Run flaky tests sequentially. Retry when necessary. -for pkg in $flaky_tests; do - max_attempts=3 - attempt=1 - # Set a timeout because some tests may deadlock when they flake. - until go test -timeout 5m $VT_GO_PARALLEL $RACE_FLAG $pkg -v -count=1; do - echo "FAILED (try $attempt/$max_attempts) in $pkg (return code $?). See above for errors." - if [ $((++attempt)) -gt $max_attempts ]; then - echo "ERROR: Flaky Go unit tests in package $pkg failed too often (after $max_attempts retries). Please reduce the flakiness." - exit 1 - fi - done -done +go tool gotestsum $GOTESTSUM_ARGS --packages="$packages_with_tests" -- $VT_GO_PARALLEL $RACE_FLAG -count=1 From 5f70f6434cf7e8f04b94b7dc2d7979cc4fba8522 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Thu, 5 Feb 2026 13:07:22 -0500 Subject: [PATCH 047/112] [release-22.0] Consolidate CI test workflows (#19259) (#19272) Signed-off-by: Mohamed Hamza Co-authored-by: Mohamed Hamza --- .github/workflows/cluster_endtoend.yml | 260 + .github/workflows/cluster_endtoend_12.yml | 136 - .github/workflows/cluster_endtoend_13.yml | 136 - .github/workflows/cluster_endtoend_15.yml | 136 - .github/workflows/cluster_endtoend_18.yml | 141 - .github/workflows/cluster_endtoend_21.yml | 142 - .../cluster_endtoend_backup_pitr.yml | 136 - ...luster_endtoend_backup_pitr_mysqlshell.yml | 136 - ...luster_endtoend_backup_pitr_xtrabackup.yml | 145 - ...ter_endtoend_ers_prs_newfeatures_heavy.yml | 154 - .../workflows/cluster_endtoend_mysql80.yml | 136 - .../cluster_endtoend_mysql_server_vault.yml | 141 - .../cluster_endtoend_onlineddl_revert.yml | 137 - .../cluster_endtoend_onlineddl_scheduler.yml | 137 - .../cluster_endtoend_onlineddl_vrepl.yml | 145 - ...luster_endtoend_onlineddl_vrepl_stress.yml | 145 - ..._endtoend_onlineddl_vrepl_stress_suite.yml | 145 - ...cluster_endtoend_onlineddl_vrepl_suite.yml | 145 - .../cluster_endtoend_schemadiff_vrepl.yml | 145 - .../cluster_endtoend_tabletmanager_consul.yml | 141 - ...cluster_endtoend_tabletmanager_tablegc.yml | 136 - ..._endtoend_tabletmanager_throttler_topo.yml | 136 - ...cluster_endtoend_topo_connection_cache.yml | 136 - ...dtoend_vreplication_across_db_versions.yml | 162 - .../cluster_endtoend_vreplication_basic.yml | 162 - ...luster_endtoend_vreplication_cellalias.yml | 162 - ...er_endtoend_vreplication_copy_parallel.yml | 162 - ...dtoend_vreplication_foreign_key_stress.yml | 162 - ...endtoend_vreplication_mariadb_to_mysql.yml | 162 - .../cluster_endtoend_vreplication_migrate.yml | 162 - ...ter_endtoend_vreplication_multi_tenant.yml | 162 - ...ion_partial_movetables_and_materialize.yml | 162 - .../cluster_endtoend_vreplication_v2.yml | 162 - .../cluster_endtoend_vreplication_vdiff2.yml | 162 - ...replication_vtctldclient_movetables_tz.yml | 162 - .../workflows/cluster_endtoend_vstream.yml | 136 - .../workflows/cluster_endtoend_vtbackup.yml | 136 - ..._vtctlbackup_sharded_clustertest_heavy.yml | 154 - .../cluster_endtoend_vtgate_concurrentdml.yml | 136 - ...ster_endtoend_vtgate_foreignkey_stress.yml | 136 - .../cluster_endtoend_vtgate_gen4.yml | 136 - .../cluster_endtoend_vtgate_general_heavy.yml | 154 - .../cluster_endtoend_vtgate_godriver.yml | 136 - ...uster_endtoend_vtgate_partial_keyspace.yml | 136 - .../cluster_endtoend_vtgate_plantests.yml | 136 - .../cluster_endtoend_vtgate_queries.yml | 136 - ...cluster_endtoend_vtgate_readafterwrite.yml | 136 - .../cluster_endtoend_vtgate_reservedconn.yml | 136 - .../cluster_endtoend_vtgate_schema.yml | 136 - ...cluster_endtoend_vtgate_schema_tracker.yml | 136 - ...dtoend_vtgate_tablet_healthcheck_cache.yml | 136 - .../cluster_endtoend_vtgate_topo.yml | 136 - .../cluster_endtoend_vtgate_topo_consul.yml | 141 - .../cluster_endtoend_vtgate_topo_etcd.yml | 136 - .../cluster_endtoend_vtgate_transaction.yml | 136 - .../cluster_endtoend_vtgate_unsharded.yml | 136 - .../cluster_endtoend_vtgate_vindex_heavy.yml | 154 - .../cluster_endtoend_vtgate_vschema.yml | 136 - .github/workflows/cluster_endtoend_vtorc.yml | 145 - .../cluster_endtoend_vttablet_prscomplex.yml | 136 - .../workflows/cluster_endtoend_xb_backup.yml | 145 - .../cluster_endtoend_xb_recovery.yml | 145 - .github/workflows/static_checks_etc.yml | 14 +- .github/workflows/unit_race.yml | 147 - .github/workflows/unit_race_evalengine.yml | 147 - .github/workflows/unit_test.yml | 194 + .../unit_test_evalengine_mysql57.yml | 147 - .../unit_test_evalengine_mysql80.yml | 147 - .../unit_test_evalengine_mysql84.yml | 147 - .github/workflows/unit_test_mysql57.yml | 147 - .github/workflows/unit_test_mysql80.yml | 147 - .github/workflows/unit_test_mysql84.yml | 147 - .github/workflows/vitess_tester_vtgate.yml | 2 - Makefile | 8 +- test/README.md | 28 +- test/ci_workflow_gen.go | 450 -- test/config.json | 4502 +++++++++-------- test/templates/cluster_endtoend_test.tpl | 231 - .../cluster_endtoend_test_docker.tpl | 88 - .../cluster_endtoend_test_mysql57.tpl | 211 - test/templates/cluster_vitess_tester.tpl | 162 - test/templates/dockerfile.tpl | 48 - test/templates/unit_test.tpl | 160 - 83 files changed, 2891 insertions(+), 13432 deletions(-) create mode 100644 .github/workflows/cluster_endtoend.yml delete mode 100644 .github/workflows/cluster_endtoend_12.yml delete mode 100644 .github/workflows/cluster_endtoend_13.yml delete mode 100644 .github/workflows/cluster_endtoend_15.yml delete mode 100644 .github/workflows/cluster_endtoend_18.yml delete mode 100644 .github/workflows/cluster_endtoend_21.yml delete mode 100644 .github/workflows/cluster_endtoend_backup_pitr.yml delete mode 100644 .github/workflows/cluster_endtoend_backup_pitr_mysqlshell.yml delete mode 100644 .github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml delete mode 100644 .github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml delete mode 100644 .github/workflows/cluster_endtoend_mysql80.yml delete mode 100644 .github/workflows/cluster_endtoend_mysql_server_vault.yml delete mode 100644 .github/workflows/cluster_endtoend_onlineddl_revert.yml delete mode 100644 .github/workflows/cluster_endtoend_onlineddl_scheduler.yml delete mode 100644 .github/workflows/cluster_endtoend_onlineddl_vrepl.yml delete mode 100644 .github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml delete mode 100644 .github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml delete mode 100644 .github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml delete mode 100644 .github/workflows/cluster_endtoend_schemadiff_vrepl.yml delete mode 100644 .github/workflows/cluster_endtoend_tabletmanager_consul.yml delete mode 100644 .github/workflows/cluster_endtoend_tabletmanager_tablegc.yml delete mode 100644 .github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml delete mode 100644 .github/workflows/cluster_endtoend_topo_connection_cache.yml delete mode 100644 .github/workflows/cluster_endtoend_vreplication_across_db_versions.yml delete mode 100644 .github/workflows/cluster_endtoend_vreplication_basic.yml delete mode 100644 .github/workflows/cluster_endtoend_vreplication_cellalias.yml delete mode 100644 .github/workflows/cluster_endtoend_vreplication_copy_parallel.yml delete mode 100644 .github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml delete mode 100644 .github/workflows/cluster_endtoend_vreplication_mariadb_to_mysql.yml delete mode 100644 .github/workflows/cluster_endtoend_vreplication_migrate.yml delete mode 100644 .github/workflows/cluster_endtoend_vreplication_multi_tenant.yml delete mode 100644 .github/workflows/cluster_endtoend_vreplication_partial_movetables_and_materialize.yml delete mode 100644 .github/workflows/cluster_endtoend_vreplication_v2.yml delete mode 100644 .github/workflows/cluster_endtoend_vreplication_vdiff2.yml delete mode 100644 .github/workflows/cluster_endtoend_vreplication_vtctldclient_movetables_tz.yml delete mode 100644 .github/workflows/cluster_endtoend_vstream.yml delete mode 100644 .github/workflows/cluster_endtoend_vtbackup.yml delete mode 100644 .github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml delete mode 100644 .github/workflows/cluster_endtoend_vtgate_concurrentdml.yml delete mode 100644 .github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml delete mode 100644 .github/workflows/cluster_endtoend_vtgate_gen4.yml delete mode 100644 .github/workflows/cluster_endtoend_vtgate_general_heavy.yml delete mode 100644 .github/workflows/cluster_endtoend_vtgate_godriver.yml delete mode 100644 .github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml delete mode 100644 .github/workflows/cluster_endtoend_vtgate_plantests.yml delete mode 100644 .github/workflows/cluster_endtoend_vtgate_queries.yml delete mode 100644 .github/workflows/cluster_endtoend_vtgate_readafterwrite.yml delete mode 100644 .github/workflows/cluster_endtoend_vtgate_reservedconn.yml delete mode 100644 .github/workflows/cluster_endtoend_vtgate_schema.yml delete mode 100644 .github/workflows/cluster_endtoend_vtgate_schema_tracker.yml delete mode 100644 .github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml delete mode 100644 .github/workflows/cluster_endtoend_vtgate_topo.yml delete mode 100644 .github/workflows/cluster_endtoend_vtgate_topo_consul.yml delete mode 100644 .github/workflows/cluster_endtoend_vtgate_topo_etcd.yml delete mode 100644 .github/workflows/cluster_endtoend_vtgate_transaction.yml delete mode 100644 .github/workflows/cluster_endtoend_vtgate_unsharded.yml delete mode 100644 .github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml delete mode 100644 .github/workflows/cluster_endtoend_vtgate_vschema.yml delete mode 100644 .github/workflows/cluster_endtoend_vtorc.yml delete mode 100644 .github/workflows/cluster_endtoend_vttablet_prscomplex.yml delete mode 100644 .github/workflows/cluster_endtoend_xb_backup.yml delete mode 100644 .github/workflows/cluster_endtoend_xb_recovery.yml delete mode 100644 .github/workflows/unit_race.yml delete mode 100644 .github/workflows/unit_race_evalengine.yml create mode 100644 .github/workflows/unit_test.yml delete mode 100644 .github/workflows/unit_test_evalengine_mysql57.yml delete mode 100644 .github/workflows/unit_test_evalengine_mysql80.yml delete mode 100644 .github/workflows/unit_test_evalengine_mysql84.yml delete mode 100644 .github/workflows/unit_test_mysql57.yml delete mode 100644 .github/workflows/unit_test_mysql80.yml delete mode 100644 .github/workflows/unit_test_mysql84.yml delete mode 100644 test/ci_workflow_gen.go delete mode 100644 test/templates/cluster_endtoend_test.tpl delete mode 100644 test/templates/cluster_endtoend_test_docker.tpl delete mode 100644 test/templates/cluster_endtoend_test_mysql57.tpl delete mode 100644 test/templates/cluster_vitess_tester.tpl delete mode 100644 test/templates/dockerfile.tpl delete mode 100644 test/templates/unit_test.tpl diff --git a/.github/workflows/cluster_endtoend.yml b/.github/workflows/cluster_endtoend.yml new file mode 100644 index 00000000000..d15a6bf47b0 --- /dev/null +++ b/.github/workflows/cluster_endtoend.yml @@ -0,0 +1,260 @@ +name: Cluster End-to-End Tests + +on: + push: + branches: + - "main" + - "release-[0-9]+.[0-9]" + tags: "**" + pull_request: + branches: "**" + +concurrency: + group: format('{0}-{1}', ${{ github.ref }}, 'Cluster End-to-End Tests') + cancel-in-progress: true + +permissions: read-all + +env: + LAUNCHABLE_ORGANIZATION: "vitess" + LAUNCHABLE_WORKSPACE: "vitess-app" + GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" + +jobs: + generate-matrix: + runs-on: ubuntu-24.04 + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - name: Check out code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: "false" + + - name: Generate shard matrix + id: set-matrix + run: | + # Shards to exclude from this workflow. + # Modify this list to add or remove shards from the cluster end-to-end tests. + # These are either: + # - Run in other dedicated workflows + # - Not cluster tests (unit tests, examples, etc.) + # - Special upgrade/downgrade tests + EXCLUDE_SHARDS='[ + "", + "java", + "docker_cluster", + "5", + "28", + "onlineddl_flow" + ]' + + # Build matrix + matrix=$(jq -c -s --argjson exclude "$EXCLUDE_SHARDS" ' + map(.Tests) | add | to_entries + | group_by(.value.Shard) + | map(select(.[0].value.Shard as $s | ($s != null) and ($exclude | index($s) | not))) + | map({ + shard: .[0].value.Shard, + needs: ([.[].value.Needs // []] | add | unique // []), + buildTag: ([.[].value.BuildTag // null] | map(select(. != null)) | first // "") + }) + ' test/config.json test/config_partial_keyspace.json) + + echo "matrix={\"include\":$matrix}" >> $GITHUB_OUTPUT + + test: + needs: generate-matrix + if: needs.generate-matrix.outputs.matrix != '' + timeout-minutes: 60 + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} + + name: Run endtoend tests on Cluster (${{ matrix.shard }}) + runs-on: ${{ contains(matrix.needs, 'larger-runner') && 'gh-hosted-runners-16cores-1-24.04' || 'ubuntu-24.04' }} + + steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 + with: + egress-policy: audit + + - name: Skip CI + run: | + if [[ "${{ contains(github.event.pull_request.labels.*.name, 'Skip CI') }}" == "true" ]]; then + echo "skipping CI due to the 'Skip CI' label" + exit 1 + fi + + - name: Check Memory + if: contains(matrix.needs, 'memory-check') + run: | + totalMem=$(free -g | awk 'NR==2 {print $2}') + echo "total memory $totalMem GB" + if [[ "$totalMem" -lt 15 ]]; then + echo "Less memory than required" + exit 1 + fi + + - name: Check out code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: "false" + + - name: Check for changes in relevant files + uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 + id: changes + with: + token: "" + filters: | + end_to_end: + - 'test/config.json' + - 'test/config_partial_keyspace.json' + - 'go/**/*.go' + - 'go/vt/sidecardb/**/*.sql' + - 'go/test/endtoend/onlineddl/vrepl_suite/**' + - 'test.go' + - 'Makefile' + - 'build.env' + - 'go.sum' + - 'go.mod' + - 'proto/*.proto' + - 'tools/**' + - 'config/**' + - 'bootstrap.sh' + - '.github/workflows/cluster_endtoend.yml' + + - name: Set up Go + if: steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 + with: + go-version-file: go.mod + + - name: Set up python + if: steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + + - name: Tune the OS + if: steps.changes.outputs.end_to_end == 'true' + uses: ./.github/actions/tune-os + + - name: Setup MySQL + if: steps.changes.outputs.end_to_end == 'true' && !contains(matrix.needs, 'xtrabackup') + uses: ./.github/actions/setup-mysql + with: + flavor: mysql-8.0 + + - name: Setup Percona Server and XtraBackup + if: steps.changes.outputs.end_to_end == 'true' && contains(matrix.needs, 'xtrabackup') + run: | + sudo apt-get -qq update + sudo apt-get -qq install -y lsb-release gnupg2 + wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb + sudo DEBIAN_FRONTEND="noninteractive" dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb + sudo percona-release setup pdps8.0 + sudo apt-get -qq update + sudo apt-get -qq install -y percona-server-server percona-server-client + sudo service mysql stop + sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ + sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld + sudo apt-get -qq install -y percona-xtrabackup-80 lz4 + + - name: Get dependencies + if: steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 10 + run: | + # Install mysql-shell for non-XtraBackup shards + if [[ "${{ contains(matrix.needs, 'xtrabackup') }}" != "true" ]]; then + sudo apt-get -qq install -y mysql-shell + fi + + sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 + sudo service etcd stop + go mod download + + - name: Install Minio + if: steps.changes.outputs.end_to_end == 'true' && contains(matrix.needs, 'minio') + run: | + wget https://dl.min.io/server/minio/release/linux-amd64/minio + chmod +x minio + sudo mv minio /usr/local/bin + + - name: Install Consul and ZooKeeper + if: steps.changes.outputs.end_to_end == 'true' && contains(matrix.needs, 'consul') + run: make tools + + - name: Setup launchable dependencies + if: | + github.event_name == 'pull_request' && + github.event.pull_request.draft == false && + steps.changes.outputs.end_to_end == 'true' && + github.base_ref == 'main' + run: | + pip3 install --user launchable~=1.0 > /dev/null + launchable verify || true + launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . + + - name: Run cluster endtoend test + if: steps.changes.outputs.end_to_end == 'true' + timeout-minutes: 45 + run: | + export VTDATAROOT="/tmp/" + source build.env + set -exo pipefail + + # Apply resource limits for heavy shards + if [[ "${{ contains(matrix.needs, 'limit-resources') }}" == "true" ]]; then + ulimit -n 65536 + cat <<-EOF>>./config/mycnf/mysql84.cnf + innodb_buffer_pool_dump_at_shutdown=OFF + innodb_buffer_pool_in_core_file=OFF + innodb_buffer_pool_load_at_startup=OFF + innodb_buffer_pool_size=64M + innodb_doublewrite=OFF + innodb_flush_log_at_trx_commit=0 + innodb_flush_method=O_DIRECT + innodb_numa_interleave=ON + innodb_adaptive_hash_index=OFF + sync_binlog=0 + sync_relay_log=0 + performance_schema=OFF + slow-query-log=OFF + EOF + fi + + # Enable binlog compression for vreplication shards + if [[ "${{ contains(matrix.needs, 'binlog-compression') }}" == "true" ]]; then + cat <<-EOF>>./config/mycnf/mysql84.cnf + binlog-transaction-compression=ON + binlog-row-value-options=PARTIAL_JSON + EOF + fi + + # Build test command with optional flags + EXTRA_FLAGS="" + if [[ "${{ matrix.buildTag }}" != "" ]]; then + EXTRA_FLAGS="$EXTRA_FLAGS -build-tag=${{ matrix.buildTag }}" + fi + if [[ "${{ matrix.shard }}" == *"partial_keyspace"* ]]; then + EXTRA_FLAGS="$EXTRA_FLAGS -partial-keyspace=true" + fi + + go run test.go -docker=false -follow -shard "${{ matrix.shard }}" $EXTRA_FLAGS + + - name: Record test results in launchable + if: | + github.event_name == 'pull_request' && + github.event.pull_request.draft == false && + steps.changes.outputs.end_to_end == 'true' && + github.base_ref == 'main' && + !cancelled() + run: | + launchable record tests --build "$GITHUB_RUN_ID" go-test . || true + + - name: Test Summary + if: steps.changes.outputs.end_to_end == 'true' && failure() + uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 + with: + paths: "_test/junit/*.xml" + show: "fail" diff --git a/.github/workflows/cluster_endtoend_12.yml b/.github/workflows/cluster_endtoend_12.yml deleted file mode 100644 index 1cf4741659b..00000000000 --- a/.github/workflows/cluster_endtoend_12.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (12) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (12)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (12) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_12.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard 12 - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_13.yml b/.github/workflows/cluster_endtoend_13.yml deleted file mode 100644 index 30a0933a2b9..00000000000 --- a/.github/workflows/cluster_endtoend_13.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (13) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (13)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (13) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_13.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard 13 - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_15.yml b/.github/workflows/cluster_endtoend_15.yml deleted file mode 100644 index 7e28a499ca2..00000000000 --- a/.github/workflows/cluster_endtoend_15.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (15) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (15)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (15) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_15.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard 15 - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_18.yml b/.github/workflows/cluster_endtoend_18.yml deleted file mode 100644 index dd5f97e3735..00000000000 --- a/.github/workflows/cluster_endtoend_18.yml +++ /dev/null @@ -1,141 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (18) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (18)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (18) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_18.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Installing zookeeper and consul - if: steps.changes.outputs.end_to_end == 'true' - run: | - make tools - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard 18 - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_21.yml b/.github/workflows/cluster_endtoend_21.yml deleted file mode 100644 index a4a8ae6a490..00000000000 --- a/.github/workflows/cluster_endtoend_21.yml +++ /dev/null @@ -1,142 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (21) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (21)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (21) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_21.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Install Minio - run: | - wget https://dl.min.io/server/minio/release/linux-amd64/minio - chmod +x minio - mv minio /usr/local/bin - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard 21 - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_backup_pitr.yml b/.github/workflows/cluster_endtoend_backup_pitr.yml deleted file mode 100644 index 643cd1158ee..00000000000 --- a/.github/workflows/cluster_endtoend_backup_pitr.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (backup_pitr) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (backup_pitr)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (backup_pitr) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_backup_pitr.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard backup_pitr - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_backup_pitr_mysqlshell.yml b/.github/workflows/cluster_endtoend_backup_pitr_mysqlshell.yml deleted file mode 100644 index 797574e626a..00000000000 --- a/.github/workflows/cluster_endtoend_backup_pitr_mysqlshell.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (backup_pitr_mysqlshell) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (backup_pitr_mysqlshell)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (backup_pitr_mysqlshell) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_backup_pitr_mysqlshell.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard backup_pitr_mysqlshell - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml b/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml deleted file mode 100644 index 81b8d1ddf40..00000000000 --- a/.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml +++ /dev/null @@ -1,145 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (backup_pitr_xtrabackup) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (backup_pitr_xtrabackup)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (backup_pitr_xtrabackup) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_backup_pitr_xtrabackup.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - # Setup Percona Server for MySQL 8.0 - sudo apt-get -qq update - sudo apt-get -qq install -y lsb-release gnupg2 - wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb - sudo DEBIAN_FRONTEND="noninteractive" dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb - sudo percona-release setup pdps8.0 - sudo apt-get -qq update - - sudo apt-get -qq install -y percona-server-server percona-server-client - - sudo service mysql stop - - sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ - sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld - - sudo apt-get -qq install -y percona-xtrabackup-80 lz4 - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard backup_pitr_xtrabackup - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml b/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml deleted file mode 100644 index a8655f26122..00000000000 --- a/.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml +++ /dev/null @@ -1,154 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (ers_prs_newfeatures_heavy) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (ers_prs_newfeatures_heavy)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (ers_prs_newfeatures_heavy) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_ers_prs_newfeatures_heavy.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Increase our open file descriptor limit as we could hit this - ulimit -n 65536 - cat <<-EOF>>./config/mycnf/mysql8026.cnf - innodb_buffer_pool_dump_at_shutdown=OFF - innodb_buffer_pool_in_core_file=OFF - innodb_buffer_pool_load_at_startup=OFF - innodb_buffer_pool_size=64M - innodb_doublewrite=OFF - innodb_flush_log_at_trx_commit=0 - innodb_flush_method=O_DIRECT - innodb_numa_interleave=ON - innodb_adaptive_hash_index=OFF - sync_binlog=0 - sync_relay_log=0 - performance_schema=OFF - slow-query-log=OFF - EOF - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard ers_prs_newfeatures_heavy - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_mysql80.yml b/.github/workflows/cluster_endtoend_mysql80.yml deleted file mode 100644 index a2ab14d84a0..00000000000 --- a/.github/workflows/cluster_endtoend_mysql80.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (mysql80) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (mysql80)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (mysql80) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_mysql80.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard mysql80 - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_mysql_server_vault.yml b/.github/workflows/cluster_endtoend_mysql_server_vault.yml deleted file mode 100644 index b3bf4920b6e..00000000000 --- a/.github/workflows/cluster_endtoend_mysql_server_vault.yml +++ /dev/null @@ -1,141 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (mysql_server_vault) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (mysql_server_vault)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (mysql_server_vault) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_mysql_server_vault.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Installing zookeeper and consul - if: steps.changes.outputs.end_to_end == 'true' - run: | - make tools - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard mysql_server_vault - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_onlineddl_revert.yml b/.github/workflows/cluster_endtoend_onlineddl_revert.yml deleted file mode 100644 index 2153a3e3136..00000000000 --- a/.github/workflows/cluster_endtoend_onlineddl_revert.yml +++ /dev/null @@ -1,137 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (onlineddl_revert) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (onlineddl_revert)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (onlineddl_revert) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_onlineddl_revert.yml' - - 'go/test/endtoend/onlineddl/vrepl_suite/testdata' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard onlineddl_revert - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml b/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml deleted file mode 100644 index 825d4456c80..00000000000 --- a/.github/workflows/cluster_endtoend_onlineddl_scheduler.yml +++ /dev/null @@ -1,137 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (onlineddl_scheduler) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (onlineddl_scheduler)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (onlineddl_scheduler) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_onlineddl_scheduler.yml' - - 'go/test/endtoend/onlineddl/vrepl_suite/testdata' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard onlineddl_scheduler - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml deleted file mode 100644 index 260a8c99c6c..00000000000 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml +++ /dev/null @@ -1,145 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (onlineddl_vrepl) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (onlineddl_vrepl)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (onlineddl_vrepl) - runs-on: gh-hosted-runners-16cores-1-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_onlineddl_vrepl.yml' - - 'go/test/endtoend/onlineddl/vrepl_suite/testdata' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-transaction-compression=ON - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-row-value-options=PARTIAL_JSON - EOF - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard onlineddl_vrepl - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml deleted file mode 100644 index d8b3b08001e..00000000000 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml +++ /dev/null @@ -1,145 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (onlineddl_vrepl_stress) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (onlineddl_vrepl_stress)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (onlineddl_vrepl_stress) - runs-on: gh-hosted-runners-16cores-1-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml' - - 'go/test/endtoend/onlineddl/vrepl_suite/testdata' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-transaction-compression=ON - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-row-value-options=PARTIAL_JSON - EOF - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard onlineddl_vrepl_stress - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml deleted file mode 100644 index 32e9f7e1eb6..00000000000 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml +++ /dev/null @@ -1,145 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (onlineddl_vrepl_stress_suite) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (onlineddl_vrepl_stress_suite)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (onlineddl_vrepl_stress_suite) - runs-on: gh-hosted-runners-16cores-1-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_onlineddl_vrepl_stress_suite.yml' - - 'go/test/endtoend/onlineddl/vrepl_suite/testdata' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-transaction-compression=ON - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-row-value-options=PARTIAL_JSON - EOF - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard onlineddl_vrepl_stress_suite - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml deleted file mode 100644 index 4e4bcce683f..00000000000 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml +++ /dev/null @@ -1,145 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (onlineddl_vrepl_suite) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (onlineddl_vrepl_suite)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (onlineddl_vrepl_suite) - runs-on: gh-hosted-runners-16cores-1-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_onlineddl_vrepl_suite.yml' - - 'go/test/endtoend/onlineddl/vrepl_suite/testdata' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-transaction-compression=ON - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-row-value-options=PARTIAL_JSON - EOF - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard onlineddl_vrepl_suite - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml b/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml deleted file mode 100644 index 4119aed7e77..00000000000 --- a/.github/workflows/cluster_endtoend_schemadiff_vrepl.yml +++ /dev/null @@ -1,145 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (schemadiff_vrepl) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (schemadiff_vrepl)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (schemadiff_vrepl) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_schemadiff_vrepl.yml' - - 'go/test/endtoend/onlineddl/vrepl_suite/testdata' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-transaction-compression=ON - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-row-value-options=PARTIAL_JSON - EOF - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard schemadiff_vrepl - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_tabletmanager_consul.yml b/.github/workflows/cluster_endtoend_tabletmanager_consul.yml deleted file mode 100644 index 49567724ffc..00000000000 --- a/.github/workflows/cluster_endtoend_tabletmanager_consul.yml +++ /dev/null @@ -1,141 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (tabletmanager_consul) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (tabletmanager_consul)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (tabletmanager_consul) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_tabletmanager_consul.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Installing zookeeper and consul - if: steps.changes.outputs.end_to_end == 'true' - run: | - make tools - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard tabletmanager_consul - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml b/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml deleted file mode 100644 index 7f611b42950..00000000000 --- a/.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (tabletmanager_tablegc) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (tabletmanager_tablegc)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (tabletmanager_tablegc) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_tabletmanager_tablegc.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard tabletmanager_tablegc - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml b/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml deleted file mode 100644 index 13c5538bbee..00000000000 --- a/.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (tabletmanager_throttler_topo) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (tabletmanager_throttler_topo)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (tabletmanager_throttler_topo) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_tabletmanager_throttler_topo.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard tabletmanager_throttler_topo - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_topo_connection_cache.yml b/.github/workflows/cluster_endtoend_topo_connection_cache.yml deleted file mode 100644 index 50b04dcccdb..00000000000 --- a/.github/workflows/cluster_endtoend_topo_connection_cache.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (topo_connection_cache) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (topo_connection_cache)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (topo_connection_cache) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_topo_connection_cache.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard topo_connection_cache - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml b/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml deleted file mode 100644 index b4117ebcce5..00000000000 --- a/.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml +++ /dev/null @@ -1,162 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vreplication_across_db_versions) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vreplication_across_db_versions)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vreplication_across_db_versions) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vreplication_across_db_versions.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Increase our open file descriptor limit as we could hit this - ulimit -n 65536 - cat <<-EOF>>./config/mycnf/mysql8026.cnf - innodb_buffer_pool_dump_at_shutdown=OFF - innodb_buffer_pool_in_core_file=OFF - innodb_buffer_pool_load_at_startup=OFF - innodb_buffer_pool_size=64M - innodb_doublewrite=OFF - innodb_flush_log_at_trx_commit=0 - innodb_flush_method=O_DIRECT - innodb_numa_interleave=ON - innodb_adaptive_hash_index=OFF - sync_binlog=0 - sync_relay_log=0 - performance_schema=OFF - slow-query-log=OFF - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-transaction-compression=ON - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-row-value-options=PARTIAL_JSON - EOF - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vreplication_across_db_versions - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vreplication_basic.yml b/.github/workflows/cluster_endtoend_vreplication_basic.yml deleted file mode 100644 index 915375a623f..00000000000 --- a/.github/workflows/cluster_endtoend_vreplication_basic.yml +++ /dev/null @@ -1,162 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vreplication_basic) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vreplication_basic)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vreplication_basic) - runs-on: gh-hosted-runners-16cores-1-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vreplication_basic.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Increase our open file descriptor limit as we could hit this - ulimit -n 65536 - cat <<-EOF>>./config/mycnf/mysql8026.cnf - innodb_buffer_pool_dump_at_shutdown=OFF - innodb_buffer_pool_in_core_file=OFF - innodb_buffer_pool_load_at_startup=OFF - innodb_buffer_pool_size=64M - innodb_doublewrite=OFF - innodb_flush_log_at_trx_commit=0 - innodb_flush_method=O_DIRECT - innodb_numa_interleave=ON - innodb_adaptive_hash_index=OFF - sync_binlog=0 - sync_relay_log=0 - performance_schema=OFF - slow-query-log=OFF - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-transaction-compression=ON - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-row-value-options=PARTIAL_JSON - EOF - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vreplication_basic - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vreplication_cellalias.yml b/.github/workflows/cluster_endtoend_vreplication_cellalias.yml deleted file mode 100644 index c507334e20e..00000000000 --- a/.github/workflows/cluster_endtoend_vreplication_cellalias.yml +++ /dev/null @@ -1,162 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vreplication_cellalias) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vreplication_cellalias)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vreplication_cellalias) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vreplication_cellalias.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Increase our open file descriptor limit as we could hit this - ulimit -n 65536 - cat <<-EOF>>./config/mycnf/mysql8026.cnf - innodb_buffer_pool_dump_at_shutdown=OFF - innodb_buffer_pool_in_core_file=OFF - innodb_buffer_pool_load_at_startup=OFF - innodb_buffer_pool_size=64M - innodb_doublewrite=OFF - innodb_flush_log_at_trx_commit=0 - innodb_flush_method=O_DIRECT - innodb_numa_interleave=ON - innodb_adaptive_hash_index=OFF - sync_binlog=0 - sync_relay_log=0 - performance_schema=OFF - slow-query-log=OFF - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-transaction-compression=ON - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-row-value-options=PARTIAL_JSON - EOF - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vreplication_cellalias - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vreplication_copy_parallel.yml b/.github/workflows/cluster_endtoend_vreplication_copy_parallel.yml deleted file mode 100644 index 27e5e24098f..00000000000 --- a/.github/workflows/cluster_endtoend_vreplication_copy_parallel.yml +++ /dev/null @@ -1,162 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vreplication_copy_parallel) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vreplication_copy_parallel)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vreplication_copy_parallel) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vreplication_copy_parallel.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Increase our open file descriptor limit as we could hit this - ulimit -n 65536 - cat <<-EOF>>./config/mycnf/mysql8026.cnf - innodb_buffer_pool_dump_at_shutdown=OFF - innodb_buffer_pool_in_core_file=OFF - innodb_buffer_pool_load_at_startup=OFF - innodb_buffer_pool_size=64M - innodb_doublewrite=OFF - innodb_flush_log_at_trx_commit=0 - innodb_flush_method=O_DIRECT - innodb_numa_interleave=ON - innodb_adaptive_hash_index=OFF - sync_binlog=0 - sync_relay_log=0 - performance_schema=OFF - slow-query-log=OFF - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-transaction-compression=ON - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-row-value-options=PARTIAL_JSON - EOF - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vreplication_copy_parallel - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml b/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml deleted file mode 100644 index ca065d6f06c..00000000000 --- a/.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml +++ /dev/null @@ -1,162 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vreplication_foreign_key_stress) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vreplication_foreign_key_stress)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vreplication_foreign_key_stress) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vreplication_foreign_key_stress.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Increase our open file descriptor limit as we could hit this - ulimit -n 65536 - cat <<-EOF>>./config/mycnf/mysql8026.cnf - innodb_buffer_pool_dump_at_shutdown=OFF - innodb_buffer_pool_in_core_file=OFF - innodb_buffer_pool_load_at_startup=OFF - innodb_buffer_pool_size=64M - innodb_doublewrite=OFF - innodb_flush_log_at_trx_commit=0 - innodb_flush_method=O_DIRECT - innodb_numa_interleave=ON - innodb_adaptive_hash_index=OFF - sync_binlog=0 - sync_relay_log=0 - performance_schema=OFF - slow-query-log=OFF - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-transaction-compression=ON - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-row-value-options=PARTIAL_JSON - EOF - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vreplication_foreign_key_stress - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vreplication_mariadb_to_mysql.yml b/.github/workflows/cluster_endtoend_vreplication_mariadb_to_mysql.yml deleted file mode 100644 index a7331cea037..00000000000 --- a/.github/workflows/cluster_endtoend_vreplication_mariadb_to_mysql.yml +++ /dev/null @@ -1,162 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vreplication_mariadb_to_mysql) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vreplication_mariadb_to_mysql)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vreplication_mariadb_to_mysql) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vreplication_mariadb_to_mysql.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Increase our open file descriptor limit as we could hit this - ulimit -n 65536 - cat <<-EOF>>./config/mycnf/mysql8026.cnf - innodb_buffer_pool_dump_at_shutdown=OFF - innodb_buffer_pool_in_core_file=OFF - innodb_buffer_pool_load_at_startup=OFF - innodb_buffer_pool_size=64M - innodb_doublewrite=OFF - innodb_flush_log_at_trx_commit=0 - innodb_flush_method=O_DIRECT - innodb_numa_interleave=ON - innodb_adaptive_hash_index=OFF - sync_binlog=0 - sync_relay_log=0 - performance_schema=OFF - slow-query-log=OFF - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-transaction-compression=ON - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-row-value-options=PARTIAL_JSON - EOF - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vreplication_mariadb_to_mysql - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vreplication_migrate.yml b/.github/workflows/cluster_endtoend_vreplication_migrate.yml deleted file mode 100644 index b6dd4f4466d..00000000000 --- a/.github/workflows/cluster_endtoend_vreplication_migrate.yml +++ /dev/null @@ -1,162 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vreplication_migrate) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vreplication_migrate)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vreplication_migrate) - runs-on: gh-hosted-runners-16cores-1-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vreplication_migrate.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Increase our open file descriptor limit as we could hit this - ulimit -n 65536 - cat <<-EOF>>./config/mycnf/mysql8026.cnf - innodb_buffer_pool_dump_at_shutdown=OFF - innodb_buffer_pool_in_core_file=OFF - innodb_buffer_pool_load_at_startup=OFF - innodb_buffer_pool_size=64M - innodb_doublewrite=OFF - innodb_flush_log_at_trx_commit=0 - innodb_flush_method=O_DIRECT - innodb_numa_interleave=ON - innodb_adaptive_hash_index=OFF - sync_binlog=0 - sync_relay_log=0 - performance_schema=OFF - slow-query-log=OFF - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-transaction-compression=ON - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-row-value-options=PARTIAL_JSON - EOF - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vreplication_migrate - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vreplication_multi_tenant.yml b/.github/workflows/cluster_endtoend_vreplication_multi_tenant.yml deleted file mode 100644 index 98afd1073a8..00000000000 --- a/.github/workflows/cluster_endtoend_vreplication_multi_tenant.yml +++ /dev/null @@ -1,162 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vreplication_multi_tenant) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vreplication_multi_tenant)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vreplication_multi_tenant) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vreplication_multi_tenant.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Increase our open file descriptor limit as we could hit this - ulimit -n 65536 - cat <<-EOF>>./config/mycnf/mysql8026.cnf - innodb_buffer_pool_dump_at_shutdown=OFF - innodb_buffer_pool_in_core_file=OFF - innodb_buffer_pool_load_at_startup=OFF - innodb_buffer_pool_size=64M - innodb_doublewrite=OFF - innodb_flush_log_at_trx_commit=0 - innodb_flush_method=O_DIRECT - innodb_numa_interleave=ON - innodb_adaptive_hash_index=OFF - sync_binlog=0 - sync_relay_log=0 - performance_schema=OFF - slow-query-log=OFF - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-transaction-compression=ON - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-row-value-options=PARTIAL_JSON - EOF - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vreplication_multi_tenant - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vreplication_partial_movetables_and_materialize.yml b/.github/workflows/cluster_endtoend_vreplication_partial_movetables_and_materialize.yml deleted file mode 100644 index d16ceb002f2..00000000000 --- a/.github/workflows/cluster_endtoend_vreplication_partial_movetables_and_materialize.yml +++ /dev/null @@ -1,162 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vreplication_partial_movetables_and_materialize) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vreplication_partial_movetables_and_materialize)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vreplication_partial_movetables_and_materialize) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vreplication_partial_movetables_and_materialize.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Increase our open file descriptor limit as we could hit this - ulimit -n 65536 - cat <<-EOF>>./config/mycnf/mysql8026.cnf - innodb_buffer_pool_dump_at_shutdown=OFF - innodb_buffer_pool_in_core_file=OFF - innodb_buffer_pool_load_at_startup=OFF - innodb_buffer_pool_size=64M - innodb_doublewrite=OFF - innodb_flush_log_at_trx_commit=0 - innodb_flush_method=O_DIRECT - innodb_numa_interleave=ON - innodb_adaptive_hash_index=OFF - sync_binlog=0 - sync_relay_log=0 - performance_schema=OFF - slow-query-log=OFF - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-transaction-compression=ON - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-row-value-options=PARTIAL_JSON - EOF - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vreplication_partial_movetables_and_materialize - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vreplication_v2.yml b/.github/workflows/cluster_endtoend_vreplication_v2.yml deleted file mode 100644 index afb1881d08f..00000000000 --- a/.github/workflows/cluster_endtoend_vreplication_v2.yml +++ /dev/null @@ -1,162 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vreplication_v2) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vreplication_v2)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vreplication_v2) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vreplication_v2.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Increase our open file descriptor limit as we could hit this - ulimit -n 65536 - cat <<-EOF>>./config/mycnf/mysql8026.cnf - innodb_buffer_pool_dump_at_shutdown=OFF - innodb_buffer_pool_in_core_file=OFF - innodb_buffer_pool_load_at_startup=OFF - innodb_buffer_pool_size=64M - innodb_doublewrite=OFF - innodb_flush_log_at_trx_commit=0 - innodb_flush_method=O_DIRECT - innodb_numa_interleave=ON - innodb_adaptive_hash_index=OFF - sync_binlog=0 - sync_relay_log=0 - performance_schema=OFF - slow-query-log=OFF - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-transaction-compression=ON - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-row-value-options=PARTIAL_JSON - EOF - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vreplication_v2 - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vreplication_vdiff2.yml b/.github/workflows/cluster_endtoend_vreplication_vdiff2.yml deleted file mode 100644 index 5084d4febbb..00000000000 --- a/.github/workflows/cluster_endtoend_vreplication_vdiff2.yml +++ /dev/null @@ -1,162 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vreplication_vdiff2) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vreplication_vdiff2)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vreplication_vdiff2) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vreplication_vdiff2.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Increase our open file descriptor limit as we could hit this - ulimit -n 65536 - cat <<-EOF>>./config/mycnf/mysql8026.cnf - innodb_buffer_pool_dump_at_shutdown=OFF - innodb_buffer_pool_in_core_file=OFF - innodb_buffer_pool_load_at_startup=OFF - innodb_buffer_pool_size=64M - innodb_doublewrite=OFF - innodb_flush_log_at_trx_commit=0 - innodb_flush_method=O_DIRECT - innodb_numa_interleave=ON - innodb_adaptive_hash_index=OFF - sync_binlog=0 - sync_relay_log=0 - performance_schema=OFF - slow-query-log=OFF - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-transaction-compression=ON - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-row-value-options=PARTIAL_JSON - EOF - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vreplication_vdiff2 - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vreplication_vtctldclient_movetables_tz.yml b/.github/workflows/cluster_endtoend_vreplication_vtctldclient_movetables_tz.yml deleted file mode 100644 index 0dddba7b5d0..00000000000 --- a/.github/workflows/cluster_endtoend_vreplication_vtctldclient_movetables_tz.yml +++ /dev/null @@ -1,162 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vreplication_vtctldclient_movetables_tz) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vreplication_vtctldclient_movetables_tz)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vreplication_vtctldclient_movetables_tz) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vreplication_vtctldclient_movetables_tz.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Increase our open file descriptor limit as we could hit this - ulimit -n 65536 - cat <<-EOF>>./config/mycnf/mysql8026.cnf - innodb_buffer_pool_dump_at_shutdown=OFF - innodb_buffer_pool_in_core_file=OFF - innodb_buffer_pool_load_at_startup=OFF - innodb_buffer_pool_size=64M - innodb_doublewrite=OFF - innodb_flush_log_at_trx_commit=0 - innodb_flush_method=O_DIRECT - innodb_numa_interleave=ON - innodb_adaptive_hash_index=OFF - sync_binlog=0 - sync_relay_log=0 - performance_schema=OFF - slow-query-log=OFF - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-transaction-compression=ON - EOF - - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-row-value-options=PARTIAL_JSON - EOF - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vreplication_vtctldclient_movetables_tz - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vstream.yml b/.github/workflows/cluster_endtoend_vstream.yml deleted file mode 100644 index c6c29d1b400..00000000000 --- a/.github/workflows/cluster_endtoend_vstream.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vstream) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vstream)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vstream) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vstream.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vstream - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtbackup.yml b/.github/workflows/cluster_endtoend_vtbackup.yml deleted file mode 100644 index 35954542af7..00000000000 --- a/.github/workflows/cluster_endtoend_vtbackup.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vtbackup) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtbackup)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vtbackup) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vtbackup.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vtbackup - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml b/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml deleted file mode 100644 index fbd4fcd83ca..00000000000 --- a/.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml +++ /dev/null @@ -1,154 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vtctlbackup_sharded_clustertest_heavy) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtctlbackup_sharded_clustertest_heavy)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vtctlbackup_sharded_clustertest_heavy) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vtctlbackup_sharded_clustertest_heavy.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Increase our open file descriptor limit as we could hit this - ulimit -n 65536 - cat <<-EOF>>./config/mycnf/mysql8026.cnf - innodb_buffer_pool_dump_at_shutdown=OFF - innodb_buffer_pool_in_core_file=OFF - innodb_buffer_pool_load_at_startup=OFF - innodb_buffer_pool_size=64M - innodb_doublewrite=OFF - innodb_flush_log_at_trx_commit=0 - innodb_flush_method=O_DIRECT - innodb_numa_interleave=ON - innodb_adaptive_hash_index=OFF - sync_binlog=0 - sync_relay_log=0 - performance_schema=OFF - slow-query-log=OFF - EOF - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vtctlbackup_sharded_clustertest_heavy - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml b/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml deleted file mode 100644 index 76680df0e9d..00000000000 --- a/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vtgate_concurrentdml) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtgate_concurrentdml)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vtgate_concurrentdml) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vtgate_concurrentdml - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml b/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml deleted file mode 100644 index c267791727f..00000000000 --- a/.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vtgate_foreignkey_stress) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtgate_foreignkey_stress)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vtgate_foreignkey_stress) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vtgate_foreignkey_stress.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vtgate_foreignkey_stress - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_gen4.yml b/.github/workflows/cluster_endtoend_vtgate_gen4.yml deleted file mode 100644 index d1c979f7eec..00000000000 --- a/.github/workflows/cluster_endtoend_vtgate_gen4.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vtgate_gen4) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtgate_gen4)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vtgate_gen4) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vtgate_gen4.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vtgate_gen4 - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml b/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml deleted file mode 100644 index 7f30d232aa6..00000000000 --- a/.github/workflows/cluster_endtoend_vtgate_general_heavy.yml +++ /dev/null @@ -1,154 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vtgate_general_heavy) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtgate_general_heavy)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vtgate_general_heavy) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vtgate_general_heavy.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Increase our open file descriptor limit as we could hit this - ulimit -n 65536 - cat <<-EOF>>./config/mycnf/mysql8026.cnf - innodb_buffer_pool_dump_at_shutdown=OFF - innodb_buffer_pool_in_core_file=OFF - innodb_buffer_pool_load_at_startup=OFF - innodb_buffer_pool_size=64M - innodb_doublewrite=OFF - innodb_flush_log_at_trx_commit=0 - innodb_flush_method=O_DIRECT - innodb_numa_interleave=ON - innodb_adaptive_hash_index=OFF - sync_binlog=0 - sync_relay_log=0 - performance_schema=OFF - slow-query-log=OFF - EOF - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vtgate_general_heavy - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_godriver.yml b/.github/workflows/cluster_endtoend_vtgate_godriver.yml deleted file mode 100644 index a53372f5063..00000000000 --- a/.github/workflows/cluster_endtoend_vtgate_godriver.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vtgate_godriver) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtgate_godriver)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vtgate_godriver) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vtgate_godriver.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vtgate_godriver - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml b/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml deleted file mode 100644 index 8f63f75f473..00000000000 --- a/.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vtgate_partial_keyspace) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtgate_partial_keyspace)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vtgate_partial_keyspace) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vtgate_partial_keyspace.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vtgate_partial_keyspace -partial-keyspace=true - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_plantests.yml b/.github/workflows/cluster_endtoend_vtgate_plantests.yml deleted file mode 100644 index b72ddb51657..00000000000 --- a/.github/workflows/cluster_endtoend_vtgate_plantests.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vtgate_plantests) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtgate_plantests)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vtgate_plantests) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vtgate_plantests.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vtgate_plantests - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_queries.yml b/.github/workflows/cluster_endtoend_vtgate_queries.yml deleted file mode 100644 index ce3c836cfc4..00000000000 --- a/.github/workflows/cluster_endtoend_vtgate_queries.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vtgate_queries) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtgate_queries)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vtgate_queries) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vtgate_queries.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vtgate_queries - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml b/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml deleted file mode 100644 index 77d25c292a0..00000000000 --- a/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vtgate_readafterwrite) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtgate_readafterwrite)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vtgate_readafterwrite) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vtgate_readafterwrite - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml b/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml deleted file mode 100644 index 6a3b4362446..00000000000 --- a/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vtgate_reservedconn) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtgate_reservedconn)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vtgate_reservedconn) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vtgate_reservedconn.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vtgate_reservedconn - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_schema.yml b/.github/workflows/cluster_endtoend_vtgate_schema.yml deleted file mode 100644 index c024cebba19..00000000000 --- a/.github/workflows/cluster_endtoend_vtgate_schema.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vtgate_schema) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtgate_schema)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vtgate_schema) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vtgate_schema.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vtgate_schema - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml b/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml deleted file mode 100644 index be354c84b4a..00000000000 --- a/.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vtgate_schema_tracker) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtgate_schema_tracker)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vtgate_schema_tracker) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vtgate_schema_tracker.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vtgate_schema_tracker - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml b/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml deleted file mode 100644 index 1049f92def6..00000000000 --- a/.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vtgate_tablet_healthcheck_cache) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtgate_tablet_healthcheck_cache)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vtgate_tablet_healthcheck_cache) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vtgate_tablet_healthcheck_cache.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vtgate_tablet_healthcheck_cache - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_topo.yml b/.github/workflows/cluster_endtoend_vtgate_topo.yml deleted file mode 100644 index 2ea5e7dc48d..00000000000 --- a/.github/workflows/cluster_endtoend_vtgate_topo.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vtgate_topo) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtgate_topo)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vtgate_topo) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vtgate_topo.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vtgate_topo - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml b/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml deleted file mode 100644 index 4b1aae42cd8..00000000000 --- a/.github/workflows/cluster_endtoend_vtgate_topo_consul.yml +++ /dev/null @@ -1,141 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vtgate_topo_consul) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtgate_topo_consul)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vtgate_topo_consul) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vtgate_topo_consul.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Installing zookeeper and consul - if: steps.changes.outputs.end_to_end == 'true' - run: | - make tools - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vtgate_topo_consul - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml b/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml deleted file mode 100644 index caede66030f..00000000000 --- a/.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vtgate_topo_etcd) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtgate_topo_etcd)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vtgate_topo_etcd) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vtgate_topo_etcd.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vtgate_topo_etcd - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_transaction.yml b/.github/workflows/cluster_endtoend_vtgate_transaction.yml deleted file mode 100644 index 48a45c53468..00000000000 --- a/.github/workflows/cluster_endtoend_vtgate_transaction.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vtgate_transaction) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtgate_transaction)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vtgate_transaction) - runs-on: gh-hosted-runners-16cores-1-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vtgate_transaction.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vtgate_transaction -build-tag=debug2PC - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_unsharded.yml b/.github/workflows/cluster_endtoend_vtgate_unsharded.yml deleted file mode 100644 index 60a02119ab7..00000000000 --- a/.github/workflows/cluster_endtoend_vtgate_unsharded.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vtgate_unsharded) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtgate_unsharded)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vtgate_unsharded) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vtgate_unsharded.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vtgate_unsharded - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml b/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml deleted file mode 100644 index d984e1e72a7..00000000000 --- a/.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml +++ /dev/null @@ -1,154 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vtgate_vindex_heavy) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtgate_vindex_heavy)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vtgate_vindex_heavy) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vtgate_vindex_heavy.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Increase our open file descriptor limit as we could hit this - ulimit -n 65536 - cat <<-EOF>>./config/mycnf/mysql8026.cnf - innodb_buffer_pool_dump_at_shutdown=OFF - innodb_buffer_pool_in_core_file=OFF - innodb_buffer_pool_load_at_startup=OFF - innodb_buffer_pool_size=64M - innodb_doublewrite=OFF - innodb_flush_log_at_trx_commit=0 - innodb_flush_method=O_DIRECT - innodb_numa_interleave=ON - innodb_adaptive_hash_index=OFF - sync_binlog=0 - sync_relay_log=0 - performance_schema=OFF - slow-query-log=OFF - EOF - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vtgate_vindex_heavy - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtgate_vschema.yml b/.github/workflows/cluster_endtoend_vtgate_vschema.yml deleted file mode 100644 index 52010c5b8e2..00000000000 --- a/.github/workflows/cluster_endtoend_vtgate_vschema.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vtgate_vschema) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtgate_vschema)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vtgate_vschema) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vtgate_vschema.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vtgate_vschema - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vtorc.yml b/.github/workflows/cluster_endtoend_vtorc.yml deleted file mode 100644 index dacbce5862a..00000000000 --- a/.github/workflows/cluster_endtoend_vtorc.yml +++ /dev/null @@ -1,145 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vtorc) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtorc)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vtorc) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check Memory - run: | - totalMem=$(free -g | awk 'NR==2 {print $2}') - echo "total memory $totalMem GB" - if [[ "$totalMem" -lt 15 ]]; then - echo "Less memory than required" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vtorc.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vtorc - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml b/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml deleted file mode 100644 index c9085996d00..00000000000 --- a/.github/workflows/cluster_endtoend_vttablet_prscomplex.yml +++ /dev/null @@ -1,136 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (vttablet_prscomplex) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vttablet_prscomplex)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (vttablet_prscomplex) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_vttablet_prscomplex.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - sudo apt-get -qq install -y mysql-shell - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard vttablet_prscomplex - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_xb_backup.yml b/.github/workflows/cluster_endtoend_xb_backup.yml deleted file mode 100644 index f7ec7690210..00000000000 --- a/.github/workflows/cluster_endtoend_xb_backup.yml +++ /dev/null @@ -1,145 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (xb_backup) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (xb_backup)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (xb_backup) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_xb_backup.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - # Setup Percona Server for MySQL 8.0 - sudo apt-get -qq update - sudo apt-get -qq install -y lsb-release gnupg2 - wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb - sudo DEBIAN_FRONTEND="noninteractive" dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb - sudo percona-release setup pdps8.0 - sudo apt-get -qq update - - sudo apt-get -qq install -y percona-server-server percona-server-client - - sudo service mysql stop - - sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ - sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld - - sudo apt-get -qq install -y percona-xtrabackup-80 lz4 - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard xb_backup - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/cluster_endtoend_xb_recovery.yml b/.github/workflows/cluster_endtoend_xb_recovery.yml deleted file mode 100644 index 5a4ff1fea83..00000000000 --- a/.github/workflows/cluster_endtoend_xb_recovery.yml +++ /dev/null @@ -1,145 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Cluster (xb_recovery) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (xb_recovery)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on Cluster (xb_recovery) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/cluster_endtoend_xb_recovery.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - - # Setup Percona Server for MySQL 8.0 - sudo apt-get -qq update - sudo apt-get -qq install -y lsb-release gnupg2 - wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb - sudo DEBIAN_FRONTEND="noninteractive" dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb - sudo percona-release setup pdps8.0 - sudo apt-get -qq update - - sudo apt-get -qq install -y percona-server-server percona-server-client - - sudo service mysql stop - - sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ - sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld - - sudo apt-get -qq install -y percona-xtrabackup-80 lz4 - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker=false -follow -shard xb_recovery - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/.github/workflows/static_checks_etc.yml b/.github/workflows/static_checks_etc.yml index 710d388d267..642d769c6e1 100644 --- a/.github/workflows/static_checks_etc.yml +++ b/.github/workflows/static_checks_etc.yml @@ -248,16 +248,4 @@ jobs: echo "" exit 1 - - name: Check make generate_ci_workflows - run: | - set -e - make generate_ci_workflows - output=$(git status -s) - if [ -z "${output}" ]; then - exit 0 - fi - echo 'Please run `make generate_ci_workflows`, commit and push again.' - echo 'Running `make generate_ci_workflows` on CI yields the following changes:' - echo "$output" - echo "" - exit 1 + diff --git a/.github/workflows/unit_race.yml b/.github/workflows/unit_race.yml deleted file mode 100644 index 5eb6e00c622..00000000000 --- a/.github/workflows/unit_race.yml +++ /dev/null @@ -1,147 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Unit Test (Race) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Unit Test (Race)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - test: - name: Unit Test (Race) - runs-on: gh-hosted-runners-16cores-1-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - unit_tests: - - 'test/config.json' - - 'go/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/unit_race.yml' - - - name: Set up Go - if: steps.changes.outputs.unit_tests == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.unit_tests == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.unit_tests == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.unit_tests == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.unit_tests == 'true' - run: | - export DEBIAN_FRONTEND="noninteractive" - sudo apt-get install -y make unzip g++ curl git wget ant openjdk-11-jdk - - mkdir -p dist bin - curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist - mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/ - - go mod download - go install golang.org/x/tools/cmd/goimports@latest - - - name: Run make tools - if: steps.changes.outputs.unit_tests == 'true' - run: | - make tools - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run test - if: steps.changes.outputs.unit_tests == 'true' - timeout-minutes: 45 - run: | - set -exo pipefail - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - - export NOVTADMINBUILD=1 - export VTEVALENGINETEST="0" - # We sometimes need to alter the behavior based on the platform we're - # testing, e.g. MySQL 5.7 vs 8.0. - export CI_DB_PLATFORM="mysql80" - - JUNIT_OUTPUT=report.xml JSON_OUTPUT=report.json make unit_test_race - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "report.xml" - show: "fail" - - - name: Slowest Tests - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - run: | - echo '## Slowest Tests' >> "$GITHUB_STEP_SUMMARY" - echo '```' >> "$GITHUB_STEP_SUMMARY" - go tool gotestsum tool slowest --num 20 --jsonfile report.json | tee -a "$GITHUB_STEP_SUMMARY" - echo '```' >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/unit_race_evalengine.yml b/.github/workflows/unit_race_evalengine.yml deleted file mode 100644 index d1f097b08e7..00000000000 --- a/.github/workflows/unit_race_evalengine.yml +++ /dev/null @@ -1,147 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Unit Test (Evalengine_Race) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Unit Test (Evalengine_Race)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - test: - name: Unit Test (Evalengine_Race) - runs-on: gh-hosted-runners-16cores-1-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - unit_tests: - - 'test/config.json' - - 'go/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/unit_race_evalengine.yml' - - - name: Set up Go - if: steps.changes.outputs.unit_tests == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.unit_tests == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.unit_tests == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.unit_tests == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.unit_tests == 'true' - run: | - export DEBIAN_FRONTEND="noninteractive" - sudo apt-get install -y make unzip g++ curl git wget ant openjdk-11-jdk - - mkdir -p dist bin - curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist - mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/ - - go mod download - go install golang.org/x/tools/cmd/goimports@latest - - - name: Run make tools - if: steps.changes.outputs.unit_tests == 'true' - run: | - make tools - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run test - if: steps.changes.outputs.unit_tests == 'true' - timeout-minutes: 45 - run: | - set -exo pipefail - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - - export NOVTADMINBUILD=1 - export VTEVALENGINETEST="1" - # We sometimes need to alter the behavior based on the platform we're - # testing, e.g. MySQL 5.7 vs 8.0. - export CI_DB_PLATFORM="mysql80" - - JUNIT_OUTPUT=report.xml JSON_OUTPUT=report.json make unit_test_race - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "report.xml" - show: "fail" - - - name: Slowest Tests - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - run: | - echo '## Slowest Tests' >> "$GITHUB_STEP_SUMMARY" - echo '```' >> "$GITHUB_STEP_SUMMARY" - go tool gotestsum tool slowest --num 20 --jsonfile report.json | tee -a "$GITHUB_STEP_SUMMARY" - echo '```' >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/unit_test.yml b/.github/workflows/unit_test.yml new file mode 100644 index 00000000000..dbbd998d5bc --- /dev/null +++ b/.github/workflows/unit_test.yml @@ -0,0 +1,194 @@ +name: Unit Test + +on: + push: + branches: + - "main" + - "release-[0-9]+.[0-9]" + tags: "**" + pull_request: + branches: "**" + +concurrency: + group: format('{0}-{1}', ${{ github.ref }}, 'Unit Test') + cancel-in-progress: true + +permissions: read-all + +env: + LAUNCHABLE_ORGANIZATION: "vitess" + LAUNCHABLE_WORKSPACE: "vitess-app" + GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" + +jobs: + test: + timeout-minutes: ${{ matrix.race && 45 || 30 }} + strategy: + fail-fast: false + matrix: + include: + # mysql57 tests + - platform: mysql57 + evalengine: "0" + flavor: mysql-5.7 + + - platform: mysql57 + evalengine: "1" + flavor: mysql-5.7 + + # mysql80 tests + - platform: mysql80 + evalengine: "0" + flavor: mysql-8.0 + + - platform: mysql80 + evalengine: "1" + flavor: mysql-8.0 + + # mysql84 tests + - platform: mysql84 + evalengine: "0" + flavor: mysql-8.4 + + - platform: mysql84 + evalengine: "1" + flavor: mysql-8.4 + + # Race tests (mysql80 only) + - platform: mysql80 + evalengine: "0" + flavor: mysql-8.0 + race: true + + - platform: mysql80 + evalengine: "1" + flavor: mysql-8.0 + race: true + + name: "Unit Test (${{ matrix.race && (matrix.evalengine == '1' && 'Evalengine_' || '') || (matrix.evalengine == '1' && 'evalengine_' || '') }}${{ matrix.race && 'Race' || matrix.platform }})" + runs-on: ${{ matrix.race && 'gh-hosted-runners-16cores-1-24.04' || 'ubuntu-24.04' }} + + steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 + with: + egress-policy: audit + + - name: Skip CI + run: | + if [[ "${{ contains(github.event.pull_request.labels.*.name, 'Skip CI') }}" == "true" ]]; then + echo "skipping CI due to the 'Skip CI' label" + exit 1 + fi + + - name: Check out code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: "false" + + - name: Check for changes in relevant files + uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 + id: changes + with: + token: "" + filters: | + unit_tests: + - 'test/config.json' + - 'go/**' + - 'test.go' + - 'Makefile' + - 'build.env' + - 'go.sum' + - 'go.mod' + - 'proto/*.proto' + - 'tools/**' + - 'config/**' + - 'bootstrap.sh' + - '.github/workflows/unit_test.yml' + + - name: Set up Go + if: steps.changes.outputs.unit_tests == 'true' + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 + with: + go-version-file: go.mod + + - name: Set up python + if: steps.changes.outputs.unit_tests == 'true' + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + + - name: Tune the OS + if: steps.changes.outputs.unit_tests == 'true' + uses: ./.github/actions/tune-os + + - name: Setup MySQL + if: steps.changes.outputs.unit_tests == 'true' + uses: ./.github/actions/setup-mysql + with: + flavor: ${{ matrix.flavor }} + + - name: Get dependencies + if: steps.changes.outputs.unit_tests == 'true' + run: | + export DEBIAN_FRONTEND="noninteractive" + sudo apt-get install -y make unzip g++ curl git wget ant openjdk-11-jdk + + mkdir -p dist bin + curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist + mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/ + + go mod download + go install golang.org/x/tools/cmd/goimports@v0.39.0 + + - name: Run make tools + if: steps.changes.outputs.unit_tests == 'true' + run: | + make tools + + - name: Setup launchable dependencies + if: | + github.event_name == 'pull_request' && + github.event.pull_request.draft == false && + steps.changes.outputs.unit_tests == 'true' && + github.base_ref == 'main' + run: | + pip3 install --user launchable~=1.0 > /dev/null + launchable verify || true + launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . + + - name: Run test + if: steps.changes.outputs.unit_tests == 'true' + run: | + set -exo pipefail + + export VTDATAROOT="/tmp/" + export NOVTADMINBUILD=1 + export VT_GO_PARALLEL_VALUE=$(nproc) + export VTEVALENGINETEST="${{ matrix.evalengine }}" + export CI_DB_PLATFORM="${{ matrix.platform }}" + + JUNIT_OUTPUT=report.xml JSON_OUTPUT=report.json make ${{ matrix.race && 'unit_test_race' || 'unit_test' }} + + - name: Record test results in launchable + if: | + github.event_name == 'pull_request' && + github.event.pull_request.draft == false && + steps.changes.outputs.unit_tests == 'true' && + github.base_ref == 'main' && + !cancelled() + run: | + launchable record tests --build "$GITHUB_RUN_ID" go-test . || true + + - name: Test Summary + if: steps.changes.outputs.unit_tests == 'true' && failure() + uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 + with: + paths: "report.xml" + show: "fail" + + - name: Slowest Tests + if: steps.changes.outputs.unit_tests == 'true' && !cancelled() + run: | + echo '## Slowest Tests' >> "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" + go tool gotestsum tool slowest --num 20 --jsonfile report.json | tee -a "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/unit_test_evalengine_mysql57.yml b/.github/workflows/unit_test_evalengine_mysql57.yml deleted file mode 100644 index 04be8d16ce7..00000000000 --- a/.github/workflows/unit_test_evalengine_mysql57.yml +++ /dev/null @@ -1,147 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Unit Test (evalengine_mysql57) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Unit Test (evalengine_mysql57)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - test: - name: Unit Test (evalengine_mysql57) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - unit_tests: - - 'test/config.json' - - 'go/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/unit_test_evalengine_mysql57.yml' - - - name: Set up Go - if: steps.changes.outputs.unit_tests == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.unit_tests == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.unit_tests == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.unit_tests == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-5.7 - - - name: Get dependencies - if: steps.changes.outputs.unit_tests == 'true' - run: | - export DEBIAN_FRONTEND="noninteractive" - sudo apt-get install -y make unzip g++ curl git wget ant openjdk-11-jdk - - mkdir -p dist bin - curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist - mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/ - - go mod download - go install golang.org/x/tools/cmd/goimports@latest - - - name: Run make tools - if: steps.changes.outputs.unit_tests == 'true' - run: | - make tools - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run test - if: steps.changes.outputs.unit_tests == 'true' - timeout-minutes: 30 - run: | - set -exo pipefail - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - - export NOVTADMINBUILD=1 - export VTEVALENGINETEST="1" - # We sometimes need to alter the behavior based on the platform we're - # testing, e.g. MySQL 5.7 vs 8.0. - export CI_DB_PLATFORM="mysql57" - - JUNIT_OUTPUT=report.xml JSON_OUTPUT=report.json make unit_test - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "report.xml" - show: "fail" - - - name: Slowest Tests - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - run: | - echo '## Slowest Tests' >> "$GITHUB_STEP_SUMMARY" - echo '```' >> "$GITHUB_STEP_SUMMARY" - go tool gotestsum tool slowest --num 20 --jsonfile report.json | tee -a "$GITHUB_STEP_SUMMARY" - echo '```' >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/unit_test_evalengine_mysql80.yml b/.github/workflows/unit_test_evalengine_mysql80.yml deleted file mode 100644 index 791931d2abe..00000000000 --- a/.github/workflows/unit_test_evalengine_mysql80.yml +++ /dev/null @@ -1,147 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Unit Test (evalengine_mysql80) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Unit Test (evalengine_mysql80)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - test: - name: Unit Test (evalengine_mysql80) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - unit_tests: - - 'test/config.json' - - 'go/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/unit_test_evalengine_mysql80.yml' - - - name: Set up Go - if: steps.changes.outputs.unit_tests == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.unit_tests == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.unit_tests == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.unit_tests == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.unit_tests == 'true' - run: | - export DEBIAN_FRONTEND="noninteractive" - sudo apt-get install -y make unzip g++ curl git wget ant openjdk-11-jdk - - mkdir -p dist bin - curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist - mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/ - - go mod download - go install golang.org/x/tools/cmd/goimports@latest - - - name: Run make tools - if: steps.changes.outputs.unit_tests == 'true' - run: | - make tools - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run test - if: steps.changes.outputs.unit_tests == 'true' - timeout-minutes: 30 - run: | - set -exo pipefail - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - - export NOVTADMINBUILD=1 - export VTEVALENGINETEST="1" - # We sometimes need to alter the behavior based on the platform we're - # testing, e.g. MySQL 5.7 vs 8.0. - export CI_DB_PLATFORM="mysql80" - - JUNIT_OUTPUT=report.xml JSON_OUTPUT=report.json make unit_test - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "report.xml" - show: "fail" - - - name: Slowest Tests - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - run: | - echo '## Slowest Tests' >> "$GITHUB_STEP_SUMMARY" - echo '```' >> "$GITHUB_STEP_SUMMARY" - go tool gotestsum tool slowest --num 20 --jsonfile report.json | tee -a "$GITHUB_STEP_SUMMARY" - echo '```' >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/unit_test_evalengine_mysql84.yml b/.github/workflows/unit_test_evalengine_mysql84.yml deleted file mode 100644 index f5083f28635..00000000000 --- a/.github/workflows/unit_test_evalengine_mysql84.yml +++ /dev/null @@ -1,147 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Unit Test (evalengine_mysql84) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Unit Test (evalengine_mysql84)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - test: - name: Unit Test (evalengine_mysql84) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - unit_tests: - - 'test/config.json' - - 'go/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/unit_test_evalengine_mysql84.yml' - - - name: Set up Go - if: steps.changes.outputs.unit_tests == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.unit_tests == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.unit_tests == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.unit_tests == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.4 - - - name: Get dependencies - if: steps.changes.outputs.unit_tests == 'true' - run: | - export DEBIAN_FRONTEND="noninteractive" - sudo apt-get install -y make unzip g++ curl git wget ant openjdk-11-jdk - - mkdir -p dist bin - curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist - mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/ - - go mod download - go install golang.org/x/tools/cmd/goimports@latest - - - name: Run make tools - if: steps.changes.outputs.unit_tests == 'true' - run: | - make tools - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run test - if: steps.changes.outputs.unit_tests == 'true' - timeout-minutes: 30 - run: | - set -exo pipefail - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - - export NOVTADMINBUILD=1 - export VTEVALENGINETEST="1" - # We sometimes need to alter the behavior based on the platform we're - # testing, e.g. MySQL 5.7 vs 8.0. - export CI_DB_PLATFORM="mysql84" - - JUNIT_OUTPUT=report.xml JSON_OUTPUT=report.json make unit_test - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "report.xml" - show: "fail" - - - name: Slowest Tests - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - run: | - echo '## Slowest Tests' >> "$GITHUB_STEP_SUMMARY" - echo '```' >> "$GITHUB_STEP_SUMMARY" - go tool gotestsum tool slowest --num 20 --jsonfile report.json | tee -a "$GITHUB_STEP_SUMMARY" - echo '```' >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/unit_test_mysql57.yml b/.github/workflows/unit_test_mysql57.yml deleted file mode 100644 index ad3acd3121b..00000000000 --- a/.github/workflows/unit_test_mysql57.yml +++ /dev/null @@ -1,147 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Unit Test (mysql57) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Unit Test (mysql57)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - test: - name: Unit Test (mysql57) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - unit_tests: - - 'test/config.json' - - 'go/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/unit_test_mysql57.yml' - - - name: Set up Go - if: steps.changes.outputs.unit_tests == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.unit_tests == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.unit_tests == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.unit_tests == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-5.7 - - - name: Get dependencies - if: steps.changes.outputs.unit_tests == 'true' - run: | - export DEBIAN_FRONTEND="noninteractive" - sudo apt-get install -y make unzip g++ curl git wget ant openjdk-11-jdk - - mkdir -p dist bin - curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist - mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/ - - go mod download - go install golang.org/x/tools/cmd/goimports@latest - - - name: Run make tools - if: steps.changes.outputs.unit_tests == 'true' - run: | - make tools - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run test - if: steps.changes.outputs.unit_tests == 'true' - timeout-minutes: 30 - run: | - set -exo pipefail - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - - export NOVTADMINBUILD=1 - export VTEVALENGINETEST="0" - # We sometimes need to alter the behavior based on the platform we're - # testing, e.g. MySQL 5.7 vs 8.0. - export CI_DB_PLATFORM="mysql57" - - JUNIT_OUTPUT=report.xml JSON_OUTPUT=report.json make unit_test - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "report.xml" - show: "fail" - - - name: Slowest Tests - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - run: | - echo '## Slowest Tests' >> "$GITHUB_STEP_SUMMARY" - echo '```' >> "$GITHUB_STEP_SUMMARY" - go tool gotestsum tool slowest --num 20 --jsonfile report.json | tee -a "$GITHUB_STEP_SUMMARY" - echo '```' >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/unit_test_mysql80.yml b/.github/workflows/unit_test_mysql80.yml deleted file mode 100644 index 242f74e499c..00000000000 --- a/.github/workflows/unit_test_mysql80.yml +++ /dev/null @@ -1,147 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Unit Test (mysql80) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Unit Test (mysql80)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - test: - name: Unit Test (mysql80) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - unit_tests: - - 'test/config.json' - - 'go/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/unit_test_mysql80.yml' - - - name: Set up Go - if: steps.changes.outputs.unit_tests == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.unit_tests == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.unit_tests == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.unit_tests == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.unit_tests == 'true' - run: | - export DEBIAN_FRONTEND="noninteractive" - sudo apt-get install -y make unzip g++ curl git wget ant openjdk-11-jdk - - mkdir -p dist bin - curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist - mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/ - - go mod download - go install golang.org/x/tools/cmd/goimports@latest - - - name: Run make tools - if: steps.changes.outputs.unit_tests == 'true' - run: | - make tools - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run test - if: steps.changes.outputs.unit_tests == 'true' - timeout-minutes: 30 - run: | - set -exo pipefail - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - - export NOVTADMINBUILD=1 - export VTEVALENGINETEST="0" - # We sometimes need to alter the behavior based on the platform we're - # testing, e.g. MySQL 5.7 vs 8.0. - export CI_DB_PLATFORM="mysql80" - - JUNIT_OUTPUT=report.xml JSON_OUTPUT=report.json make unit_test - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "report.xml" - show: "fail" - - - name: Slowest Tests - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - run: | - echo '## Slowest Tests' >> "$GITHUB_STEP_SUMMARY" - echo '```' >> "$GITHUB_STEP_SUMMARY" - go tool gotestsum tool slowest --num 20 --jsonfile report.json | tee -a "$GITHUB_STEP_SUMMARY" - echo '```' >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/unit_test_mysql84.yml b/.github/workflows/unit_test_mysql84.yml deleted file mode 100644 index dfe2b50ac8e..00000000000 --- a/.github/workflows/unit_test_mysql84.yml +++ /dev/null @@ -1,147 +0,0 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - -name: Unit Test (mysql84) -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Unit Test (mysql84)') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}" - -jobs: - test: - name: Unit Test (mysql84) - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - unit_tests: - - 'test/config.json' - - 'go/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/unit_test_mysql84.yml' - - - name: Set up Go - if: steps.changes.outputs.unit_tests == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Set up python - if: steps.changes.outputs.unit_tests == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.unit_tests == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.unit_tests == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.4 - - - name: Get dependencies - if: steps.changes.outputs.unit_tests == 'true' - run: | - export DEBIAN_FRONTEND="noninteractive" - sudo apt-get install -y make unzip g++ curl git wget ant openjdk-11-jdk - - mkdir -p dist bin - curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist - mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/ - - go mod download - go install golang.org/x/tools/cmd/goimports@latest - - - name: Run make tools - if: steps.changes.outputs.unit_tests == 'true' - run: | - make tools - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run test - if: steps.changes.outputs.unit_tests == 'true' - timeout-minutes: 30 - run: | - set -exo pipefail - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - - export NOVTADMINBUILD=1 - export VTEVALENGINETEST="0" - # We sometimes need to alter the behavior based on the platform we're - # testing, e.g. MySQL 5.7 vs 8.0. - export CI_DB_PLATFORM="mysql84" - - JUNIT_OUTPUT=report.xml JSON_OUTPUT=report.json make unit_test - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "report.xml" - show: "fail" - - - name: Slowest Tests - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - run: | - echo '## Slowest Tests' >> "$GITHUB_STEP_SUMMARY" - echo '```' >> "$GITHUB_STEP_SUMMARY" - go tool gotestsum tool slowest --num 20 --jsonfile report.json | tee -a "$GITHUB_STEP_SUMMARY" - echo '```' >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/vitess_tester_vtgate.yml b/.github/workflows/vitess_tester_vtgate.yml index 74d22ac16ec..638dc534237 100644 --- a/.github/workflows/vitess_tester_vtgate.yml +++ b/.github/workflows/vitess_tester_vtgate.yml @@ -1,5 +1,3 @@ -# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" - name: Vitess Tester (vtgate) on: push: diff --git a/Makefile b/Makefile index 82a0232a610..b2346fc63b0 100644 --- a/Makefile +++ b/Makefile @@ -46,7 +46,7 @@ export REWRITER=go/vt/sqlparser/rewriter.go # Since we are not using this Makefile for compilation, limiting parallelism will not increase build time. .NOTPARALLEL: -.PHONY: all build install test clean unit_test unit_test_cover unit_test_race integration_test proto proto_banner site_test site_integration_test docker_bootstrap docker_test docker_unit_test java_test reshard_tests e2e_test e2e_test_race minimaltools tools generate_ci_workflows generate-flag-testdata +.PHONY: all build install test clean unit_test unit_test_cover unit_test_race integration_test proto proto_banner site_test site_integration_test docker_bootstrap docker_test docker_unit_test java_test reshard_tests e2e_test e2e_test_race minimaltools tools generate-flag-testdata all: build @@ -387,12 +387,6 @@ vtadmin_authz_testgen: go generate ./go/vt/vtadmin/ go fmt ./go/vt/vtadmin/ -# Generate github CI actions workflow files for unit tests and cluster endtoend tests based on templates in the test/templates directory -# Needs to be called if the templates change or if a new test "shard" is created. We do not need to rebuild tests if only the test/config.json -# is changed by adding a new test to an existing shard. Any new or modified files need to be committed into git -generate_ci_workflows: - cd test && go run ci_workflow_gen.go && cd .. - generate-flag-testdata: ./tools/generate_flag_testdata.sh diff --git a/test/README.md b/test/README.md index 196e3f05d06..1f4ca8e5306 100644 --- a/test/README.md +++ b/test/README.md @@ -4,17 +4,23 @@ This document has a short outline of how tests are run in CI, how to add new tes ### Adding a new test -Unit tests are run by the unit test runner, one per platform, currently mysql57, mysql80. +Unit tests are run by the unit test runner, one per platform, currently mysql57, mysql80, and mysql84. The workflow first installs the required database server before calling `make unit_test`. To add a new end-to-end (e2e) test (also called _cluster end to end_ tests): -* Add a new object to test/config.json -* If you are creating a new test _shard_: - * update `clusterList` in `ci_workflow_gen.go` - * `make generate_ci_workflows` -* If you are adding a new database platform, update the `templates\unit_test.tpl` to add - the platform specific packages and update `unitTestDatabases` +* Add a new object to test/config.json with the appropriate `Shard` value +* Add any required dependencies to the test's `Needs` array in config.json +* The cluster_endtoend.yml workflow will automatically pick up the new shard + +Available `Needs` values: +* `xtrabackup` - Install Percona Server and XtraBackup +* `minio` - Install Minio S3 server +* `consul` - Run `make tools` for Consul/ZooKeeper +* `larger-runner` - Use 16-core runner +* `memory-check` - Verify 15GB+ RAM +* `limit-resources` - Apply MySQL resource limits +* `binlog-compression` - Enable binlog transaction compression ### Vitess test runner The `.github/workflows` directory contains one yaml file per workflow. e2e tests are run using the `test.go` script @@ -30,15 +36,15 @@ Each test is of the form: "Args": [], "Command": [], "Manual": false, - "Shard": 17, + "Shard": "vtgate_queries", + "Needs": ["larger-runner"], "Tags": [] }, ``` -The important parameters here are Packages which define the Go packages to test, Args for any `go test` flags, and the Shard which says -which Test VM should run this test. All tests which have a common Shard value are run in the same test vm. +The important parameters here are Packages which define the Go packages to test, Args for any `go test` flags, the Shard which says +which group of tests to run together, and Needs which specifies CI dependencies. ### Known Issue * Each VM does not seem to be able to create a lot of vttablets. For this reason we have had to split a few VReplication e2e tests across Shards. We need to identify and if possible fix this limitation so that we can reduce the number of test Shards - diff --git a/test/ci_workflow_gen.go b/test/ci_workflow_gen.go deleted file mode 100644 index 225ee344f70..00000000000 --- a/test/ci_workflow_gen.go +++ /dev/null @@ -1,450 +0,0 @@ -/* -Copyright 2021 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package main - -import ( - "bytes" - "fmt" - "log" - "os" - "path" - "strings" - "text/template" -) - -type mysqlVersion string - -const ( - mysql57 mysqlVersion = "mysql57" - mysql80 mysqlVersion = "mysql80" - mysql84 mysqlVersion = "mysql84" - - defaultMySQLVersion = mysql80 -) - -type mysqlVersions []mysqlVersion - -var defaultMySQLVersions = []mysqlVersion{defaultMySQLVersion} - -var unitTestDatabases = []mysqlVersion{mysql57, mysql80, mysql84} - -const ( - oracleCloudRunner = "oracle-16cpu-64gb-x86-64" - githubRunner = "gh-hosted-runners-16cores-1-24.04" - cores16RunnerName = githubRunner - defaultRunnerName = "ubuntu-24.04" -) - -// To support a private git repository, set goPrivate to a repo in -// github.com/org/repo format. This assumes a GitHub PAT token is -// set as a repo secret named GH_ACCESS_TOKEN. The GitHub PAT must -// have read access to your vitess fork/repo. -const goPrivate = "" - -const ( - workflowConfigDir = "../.github/workflows" - - unitTestTemplate = "templates/unit_test.tpl" - - // An empty string will cause the default non platform specific template - // to be used. - clusterTestTemplate = "templates/cluster_endtoend_test%s.tpl" - - clusterVitessTesterTemplate = "templates/cluster_vitess_tester.tpl" - - clusterTestDockerTemplate = "templates/cluster_endtoend_test_docker.tpl" -) - -var ( - // Clusters 10, 25 are executed on docker, using the docker_test_cluster 10, 25 workflows. - // Hence, they are not listed in the list below. - clusterList = []string{ - "vtctlbackup_sharded_clustertest_heavy", - "12", - "13", - "ers_prs_newfeatures_heavy", - "15", - "vtgate_general_heavy", - "vtbackup", - "18", - "xb_backup", - "backup_pitr", - "backup_pitr_xtrabackup", - "backup_pitr_mysqlshell", - "21", - "mysql_server_vault", - "vstream", - "onlineddl_vrepl", - "onlineddl_vrepl_stress", - "onlineddl_vrepl_stress_suite", - "onlineddl_vrepl_suite", - "onlineddl_revert", - "onlineddl_scheduler", - "tabletmanager_throttler_topo", - "tabletmanager_tablegc", - "tabletmanager_consul", - "vtgate_concurrentdml", - "vtgate_godriver", - "vtgate_gen4", - "vtgate_readafterwrite", - "vtgate_reservedconn", - "vtgate_schema", - "vtgate_tablet_healthcheck_cache", - "vtgate_topo", - "vtgate_topo_consul", - "vtgate_topo_etcd", - "vtgate_transaction", - "vtgate_unsharded", - "vtgate_vindex_heavy", - "vtgate_vschema", - "vtgate_queries", - "vtgate_plantests", - "vtgate_schema_tracker", - "vtgate_foreignkey_stress", - "vtorc", - "xb_recovery", - "mysql80", - "vreplication_across_db_versions", - "vreplication_mariadb_to_mysql", - "vreplication_basic", - "vreplication_cellalias", - "vreplication_copy_parallel", - "vreplication_v2", - "vreplication_partial_movetables_and_materialize", - "vreplication_foreign_key_stress", - "vreplication_migrate", - "vreplication_vtctldclient_movetables_tz", - "vreplication_vdiff2", - "vreplication_multi_tenant", - "schemadiff_vrepl", - "topo_connection_cache", - "vtgate_partial_keyspace", - "vttablet_prscomplex", - } - - buildTag = map[string]string{ - "vtgate_transaction": "debug2PC", - } - - vitessTesterMap = map[string]string{ - "vtgate": "./go/test/endtoend/vtgate/vitess_tester", - } - - clusterDockerList = []string{} - clustersRequiringXtraBackup = []string{ - "xb_backup", - "xb_recovery", - "backup_pitr_xtrabackup", - } - clustersRequiringMakeTools = []string{ - "18", - "mysql_server_vault", - "vtgate_topo_consul", - "tabletmanager_consul", - } - clustersRequiringMemoryCheck = []string{ - "vtorc", - } - clusterRequiring16CoresMachines = []string{ - "onlineddl_vrepl", - "onlineddl_vrepl_stress", - "onlineddl_vrepl_stress_suite", - "onlineddl_vrepl_suite", - "vreplication_basic", - "vreplication_migrate", - "vreplication_vtctldclient_vdiff2_movetables_tz", - "vtgate_transaction", - } - clusterRequiringMinio = []string{ - "21", - } -) - -type unitTest struct { - Name, RunsOn, Platform, FileName, GoPrivate, Evalengine string - Race bool -} - -type clusterTest struct { - Name, Shard, Platform string - FileName string - BuildTag string - RunsOn string - GoPrivate string - MemoryCheck bool - MakeTools, InstallXtraBackup bool - Docker bool - LimitResourceUsage bool - EnableBinlogTransactionCompression bool - EnablePartialJSON bool - PartialKeyspace bool - NeedsMinio bool -} - -type vitessTesterTest struct { - FileName string - Name string - RunsOn string - GoPrivate string - Path string -} - -// clusterMySQLVersions return list of mysql versions (one or more) that this cluster needs to test against -func clusterMySQLVersions() mysqlVersions { - switch { - // Add any specific clusters, or groups of clusters, here, - // that require allMySQLVersions to be tested against. - // At this time this list is clean because Vitess stopped - // supporting MySQL 5.7. At some point, we will need to - // support post 8.0 versions of MySQL, and this list will - // inevitably grow. - default: - return defaultMySQLVersions - } -} - -func mergeBlankLines(buf *bytes.Buffer) string { - var out []string - in := strings.Split(buf.String(), "\n") - lastWasBlank := false - for _, line := range in { - if strings.TrimSpace(line) == "" { - if lastWasBlank { - continue - } - lastWasBlank = true - } else { - lastWasBlank = false - } - - out = append(out, line) - } - return strings.Join(out, "\n") -} - -func main() { - generateUnitTestWorkflows() - generateVitessTesterWorkflows(vitessTesterMap, clusterVitessTesterTemplate) - generateClusterWorkflows(clusterList, clusterTestTemplate) - generateClusterWorkflows(clusterDockerList, clusterTestDockerTemplate) -} - -func canonnizeList(list []string) []string { - var output []string - for _, item := range list { - if item := strings.TrimSpace(item); item != "" { - output = append(output, item) - } - } - return output -} - -func generateVitessTesterWorkflows(mp map[string]string, tpl string) { - for test, testPath := range mp { - tt := &vitessTesterTest{ - Name: fmt.Sprintf("Vitess Tester (%v)", test), - RunsOn: defaultRunnerName, - GoPrivate: goPrivate, - Path: testPath, - } - - templateFileName := tpl - tt.FileName = fmt.Sprintf("vitess_tester_%s.yml", test) - workflowPath := fmt.Sprintf("%s/%s", workflowConfigDir, tt.FileName) - err := writeFileFromTemplate(templateFileName, workflowPath, tt) - if err != nil { - log.Print(err) - } - } -} - -func generateClusterWorkflows(list []string, tpl string) { - clusters := canonnizeList(list) - for _, cluster := range clusters { - for _, mysqlVersion := range clusterMySQLVersions() { - test := &clusterTest{ - Name: fmt.Sprintf("Cluster (%s)", cluster), - Shard: cluster, - BuildTag: buildTag[cluster], - RunsOn: defaultRunnerName, - GoPrivate: goPrivate, - } - cores16Clusters := canonnizeList(clusterRequiring16CoresMachines) - for _, cores16Cluster := range cores16Clusters { - if cores16Cluster == cluster { - test.RunsOn = cores16RunnerName - break - } - } - makeToolClusters := canonnizeList(clustersRequiringMakeTools) - for _, makeToolCluster := range makeToolClusters { - if makeToolCluster == cluster { - test.MakeTools = true - break - } - } - memoryCheckClusters := canonnizeList(clustersRequiringMemoryCheck) - for _, memCheckCluster := range memoryCheckClusters { - if memCheckCluster == cluster { - test.MemoryCheck = true - break - } - } - xtraBackupClusters := canonnizeList(clustersRequiringXtraBackup) - for _, xtraBackupCluster := range xtraBackupClusters { - if xtraBackupCluster == cluster { - test.InstallXtraBackup = true - break - } - } - minioClusters := canonnizeList(clusterRequiringMinio) - for _, minioCluster := range minioClusters { - if minioCluster == cluster { - test.NeedsMinio = true - break - } - } - if mysqlVersion == mysql57 { - test.Platform = string(mysql57) - } - if strings.HasPrefix(cluster, "vreplication") || strings.HasSuffix(cluster, "heavy") { - test.LimitResourceUsage = true - } - if strings.Contains(cluster, "vrepl") { - test.EnableBinlogTransactionCompression = true - test.EnablePartialJSON = true - } - mysqlVersionIndicator := "" - if mysqlVersion != defaultMySQLVersion && len(clusterMySQLVersions()) > 1 { - mysqlVersionIndicator = "_" + string(mysqlVersion) - test.Name = test.Name + " " + string(mysqlVersion) - } - if strings.Contains(test.Shard, "partial_keyspace") { - test.PartialKeyspace = true - } - - workflowPath := fmt.Sprintf("%s/cluster_endtoend_%s%s.yml", workflowConfigDir, cluster, mysqlVersionIndicator) - templateFileName := tpl - if test.Platform != "" { - templateFileName = fmt.Sprintf(tpl, "_"+test.Platform) - } else if strings.Contains(templateFileName, "%s") { - templateFileName = fmt.Sprintf(tpl, "") - } - test.FileName = fmt.Sprintf("cluster_endtoend_%s%s.yml", cluster, mysqlVersionIndicator) - err := writeFileFromTemplate(templateFileName, workflowPath, test) - if err != nil { - log.Print(err) - } - } - } -} - -func generateUnitTestWorkflows() { - for _, platform := range unitTestDatabases { - for _, evalengine := range []string{"1", "0"} { - test := &unitTest{ - Name: fmt.Sprintf("Unit Test (%s%s)", evalengineToString(evalengine), platform), - RunsOn: defaultRunnerName, - Platform: string(platform), - GoPrivate: goPrivate, - Evalengine: evalengine, - } - test.FileName = fmt.Sprintf("unit_test_%s%s.yml", evalengineToString(evalengine), platform) - path := fmt.Sprintf("%s/%s", workflowConfigDir, test.FileName) - err := writeFileFromTemplate(unitTestTemplate, path, test) - if err != nil { - log.Print(err) - } - } - } - - // Generate unit tests with race detection - for _, evalengine := range []string{"1", "0"} { - raceTest := &unitTest{ - Name: fmt.Sprintf("Unit Test (%sRace)", evalengineToRaceNamePrefix(evalengine)), - RunsOn: cores16RunnerName, - Platform: string(mysql80), - GoPrivate: goPrivate, - Evalengine: evalengine, - Race: true, - } - raceTest.FileName = fmt.Sprintf("unit_race%s.yml", evalengineToFileSuffix(evalengine)) - path := fmt.Sprintf("%s/%s", workflowConfigDir, raceTest.FileName) - err := writeFileFromTemplate(unitTestTemplate, path, raceTest) - if err != nil { - log.Print(err) - } - } -} - -func evalengineToString(evalengine string) string { - if evalengine == "1" { - return "evalengine_" - } - return "" -} - -func evalengineToNameSuffix(evalengine string) string { - if evalengine == "1" { - return " evalengine" - } - return "" -} - -func evalengineToRaceNamePrefix(evalengine string) string { - if evalengine == "1" { - return "Evalengine_" - } - return "" -} - -func evalengineToFileSuffix(evalengine string) string { - if evalengine == "1" { - return "_evalengine" - } - return "" -} - -func writeFileFromTemplate(templateFile, filePath string, test any) error { - tpl := template.New(path.Base(templateFile)) - tpl.Funcs(template.FuncMap{ - "contains": strings.Contains, - }) - tpl, err := tpl.ParseFiles(templateFile) - if err != nil { - return fmt.Errorf("Error: %s\n", err) - } - - buf := &bytes.Buffer{} - err = tpl.Execute(buf, test) - if err != nil { - return fmt.Errorf("Error: %s\n", err) - } - - f, err := os.Create(filePath) - if err != nil { - return fmt.Errorf("Error creating file: %s\n", err) - } - if _, err := f.WriteString("# DO NOT MODIFY: THIS FILE IS GENERATED USING \"make generate_ci_workflows\"\n\n"); err != nil { - return err - } - if _, err := f.WriteString(mergeBlankLines(buf)); err != nil { - return err - } - fmt.Printf("Generated %s\n", filePath) - return nil -} diff --git a/test/config.json b/test/config.json index 3c737f23bd3..fb111c47bef 100644 --- a/test/config.json +++ b/test/config.json @@ -1,2086 +1,2420 @@ { - "Tests": { - "java": { - "File": "", - "Packages": [], - "Args": [], - "Command": [ - "make", - "java_test" - ], - "Manual": false, - "Shard": "java", - "Tags": [] - }, - "client_test": { - "File": "", - "Packages": [], - "Args": [], - "Command": [ - "test/client_test.sh" - ], - "Manual": false, - "Shard": "java", - "Tags": [] - }, - "e2e": { - "File": "", - "Packages": [], - "Args": [], - "Command": [ - "tools/e2e_test_runner.sh" - ], - "Manual": false, - "Shard": "", - "Tags": [] - }, - "e2e_race": { - "File": "", - "Packages": [], - "Args": [], - "Command": [ - "make", - "e2e_test_race" - ], - "Manual": false, - "Shard": "", - "Tags": [] - }, - "unit": { - "File": "", - "Packages": [], - "Args": [], - "Command": [ - "tools/unit_test_runner.sh" - ], - "Manual": false, - "Shard": "", - "Tags": [] - }, - "unit_race": { - "File": "", - "Packages": [], - "Args": [], - "Command": [ - "make", - "unit_test_race" - ], - "Manual": false, - "Shard": "5", - "Tags": [] - }, - "local_example": { - "File": "", - "Packages": [], - "Args": [], - "Command": [ - "test/local_example.sh" - ], - "Manual": false, - "Shard": "", - "Tags": [] - }, - "region_example": { - "File": "", - "Packages": [], - "Args": [], - "Command": [ - "test/region_example.sh" - ], - "Manual": false, - "Shard": "", - "Tags": [] - }, - "backup_pitr": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/backup/pitr" - ], - "Args": [ - "-timeout", - "30m" - ], - "Command": [], - "Manual": false, - "Shard": "backup_pitr", - "Tags": [] - }, - "backup_pitr_xtrabackup": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/backup/pitr_xtrabackup" - ], - "Args": [ - "-timeout", - "30m" - ], - "Command": [], - "Manual": false, - "Shard": "backup_pitr_xtrabackup", - "Tags": [] - }, - "backup_pitr_mysqlshell": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/backup/pitr_mysqlshell" - ], - "Args": [ - "-timeout", - "30m" - ], - "Command": [], - "Manual": false, - "Shard": "backup_pitr_mysqlshell", - "Tags": [] - }, - "backup": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/backup/vtctlbackup" - ], - "Args": [ - "-timeout", - "30m" - ], - "Command": [], - "Manual": false, - "Shard": "vtctlbackup_sharded_clustertest_heavy", - "Tags": [] - }, - "backup_mysqlctld": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/backup/mysqlctld" - ], - "Args": [ - "-timeout", - "30m" - ], - "Command": [], - "Manual": false, - "Shard": "21", - "Tags": [] - }, - "backup_s3": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/backup/s3" - ], - "Args": [ - "-timeout", - "30m" - ], - "Command": [], - "Manual": false, - "Shard": "21", - "Tags": [] - }, - "backup_only": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/backup/vtbackup" - ], - "Args": [ - "-timeout", - "20m" - ], - "Command": [], - "Manual": false, - "Shard": "vtbackup", - "Tags": [ - "upgrade_downgrade_backups" - ] - }, - "backup_xtrabackup": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/backup/xtrabackup" - ], - "Args": [ - "-timeout", - "30m" - ], - "Command": [], - "Manual": false, - "Shard": "xb_backup", - "Tags": [] - }, - "backup_xtrabackup_xbstream": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/backup/xtrabackupstream" - ], - "Args": [ - "-run", - "XtrabackupStream", - "-timeout", - "30m" - ], - "Command": [], - "Manual": false, - "Shard": "xb_backup", - "Tags": [] - }, - "backup_xtrabackup_xbstream_lz4": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/backup/xtrabackupstream" - ], - "Args": [ - "-run", - "XtrabackupStreamWithlz4Compression", - "-timeout", - "30m" - ], - "Command": [], - "Manual": false, - "Shard": "xb_backup", - "Tags": [] - }, - "cellalias": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/cellalias" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "13", - "Tags": [] - }, - "prepare_statement": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/preparestmt" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "12", - "Tags": [ - "upgrade_downgrade_query_serving_queries" - ] - }, - "mysql_server": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/mysqlserver" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "mysql_server_vault", - "Tags": [] - }, - "messaging": { - "File": "messaging_test.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/messaging" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "12", - "Tags": [] - }, - "clustertest": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/clustertest" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtctlbackup_sharded_clustertest_heavy", - "Tags": [] - }, - "encrypted_replication": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/encryption/encryptedreplication" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "12", - "Tags": [] - }, - "encrypted_transport": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/encryption/encryptedtransport" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "12", - "Tags": [] - }, - "keyspace": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/keyspace" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "12", - "Tags": [ - "site_test" - ] - }, - "mysqlctl": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/mysqlctl" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "12", - "Tags": [ - "site_test" - ] - }, - "mysqlctld": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/mysqlctld" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "12", - "Tags": [ - "site_test" - ] - }, - "onlineddl_vrepl": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/onlineddl/vrepl" - ], - "Args": [ - "-timeout", - "30m" - ], - "Command": [], - "Manual": false, - "Shard": "onlineddl_vrepl", - "Tags": [] - }, - "onlineddl_vrepl_stress": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/onlineddl/vrepl_stress" - ], - "Args": [ - "-timeout", - "30m" - ], - "Command": [], - "Manual": false, - "Shard": "onlineddl_vrepl_stress", - "Tags": [] - }, - "onlineddl_vrepl_suite": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/onlineddl/vrepl_suite" - ], - "Args": [ - "-timeout", - "30m" - ], - "Command": [], - "Manual": false, - "Shard": "onlineddl_vrepl_suite", - "Tags": [] - }, - "onlineddl_vrepl_stress_suite": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/onlineddl/vrepl_stress_suite" - ], - "Args": [ - "-timeout", - "30m" - ], - "Command": [], - "Manual": false, - "Shard": "onlineddl_vrepl_stress_suite", - "Tags": [] - }, - "onlineddl_revert": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/onlineddl/revert" - ], - "Args": [ - "-timeout", - "30m" - ], - "Command": [], - "Manual": false, - "Shard": "onlineddl_revert", - "Tags": [] - }, - "onlineddl_scheduler": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/onlineddl/scheduler" - ], - "Args": [ - "-timeout", - "30m" - ], - "Command": [], - "Manual": false, - "Shard": "onlineddl_scheduler", - "Tags": [] - }, - "onlineddl_flow": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/onlineddl/flow" - ], - "Args": [ - "-timeout", - "30m" - ], - "Command": [], - "Manual": false, - "Shard": "onlineddl_flow", - "Tags": [ - "upgrade_downgrade_onlineddl_flow" - ] - }, - "schemadiff_vrepl": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/schemadiff/vrepl" - ], - "Args": [ - "-timeout", - "30m" - ], - "Command": [], - "Manual": false, - "Shard": "schemadiff_vrepl", - "Tags": [] - }, - "recovery": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/recovery/unshardedrecovery" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtctlbackup_sharded_clustertest_heavy", - "Tags": [] - }, - "emergencyreparent": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/reparent/emergencyreparent" - ], - "Args": [ - "-timeout", - "20m" - ], - "Command": [], - "Manual": false, - "Shard": "ers_prs_newfeatures_heavy", - "Tags": [ - "upgrade_downgrade_reparent" - ] - }, - "plannedreparent": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/reparent/plannedreparent" - ], - "Args": [ - "-timeout", - "20m" - ], - "Command": [], - "Manual": false, - "Shard": "ers_prs_newfeatures_heavy", - "Tags": [ - "upgrade_downgrade_reparent" - ] - }, - "newfeatures": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/reparent/newfeaturetest" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "ers_prs_newfeatures_heavy", - "Tags": [ - "" - ] - }, - "sharded": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/sharded" - ], - "Args": [ - "-timeout", - "30m" - ], - "Command": [], - "Manual": false, - "Shard": "vtctlbackup_sharded_clustertest_heavy", - "Tags": [] - }, - "tabletgateway_buffer_reparent": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/tabletgateway/buffer/reparent" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "13", - "Tags": [] - }, - "tabletgateway_buffer_reshard": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/tabletgateway/buffer/reshard" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "13", - "Tags": [] - }, - "tabletgateway": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/tabletgateway" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "15", - "Tags": [] - }, - "tabletmanager": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/tabletmanager" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "18", - "Tags": [ - "site_test" - ] - }, - "tabletmanager_replication_manager": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/tabletmanager/replication_manager" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "18", - "Tags": [] - }, - "tabletmanager_consul": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/tabletmanager" - ], - "Args": [ - "--topo-flavor=consul" - ], - "Command": [], - "Manual": false, - "Shard": "tabletmanager_consul", - "Tags": [ - "site_test" - ] - }, - "tabletmanager_throttler_topo": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/tabletmanager/throttler_topo" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "tabletmanager_throttler_topo", - "Tags": [ - "site_test" - ] - }, - "tabletmanager_tablegc": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/tabletmanager/tablegc" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "tabletmanager_tablegc", - "Tags": [ - "site_test" - ] - }, - "tabletmanager_zk2": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/tabletmanager" - ], - "Args": [ - "--topo-flavor=zk2" - ], - "Command": [], - "Manual": false, - "Shard": "docker_cluster", - "Tags": [ - "site_test" - ] - }, - "upgrade": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/versionupgrade" - ], - "Args": [ - "-keep-data", - "-force-vtdataroot", - "/tmp/vtdataroot/vtroot_10901", - "-force-port-start", - "vtctlbackup_sharded_clustertest_heavy900", - "-force-base-tablet-uid", - "vtctlbackup_sharded_clustertest_heavy90" - ], - "Command": [], - "Manual": false, - "Shard": "28", - "Tags": [] - }, - "vtgate": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_general_heavy", - "Tags": [] - }, - "vtgate_connectiondrain": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/connectiondrain" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_general_heavy", - "Tags": [] - }, - "vtgate_queries_derived": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/queries/derived" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_queries", - "Tags": [ - "upgrade_downgrade_query_serving_queries" - ] - }, - "vtgate_queries_aggregation": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/queries/aggregation" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_queries", - "Tags": [ - "upgrade_downgrade_query_serving_queries" - ] - }, - "vtgate_queries_foundrows": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/queries/foundrows" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_queries", - "Tags": [ - "upgrade_downgrade_query_serving_queries" - ] - }, - "vtgate_queries_informationschema": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/queries/informationschema" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_queries", - "Tags": [ - "upgrade_downgrade_query_serving_queries" - ] - }, - "vtgate_queries_misc": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/queries/misc" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_queries", - "Tags": [ - "upgrade_downgrade_query_serving_queries" - ] - }, - "vtgate_queries_multi_query": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/queries/multi_query" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_queries", - "Tags": [ - "upgrade_downgrade_query_serving_queries" - ] - }, - "vtgate_queries_timeout": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/queries/timeout" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_queries", - "Tags": [ - "upgrade_downgrade_query_serving_queries" - ] - }, - "vtgate_queries_normalize": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/queries/normalize" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_queries", - "Tags": [ - "upgrade_downgrade_query_serving_queries" - ] - }, - "vtgate_queries_no_scatter": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/queries/no_scatter" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_queries", - "Tags": [ - "upgrade_downgrade_query_serving_queries" - ] - }, - "vtgate_queries_orderby": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/queries/orderby" - ], - "Args": [ - "-timeout", - "20m" - ], - "Command": [], - "Manual": false, - "Shard": "vtgate_queries", - "Tags": [ - "upgrade_downgrade_query_serving_queries" - ] - }, - "vtgate_queries_tpch": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/queries/tpch" - ], - "Args": [ - "-timeout", - "20m" - ], - "Command": [], - "Manual": false, - "Shard": "vtgate_queries", - "Tags": [ - "upgrade_downgrade_query_serving_queries_2" - ] - }, - "vtgate_queries_subquery": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/queries/subquery" - ], - "Args": [ - "-timeout", - "20m" - ], - "Command": [], - "Manual": false, - "Shard": "vtgate_queries", - "Tags": [ - "upgrade_downgrade_query_serving_queries_2" - ] - }, - "vtgate_queries_union": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/queries/union" - ], - "Args": [ - "-timeout", - "20m" - ], - "Command": [], - "Manual": false, - "Shard": "vtgate_queries", - "Tags": [ - "upgrade_downgrade_query_serving_queries_2" - ] - }, - "vtgate_queries_insert": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/queries/dml" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_queries", - "Tags": [ - "upgrade_downgrade_query_serving_queries_2" - ] - }, - "vtgate_queries_vexplain": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/queries/vexplain" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_queries", - "Tags": [ - "upgrade_downgrade_query_serving_queries_2" - ] - }, - "vtgate_queries_reference": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/queries/reference" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_queries", - "Tags": [ - "upgrade_downgrade_query_serving_queries_2" - ] - }, - "vtgate_queries_random": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/queries/random" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_queries", - "Tags": [ - "upgrade_downgrade_query_serving_queries_2" - ] - }, - "vtgate_kill": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/queries/kill" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_queries", - "Tags": [ - "upgrade_downgrade_query_serving_queries_2" - ] - }, - "vtgate_concurrentdml": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/concurrentdml" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_concurrentdml", - "Tags": [] - }, - "vtgate_schema": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/schema" - ], - "Args": [ - "-timeout", - "20m" - ], - "Command": [], - "Manual": false, - "Shard": "vtgate_schema", - "Tags": [ - "upgrade_downgrade_query_serving_schema" - ] - }, - "vtgate_schematracker_loadkeyspace": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/schematracker/loadkeyspace" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_schema_tracker", - "Tags": [] - }, - "vtgate_schematracker_restarttablet": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/schematracker/restarttablet" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_schema_tracker", - "Tags": [] - }, - "vtgate_schematracker_sharded": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/schematracker/sharded" - ], - "Args": [ - "-timeout", - "20m" - ], - "Command": [], - "Manual": false, - "Shard": "vtgate_schema_tracker", - "Tags": [ - "upgrade_downgrade_query_serving_schema" - ] - }, - "vtgate_schematracker_sharded_prs": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/schematracker/sharded_prs" - ], - "Args": [ - "-timeout", - "20m" - ], - "Command": [], - "Manual": false, - "Shard": "vtgate_schema_tracker", - "Tags": [ - "upgrade_downgrade_query_serving_schema" - ] - }, - "vtgate_schematracker_unsharded": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/schematracker/unsharded" - ], - "Args": [ - "-timeout", - "20m" - ], - "Command": [], - "Manual": false, - "Shard": "vtgate_schema_tracker", - "Tags": [ - "upgrade_downgrade_query_serving_schema" - ] - }, - "vtgate_schematracker_viewsdisabled": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/schematracker/viewsdisabled" - ], - "Args": [ - "-timeout", - "20m" - ], - "Command": [], - "Manual": false, - "Shard": "vtgate_schema_tracker", - "Tags": [ - "upgrade_downgrade_query_serving_schema" - ] - }, - "vtgate_mysql80": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/schematracker/multi_ks" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "mysql80", - "RetryMax": 1, - "Tags": [] - }, - "vtgate_sequence": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/sequence" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_general_heavy", - "Tags": [] - }, - "vtgate_setstatement": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/reservedconn" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_reservedconn", - "Tags": [] - }, - "vtgate_reserved_conn1": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/reservedconn/reconnect1" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_reservedconn", - "Tags": [] - }, - "vtgate_reserved_conn2": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/reservedconn/reconnect2" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_reservedconn", - "Tags": [] - }, - "vtgate_reserved_conn3": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/reservedconn/reconnect3" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_reservedconn", - "Tags": [] - }, - "vtgate_reserved_conn4": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/reservedconn/reconnect4" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_reservedconn", - "Tags": [] - }, - "vtgate_tablet_healthcheck_cache": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/tablet_healthcheck_cache" - ], - "Args": [ - "-timeout", - "45m" - ], - "Command": [], - "Manual": false, - "Shard": "vtgate_tablet_healthcheck_cache", - "Tags": [] - }, - "vtgate_transaction": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/transaction" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_transaction", - "Tags": [] - }, - "vtgate_transaction_restart": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/transaction/restart" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_transaction", - "Tags": [] - }, - "vtgate_transaction_rollback": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/transaction/rollback" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_transaction", - "Tags": [] - }, - "vtgate_transaction_single": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/transaction/single" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_transaction", - "Tags": [] - }, - "vtgate_transaction_twopc": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/transaction/twopc" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_transaction", - "Tags": [] - }, - "vtgate_transaction_twopc_metric": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/transaction/twopc/metric" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_transaction", - "Tags": [] - }, - "vtgate_transaction_twopc_stress": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/transaction/twopc/stress" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_transaction", - "Tags": [] - }, - "vtgate_transaction_twopc_fuzz": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/transaction/twopc/fuzz" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_transaction", - "Tags": [] - }, - "vtgate_transaction_partial_exec": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/partialfailure" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_transaction", - "Tags": [] - }, - "vtgate_plantests": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/plan_tests" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_plantests", - "Tags": [] - }, - "vtgate_unsharded": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/unsharded" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_unsharded", - "Tags": [] - }, - "vtgate_vschema": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/vschema" - ], - "Args": [ - "-timeout", - "20m" - ], - "Command": [], - "Manual": false, - "Shard": "vtgate_vschema", - "Tags": [ - "upgrade_downgrade_query_serving_schema" - ] - }, - "vtgate_readafterwrite": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/readafterwrite" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_readafterwrite", - "Tags": [] - }, - "vtgate_dbddlplugin": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/createdb_plugin" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_general_heavy", - "Tags": [] - }, - "vtgate_foreignkey": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/foreignkey" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_foreignkey_stress", - "Tags": [] - }, - "vtgate_foreignkey_routing": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/foreignkey/routing" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_foreignkey_stress", - "Tags": [] - }, - "vtgate_foreignkey_stress": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/foreignkey/stress" - ], - "Args": [ - "-timeout", - "30m" - ], - "Command": [], - "Manual": false, - "Shard": "vtgate_foreignkey_stress", - "Tags": [] - }, - "vtgate_gen4": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/gen4" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_gen4", - "Tags": [] - }, - "vtgate_godriver": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/godriver" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_godriver", - "Tags": [] - }, - "vtgate_watchkeyspace": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/keyspace_watches" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_topo", - "Tags": [] - }, - "vtgate_grpc_api": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/grpc_api" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_general_heavy", - "Tags": [] - }, - "topo_zk2": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/topotest/zk2" - ], - "Args": [ - "--topo-flavor=zk2" - ], - "Command": [], - "Manual": false, - "Shard": "docker_cluster", - "Tags": [] - }, - "topo_consul": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/topotest/consul" - ], - "Args": [ - "--topo-flavor=consul" - ], - "Command": [], - "Manual": false, - "Shard": "vtgate_topo_consul", - "Tags": [] - }, - "topo_etcd2": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/topotest/etcd2" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_topo_etcd", - "Tags": [] - }, - "errs_as_warns": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/errors_as_warnings" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_general_heavy", - "Tags": [] - }, - "consolidator": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/consolidator" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_general_heavy", - "Tags": [] - }, - "prefixfanout": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/prefixfanout" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_vindex_heavy", - "Tags": [] - }, - "vindex_bindvars": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/vindex_bindvars" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_vindex_heavy", - "Tags": [] - }, - "vindex_secondary": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtgate/sec_vind" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtgate_vindex_heavy", - "Tags": [] - }, - "vttest_sample": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtcombo" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "docker_cluster", - "Tags": [] - }, - "xb_recovery": { - "File": "recovery_test.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/recovery/xtrabackup" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "xb_recovery", - "Tags": [] - }, - "vreplication_materialize": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "Materialize" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_partial_movetables_and_materialize", - "Tags": [] - }, - "vreplication_vtctldclient_materialize": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "TestMaterializeVtctldClient" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_partial_movetables_and_materialize", - "Tags": [] - }, - "vreplication_cellalias": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "CellAlias" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_cellalias", - "Tags": [] - }, - "vreplication_movetables_ignore_source_keyspace": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "TestMoveTablesIgnoreSourceKeyspace" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_cellalias", - "Tags": [] - }, - "vreplication_multi_tenant": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "MultiTenant" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_multi_tenant", - "Tags": [] - }, - "vreplication_partial_movetables_basic": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "PartialMoveTablesBasic" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_partial_movetables_and_materialize", - "Tags": [] - }, - "vdiff_multiple_movetables_test.go": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "TestMultipleConcurrentVDiffs" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_partial_movetables_and_materialize", - "Tags": [] - }, - "vreplication_movetables_buffering": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "TestMoveTablesBuffering" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_cellalias", - "Tags": [] - }, - "vreplication_onlineddl_vdiff": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "TestOnlineDDLVDiff" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_cellalias", - "Tags": [] - }, - "vreplication_vschema_load": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "TestVSchemaChangesUnderLoad" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_cellalias", - "Tags": [] - }, - "sidecardb": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "TestSidecarDB" - ], - "Command": [], - "Manual": false, - "Shard": "schemadiff_vrepl", - "Tags": [] - }, - "vreplication_basic": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "TestBasicVreplicationWorkflow", - "-timeout", - "20m" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_basic", - "Tags": [] - }, - "vreplication_copy_parallel": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "TestVreplicationCopyParallel", - "-timeout", - "20m" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_copy_parallel", - "Tags": [] - }, - "vreplication_partial_movetables_sequences": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "TestPartialMoveTablesWithSequences" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_partial_movetables_and_materialize", - "Tags": [] - }, - "vreplication_sequence_reset_on_switch_traffic": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "TestSequenceResetOnSwitchTraffic" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_partial_movetables_and_materialize", - "Tags": [] - }, - "vstream_flush_binlog": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "TestVStreamFlushBinlog" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_basic", - "Tags": [] - }, - "multi_vstreams_keyspace_reshard": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "TestMultiVStreamsKeyspaceReshard", - "-timeout", - "15m" - ], - "Command": [], - "Manual": false, - "Shard": "vstream", - "Tags": [] - }, - "vstream_failover": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "VStreamFailover" - ], - "Command": [], - "Manual": false, - "Shard": "vstream", - "Tags": [] - }, - "vstream_stoponreshard_true": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "VStreamStopOnReshardTrue" - ], - "Command": [], - "Manual": false, - "Shard": "vstream", - "Tags": [] - }, - "vstream_stoponreshard_false": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "VStreamStopOnReshardFalse" - ], - "Command": [], - "Manual": false, - "Shard": "vstream", - "Tags": [] - }, - "vstream_with_keyspaces_to_watch": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "VStreamWithKeyspacesToWatch" - ], - "Command": [], - "Manual": false, - "Shard": "vstream", - "Tags": [] - }, - "vtop_example": { - "File": "", - "Packages": [], - "Args": [], - "Command": [ - "test/vtop_example.sh" - ], - "Manual": false, - "Shard": "", - "Tags": [] - }, - "vtorc_primary_failure": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtorc/primaryfailure" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtorc", - "Tags": [] - }, - "vtorc_api": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtorc/api" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtorc", - "Tags": [] - }, - "vtorc_general": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtorc/general" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtorc", - "Tags": [] - }, - "vtorc_readtopologyinstance": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtorc/readtopologyinstance" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vtorc", - "Tags": [] - }, - "vault": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vault" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "mysql_server_vault", - "Tags": [] - }, - "vreplication_v2": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "TestBasicV2Workflows", - "-timeout", - "30m" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_v2", - "Tags": [] - }, - "global_routing": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "TestGlobalRouting", - "-timeout", - "30m" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_v2", - "Tags": [] - }, - "vreplication_fk": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "TestFKWorkflow" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_cellalias", - "Tags": [] - }, - "vreplication_foreign_key_stress": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "TestFKExt" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_foreign_key_stress", - "Tags": [] - }, - "vreplication_across_db_versions": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "TestV2WorkflowsAcrossDBVersions", - "-timeout", - "20m" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_across_db_versions", - "Tags": [] - }, - "vreplication_mariadb_to_mysql": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "TestMoveTablesMariaDBToMySQL", - "-timeout", - "20m" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_mariadb_to_mysql", - "Tags": [] - }, - "vreplication_migrate": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "TestMigrate", - "-timeout", - "30m" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_migrate", - "Tags": [] - }, - "vdiff2": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "TestVDiff2", - "-timeout", - "30m" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_vdiff2", - "Tags": [] - }, - "vreplication_vtctldclient_cli": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "TestVtctldclientCLI", - "-timeout", - "20m" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_vtctldclient_movetables_tz", - "Tags": [] - }, - "vreplication_movetables_tz": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "TestMoveTablesTZ" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_vtctldclient_movetables_tz", - "Tags": [] - }, - "loopkup_index": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vreplication" - ], - "Args": [ - "-run", - "TestLookupIndex" - ], - "Command": [], - "Manual": false, - "Shard": "vreplication_vtctldclient_movetables_tz", - "Tags": [] - }, - "vtadmin": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/vtadmin" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "15", - "Tags": [] - }, - "topo_connection_cache": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/topoconncache" - ], - "Args": [ - "-run", - "TestVtctldListAllTablets" - ], - "Command": [], - "Manual": false, - "Shard": "topo_connection_cache", - "Tags": [] - }, - "prscomplex": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/reparent/prscomplex" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vttablet_prscomplex", - "Tags": [ - "" - ] - }, - "prssettingspool": { - "File": "unused.go", - "Packages": [ - "vitess.io/vitess/go/test/endtoend/reparent/prssettingspool" - ], - "Args": [], - "Command": [], - "Manual": false, - "Shard": "vttablet_prscomplex", - "Tags": [ - "" - ] - } - } + "Tests": { + "java": { + "File": "", + "Packages": [], + "Args": [], + "Command": [ + "make", + "java_test" + ], + "Manual": false, + "Shard": "java", + "Tags": [], + "Needs": [] + }, + "client_test": { + "File": "", + "Packages": [], + "Args": [], + "Command": [ + "test/client_test.sh" + ], + "Manual": false, + "Shard": "java", + "Tags": [], + "Needs": [] + }, + "e2e": { + "File": "", + "Packages": [], + "Args": [], + "Command": [ + "tools/e2e_test_runner.sh" + ], + "Manual": false, + "Shard": "", + "Tags": [], + "Needs": [] + }, + "e2e_race": { + "File": "", + "Packages": [], + "Args": [], + "Command": [ + "make", + "e2e_test_race" + ], + "Manual": false, + "Shard": "", + "Tags": [], + "Needs": [] + }, + "unit": { + "File": "", + "Packages": [], + "Args": [], + "Command": [ + "tools/unit_test_runner.sh" + ], + "Manual": false, + "Shard": "", + "Tags": [], + "Needs": [] + }, + "unit_race": { + "File": "", + "Packages": [], + "Args": [], + "Command": [ + "make", + "unit_test_race" + ], + "Manual": false, + "Shard": "5", + "Tags": [], + "Needs": [] + }, + "local_example": { + "File": "", + "Packages": [], + "Args": [], + "Command": [ + "test/local_example.sh" + ], + "Manual": false, + "Shard": "", + "Tags": [], + "Needs": [] + }, + "region_example": { + "File": "", + "Packages": [], + "Args": [], + "Command": [ + "test/region_example.sh" + ], + "Manual": false, + "Shard": "", + "Tags": [], + "Needs": [] + }, + "backup_pitr": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/backup/pitr" + ], + "Args": [ + "-timeout", + "30m" + ], + "Command": [], + "Manual": false, + "Shard": "backup_pitr", + "Tags": [], + "Needs": [] + }, + "backup_pitr_xtrabackup": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/backup/pitr_xtrabackup" + ], + "Args": [ + "-timeout", + "30m" + ], + "Command": [], + "Manual": false, + "Shard": "backup_pitr_xtrabackup", + "Tags": [], + "Needs": [ + "xtrabackup" + ] + }, + "backup_pitr_mysqlshell": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/backup/pitr_mysqlshell" + ], + "Args": [ + "-timeout", + "30m" + ], + "Command": [], + "Manual": false, + "Shard": "backup_pitr_mysqlshell", + "Tags": [], + "Needs": [] + }, + "backup": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/backup/vtctlbackup" + ], + "Args": [ + "-timeout", + "30m" + ], + "Command": [], + "Manual": false, + "Shard": "vtctlbackup_sharded_clustertest_heavy", + "Tags": [], + "Needs": [ + "limit-resources" + ] + }, + "backup_mysqlctld": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/backup/mysqlctld" + ], + "Args": [ + "-timeout", + "30m" + ], + "Command": [], + "Manual": false, + "Shard": "21", + "Tags": [], + "Needs": [ + "minio" + ] + }, + "backup_s3": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/backup/s3" + ], + "Args": [ + "-timeout", + "30m" + ], + "Command": [], + "Manual": false, + "Shard": "21", + "Tags": [], + "Needs": [ + "minio" + ] + }, + "backup_only": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/backup/vtbackup" + ], + "Args": [ + "-timeout", + "20m" + ], + "Command": [], + "Manual": false, + "Shard": "vtbackup", + "Tags": [ + "upgrade_downgrade_backups" + ], + "Needs": [] + }, + "backup_xtrabackup": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/backup/xtrabackup" + ], + "Args": [ + "-timeout", + "30m" + ], + "Command": [], + "Manual": false, + "Shard": "xb_backup", + "Tags": [], + "Needs": [ + "xtrabackup" + ] + }, + "backup_xtrabackup_xbstream": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/backup/xtrabackupstream" + ], + "Args": [ + "-run", + "XtrabackupStream", + "-timeout", + "30m" + ], + "Command": [], + "Manual": false, + "Shard": "xb_backup", + "Tags": [], + "Needs": [ + "xtrabackup" + ] + }, + "backup_xtrabackup_xbstream_lz4": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/backup/xtrabackupstream" + ], + "Args": [ + "-run", + "XtrabackupStreamWithlz4Compression", + "-timeout", + "30m" + ], + "Command": [], + "Manual": false, + "Shard": "xb_backup", + "Tags": [], + "Needs": [ + "xtrabackup" + ] + }, + "cellalias": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/cellalias" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "13", + "Tags": [], + "Needs": [] + }, + "prepare_statement": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/preparestmt" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "12", + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ], + "Needs": [] + }, + "mysql_server": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/mysqlserver" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "mysql_server_vault", + "Tags": [], + "Needs": [ + "consul" + ] + }, + "messaging": { + "File": "messaging_test.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/messaging" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "12", + "Tags": [], + "Needs": [] + }, + "clustertest": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/clustertest" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtctlbackup_sharded_clustertest_heavy", + "Tags": [], + "Needs": [ + "limit-resources" + ] + }, + "encrypted_replication": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/encryption/encryptedreplication" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "12", + "Tags": [], + "Needs": [] + }, + "encrypted_transport": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/encryption/encryptedtransport" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "12", + "Tags": [], + "Needs": [] + }, + "keyspace": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/keyspace" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "12", + "Tags": [ + "site_test" + ], + "Needs": [] + }, + "mysqlctl": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/mysqlctl" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "12", + "Tags": [ + "site_test" + ], + "Needs": [] + }, + "mysqlctld": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/mysqlctld" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "12", + "Tags": [ + "site_test" + ], + "Needs": [] + }, + "onlineddl_vrepl": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/onlineddl/vrepl" + ], + "Args": [ + "-timeout", + "30m" + ], + "Command": [], + "Manual": false, + "Shard": "onlineddl_vrepl", + "Tags": [], + "Needs": [ + "larger-runner", + "binlog-compression" + ] + }, + "onlineddl_vrepl_stress": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/onlineddl/vrepl_stress" + ], + "Args": [ + "-timeout", + "30m" + ], + "Command": [], + "Manual": false, + "Shard": "onlineddl_vrepl_stress", + "Tags": [], + "Needs": [ + "larger-runner", + "binlog-compression" + ] + }, + "onlineddl_vrepl_suite": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/onlineddl/vrepl_suite" + ], + "Args": [ + "-timeout", + "30m" + ], + "Command": [], + "Manual": false, + "Shard": "onlineddl_vrepl_suite", + "Tags": [], + "Needs": [ + "larger-runner", + "binlog-compression" + ] + }, + "onlineddl_vrepl_stress_suite": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/onlineddl/vrepl_stress_suite" + ], + "Args": [ + "-timeout", + "30m" + ], + "Command": [], + "Manual": false, + "Shard": "onlineddl_vrepl_stress_suite", + "Tags": [], + "Needs": [ + "larger-runner", + "binlog-compression" + ] + }, + "onlineddl_revert": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/onlineddl/revert" + ], + "Args": [ + "-timeout", + "30m" + ], + "Command": [], + "Manual": false, + "Shard": "onlineddl_revert", + "Tags": [], + "Needs": [] + }, + "onlineddl_scheduler": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/onlineddl/scheduler" + ], + "Args": [ + "-timeout", + "30m" + ], + "Command": [], + "Manual": false, + "Shard": "onlineddl_scheduler", + "Tags": [], + "Needs": [] + }, + "onlineddl_flow": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/onlineddl/flow" + ], + "Args": [ + "-timeout", + "30m" + ], + "Command": [], + "Manual": false, + "Shard": "onlineddl_flow", + "Tags": [ + "upgrade_downgrade_onlineddl_flow" + ], + "Needs": [] + }, + "schemadiff_vrepl": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/schemadiff/vrepl" + ], + "Args": [ + "-timeout", + "30m" + ], + "Command": [], + "Manual": false, + "Shard": "schemadiff_vrepl", + "Tags": [], + "Needs": [ + "binlog-compression" + ] + }, + "recovery": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/recovery/unshardedrecovery" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtctlbackup_sharded_clustertest_heavy", + "Tags": [], + "Needs": [ + "limit-resources" + ] + }, + "emergencyreparent": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/reparent/emergencyreparent" + ], + "Args": [ + "-timeout", + "20m" + ], + "Command": [], + "Manual": false, + "Shard": "ers_prs_newfeatures_heavy", + "Tags": [ + "upgrade_downgrade_reparent" + ], + "Needs": [ + "limit-resources" + ] + }, + "plannedreparent": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/reparent/plannedreparent" + ], + "Args": [ + "-timeout", + "20m" + ], + "Command": [], + "Manual": false, + "Shard": "ers_prs_newfeatures_heavy", + "Tags": [ + "upgrade_downgrade_reparent" + ], + "Needs": [ + "limit-resources" + ] + }, + "newfeatures": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/reparent/newfeaturetest" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "ers_prs_newfeatures_heavy", + "Tags": [ + "" + ], + "Needs": [ + "limit-resources" + ] + }, + "sharded": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/sharded" + ], + "Args": [ + "-timeout", + "30m" + ], + "Command": [], + "Manual": false, + "Shard": "vtctlbackup_sharded_clustertest_heavy", + "Tags": [], + "Needs": [ + "limit-resources" + ] + }, + "tabletgateway_buffer_reparent": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/tabletgateway/buffer/reparent" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "13", + "Tags": [], + "Needs": [] + }, + "tabletgateway_buffer_reshard": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/tabletgateway/buffer/reshard" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "13", + "Tags": [], + "Needs": [] + }, + "tabletgateway": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/tabletgateway" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "15", + "Tags": [], + "Needs": [] + }, + "tabletmanager": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/tabletmanager" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "18", + "Tags": [ + "site_test" + ], + "Needs": [ + "consul" + ] + }, + "tabletmanager_replication_manager": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/tabletmanager/replication_manager" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "18", + "Tags": [], + "Needs": [ + "consul" + ] + }, + "tabletmanager_consul": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/tabletmanager" + ], + "Args": [ + "--topo-flavor=consul" + ], + "Command": [], + "Manual": false, + "Shard": "tabletmanager_consul", + "Tags": [ + "site_test" + ], + "Needs": [ + "consul" + ] + }, + "tabletmanager_throttler_topo": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/tabletmanager/throttler_topo" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "tabletmanager_throttler_topo", + "Tags": [ + "site_test" + ], + "Needs": [] + }, + "tabletmanager_tablegc": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/tabletmanager/tablegc" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "tabletmanager_tablegc", + "Tags": [ + "site_test" + ], + "Needs": [] + }, + "tabletmanager_zk2": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/tabletmanager" + ], + "Args": [ + "--topo-flavor=zk2" + ], + "Command": [], + "Manual": false, + "Shard": "docker_cluster", + "Tags": [ + "site_test" + ], + "Needs": [] + }, + "upgrade": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/versionupgrade" + ], + "Args": [ + "-keep-data", + "-force-vtdataroot", + "/tmp/vtdataroot/vtroot_10901", + "-force-port-start", + "vtctlbackup_sharded_clustertest_heavy900", + "-force-base-tablet-uid", + "vtctlbackup_sharded_clustertest_heavy90" + ], + "Command": [], + "Manual": false, + "Shard": "28", + "Tags": [], + "Needs": [] + }, + "vtgate": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_general_heavy", + "Tags": [], + "Needs": [ + "limit-resources" + ] + }, + "vtgate_connectiondrain": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/connectiondrain" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_general_heavy", + "Tags": [], + "Needs": [ + "limit-resources" + ] + }, + "vtgate_queries_derived": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/derived" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_queries", + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ], + "Needs": [] + }, + "vtgate_queries_aggregation": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/aggregation" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_queries", + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ], + "Needs": [] + }, + "vtgate_queries_foundrows": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/foundrows" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_queries", + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ], + "Needs": [] + }, + "vtgate_queries_informationschema": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/informationschema" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_queries", + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ], + "Needs": [] + }, + "vtgate_queries_misc": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/misc" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_queries", + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ], + "Needs": [] + }, + "vtgate_queries_multi_query": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/multi_query" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_queries", + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ], + "Needs": [] + }, + "vtgate_queries_timeout": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/timeout" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_queries", + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ], + "Needs": [] + }, + "vtgate_queries_normalize": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/normalize" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_queries", + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ], + "Needs": [] + }, + "vtgate_queries_no_scatter": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/no_scatter" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_queries", + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ], + "Needs": [] + }, + "vtgate_queries_orderby": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/orderby" + ], + "Args": [ + "-timeout", + "20m" + ], + "Command": [], + "Manual": false, + "Shard": "vtgate_queries", + "Tags": [ + "upgrade_downgrade_query_serving_queries" + ], + "Needs": [] + }, + "vtgate_queries_tpch": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/tpch" + ], + "Args": [ + "-timeout", + "20m" + ], + "Command": [], + "Manual": false, + "Shard": "vtgate_queries", + "Tags": [ + "upgrade_downgrade_query_serving_queries_2" + ], + "Needs": [] + }, + "vtgate_queries_subquery": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/subquery" + ], + "Args": [ + "-timeout", + "20m" + ], + "Command": [], + "Manual": false, + "Shard": "vtgate_queries", + "Tags": [ + "upgrade_downgrade_query_serving_queries_2" + ], + "Needs": [] + }, + "vtgate_queries_union": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/union" + ], + "Args": [ + "-timeout", + "20m" + ], + "Command": [], + "Manual": false, + "Shard": "vtgate_queries", + "Tags": [ + "upgrade_downgrade_query_serving_queries_2" + ], + "Needs": [] + }, + "vtgate_queries_insert": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/dml" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_queries", + "Tags": [ + "upgrade_downgrade_query_serving_queries_2" + ], + "Needs": [] + }, + "vtgate_queries_vexplain": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/vexplain" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_queries", + "Tags": [ + "upgrade_downgrade_query_serving_queries_2" + ], + "Needs": [] + }, + "vtgate_queries_reference": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/reference" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_queries", + "Tags": [ + "upgrade_downgrade_query_serving_queries_2" + ], + "Needs": [] + }, + "vtgate_queries_random": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/random" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_queries", + "Tags": [ + "upgrade_downgrade_query_serving_queries_2" + ], + "Needs": [] + }, + "vtgate_kill": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/queries/kill" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_queries", + "Tags": [ + "upgrade_downgrade_query_serving_queries_2" + ], + "Needs": [] + }, + "vtgate_concurrentdml": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/concurrentdml" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_concurrentdml", + "Tags": [], + "Needs": [] + }, + "vtgate_schema": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/schema" + ], + "Args": [ + "-timeout", + "20m" + ], + "Command": [], + "Manual": false, + "Shard": "vtgate_schema", + "Tags": [ + "upgrade_downgrade_query_serving_schema" + ], + "Needs": [] + }, + "vtgate_schematracker_loadkeyspace": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/schematracker/loadkeyspace" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_schema_tracker", + "Tags": [], + "Needs": [] + }, + "vtgate_schematracker_restarttablet": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/schematracker/restarttablet" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_schema_tracker", + "Tags": [], + "Needs": [] + }, + "vtgate_schematracker_sharded": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/schematracker/sharded" + ], + "Args": [ + "-timeout", + "20m" + ], + "Command": [], + "Manual": false, + "Shard": "vtgate_schema_tracker", + "Tags": [ + "upgrade_downgrade_query_serving_schema" + ], + "Needs": [] + }, + "vtgate_schematracker_sharded_prs": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/schematracker/sharded_prs" + ], + "Args": [ + "-timeout", + "20m" + ], + "Command": [], + "Manual": false, + "Shard": "vtgate_schema_tracker", + "Tags": [ + "upgrade_downgrade_query_serving_schema" + ], + "Needs": [] + }, + "vtgate_schematracker_unsharded": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/schematracker/unsharded" + ], + "Args": [ + "-timeout", + "20m" + ], + "Command": [], + "Manual": false, + "Shard": "vtgate_schema_tracker", + "Tags": [ + "upgrade_downgrade_query_serving_schema" + ], + "Needs": [] + }, + "vtgate_schematracker_viewsdisabled": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/schematracker/viewsdisabled" + ], + "Args": [ + "-timeout", + "20m" + ], + "Command": [], + "Manual": false, + "Shard": "vtgate_schema_tracker", + "Tags": [ + "upgrade_downgrade_query_serving_schema" + ], + "Needs": [] + }, + "vtgate_sequence": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/sequence" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_general_heavy", + "Tags": [], + "Needs": [ + "limit-resources" + ] + }, + "vtgate_setstatement": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/reservedconn" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_reservedconn", + "Tags": [], + "Needs": [] + }, + "vtgate_reserved_conn1": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/reservedconn/reconnect1" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_reservedconn", + "Tags": [], + "Needs": [] + }, + "vtgate_reserved_conn2": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/reservedconn/reconnect2" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_reservedconn", + "Tags": [], + "Needs": [] + }, + "vtgate_reserved_conn3": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/reservedconn/reconnect3" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_reservedconn", + "Tags": [], + "Needs": [] + }, + "vtgate_reserved_conn4": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/reservedconn/reconnect4" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_reservedconn", + "Tags": [], + "Needs": [] + }, + "vtgate_tablet_healthcheck_cache": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/tablet_healthcheck_cache" + ], + "Args": [ + "-timeout", + "45m" + ], + "Command": [], + "Manual": false, + "Shard": "vtgate_tablet_healthcheck_cache", + "Tags": [], + "Needs": [] + }, + "vtgate_transaction": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/transaction" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_transaction", + "Tags": [], + "Needs": [], + "BuildTag": "debug2PC" + }, + "vtgate_transaction_restart": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/transaction/restart" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_transaction", + "Tags": [], + "Needs": [], + "BuildTag": "debug2PC" + }, + "vtgate_transaction_rollback": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/transaction/rollback" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_transaction", + "Tags": [], + "Needs": [], + "BuildTag": "debug2PC" + }, + "vtgate_transaction_single": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/transaction/single" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_transaction", + "Tags": [], + "Needs": [], + "BuildTag": "debug2PC" + }, + "vtgate_transaction_twopc": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/transaction/twopc" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_transaction", + "Tags": [], + "Needs": [], + "BuildTag": "debug2PC" + }, + "vtgate_transaction_twopc_metric": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/transaction/twopc/metric" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_transaction", + "Tags": [], + "Needs": [], + "BuildTag": "debug2PC" + }, + "vtgate_transaction_twopc_stress": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/transaction/twopc/stress" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_transaction", + "Tags": [], + "Needs": [], + "BuildTag": "debug2PC" + }, + "vtgate_transaction_twopc_fuzz": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/transaction/twopc/fuzz" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_transaction", + "Tags": [], + "Needs": [], + "BuildTag": "debug2PC" + }, + "vtgate_transaction_partial_exec": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/partialfailure" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_transaction", + "Tags": [], + "Needs": [], + "BuildTag": "debug2PC" + }, + "vtgate_plantests": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/plan_tests" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_plantests", + "Tags": [], + "Needs": [] + }, + "vtgate_unsharded": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/unsharded" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_unsharded", + "Tags": [], + "Needs": [] + }, + "vtgate_vschema": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/vschema" + ], + "Args": [ + "-timeout", + "20m" + ], + "Command": [], + "Manual": false, + "Shard": "vtgate_vschema", + "Tags": [ + "upgrade_downgrade_query_serving_schema" + ], + "Needs": [] + }, + "vtgate_readafterwrite": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/readafterwrite" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_readafterwrite", + "Tags": [], + "Needs": [] + }, + "vtgate_dbddlplugin": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/createdb_plugin" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_general_heavy", + "Tags": [], + "Needs": [ + "limit-resources" + ] + }, + "vtgate_foreignkey": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/foreignkey" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_foreignkey_stress", + "Tags": [], + "Needs": [] + }, + "vtgate_foreignkey_routing": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/foreignkey/routing" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_foreignkey_stress", + "Tags": [], + "Needs": [] + }, + "vtgate_foreignkey_stress": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/foreignkey/stress" + ], + "Args": [ + "-timeout", + "30m" + ], + "Command": [], + "Manual": false, + "Shard": "vtgate_foreignkey_stress", + "Tags": [], + "Needs": [] + }, + "vtgate_gen4": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/gen4" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_gen4", + "Tags": [], + "Needs": [] + }, + "vtgate_godriver": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/godriver" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_godriver", + "Tags": [], + "Needs": [] + }, + "vtgate_watchkeyspace": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/keyspace_watches" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_topo", + "Tags": [], + "Needs": [] + }, + "vtgate_grpc_api": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/grpc_api" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_general_heavy", + "Tags": [], + "Needs": [ + "limit-resources" + ] + }, + "topo_zk2": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/topotest/zk2" + ], + "Args": [ + "--topo-flavor=zk2" + ], + "Command": [], + "Manual": false, + "Shard": "docker_cluster", + "Tags": [], + "Needs": [] + }, + "topo_consul": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/topotest/consul" + ], + "Args": [ + "--topo-flavor=consul" + ], + "Command": [], + "Manual": false, + "Shard": "vtgate_topo_consul", + "Tags": [], + "Needs": [ + "consul" + ] + }, + "topo_etcd2": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/topotest/etcd2" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_topo_etcd", + "Tags": [], + "Needs": [] + }, + "errs_as_warns": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/errors_as_warnings" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_general_heavy", + "Tags": [], + "Needs": [ + "limit-resources" + ] + }, + "consolidator": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/consolidator" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_general_heavy", + "Tags": [], + "Needs": [ + "limit-resources" + ] + }, + "prefixfanout": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/prefixfanout" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_vindex_heavy", + "Tags": [], + "Needs": [ + "limit-resources" + ] + }, + "vindex_bindvars": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/vindex_bindvars" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_vindex_heavy", + "Tags": [], + "Needs": [ + "limit-resources" + ] + }, + "vindex_secondary": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/sec_vind" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtgate_vindex_heavy", + "Tags": [], + "Needs": [ + "limit-resources" + ] + }, + "vttest_sample": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtcombo" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "docker_cluster", + "Tags": [], + "Needs": [] + }, + "xb_recovery": { + "File": "recovery_test.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/recovery/xtrabackup" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "xb_recovery", + "Tags": [], + "Needs": [ + "xtrabackup" + ] + }, + "vreplication_materialize": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "Materialize" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_partial_movetables_and_materialize", + "Tags": [], + "Needs": [ + "limit-resources", + "binlog-compression" + ] + }, + "vreplication_vtctldclient_materialize": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestMaterializeVtctldClient" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_partial_movetables_and_materialize", + "Tags": [], + "Needs": [ + "limit-resources", + "binlog-compression" + ] + }, + "vreplication_cellalias": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "CellAlias" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_cellalias", + "Tags": [], + "Needs": [ + "limit-resources", + "binlog-compression" + ] + }, + "vreplication_movetables_ignore_source_keyspace": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestMoveTablesIgnoreSourceKeyspace" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_cellalias", + "Tags": [], + "Needs": [ + "limit-resources", + "binlog-compression" + ] + }, + "vreplication_multi_tenant": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "MultiTenant" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_multi_tenant", + "Tags": [], + "Needs": [ + "limit-resources", + "binlog-compression" + ] + }, + "vreplication_partial_movetables_basic": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "PartialMoveTablesBasic" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_partial_movetables_and_materialize", + "Tags": [], + "Needs": [ + "limit-resources", + "binlog-compression" + ] + }, + "vdiff_multiple_movetables_test.go": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestMultipleConcurrentVDiffs" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_partial_movetables_and_materialize", + "Tags": [], + "Needs": [ + "limit-resources", + "binlog-compression" + ] + }, + "vreplication_movetables_buffering": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestMoveTablesBuffering" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_cellalias", + "Tags": [], + "Needs": [ + "limit-resources", + "binlog-compression" + ] + }, + "vreplication_onlineddl_vdiff": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestOnlineDDLVDiff" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_cellalias", + "Tags": [], + "Needs": [ + "limit-resources", + "binlog-compression" + ] + }, + "vreplication_vschema_load": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestVSchemaChangesUnderLoad" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_cellalias", + "Tags": [], + "Needs": [ + "limit-resources", + "binlog-compression" + ] + }, + "sidecardb": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestSidecarDB" + ], + "Command": [], + "Manual": false, + "Shard": "schemadiff_vrepl", + "Tags": [], + "Needs": [ + "binlog-compression" + ] + }, + "vreplication_basic": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestBasicVreplicationWorkflow", + "-timeout", + "20m" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_basic", + "Tags": [], + "Needs": [ + "larger-runner", + "limit-resources", + "binlog-compression" + ] + }, + "vreplication_copy_parallel": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestVreplicationCopyParallel", + "-timeout", + "20m" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_copy_parallel", + "Tags": [], + "Needs": [ + "limit-resources", + "binlog-compression" + ] + }, + "vreplication_partial_movetables_sequences": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestPartialMoveTablesWithSequences" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_partial_movetables_and_materialize", + "Tags": [], + "Needs": [ + "limit-resources", + "binlog-compression" + ] + }, + "vreplication_sequence_reset_on_switch_traffic": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestSequenceResetOnSwitchTraffic" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_partial_movetables_and_materialize", + "Tags": [], + "Needs": [ + "limit-resources", + "binlog-compression" + ] + }, + "vstream_flush_binlog": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestVStreamFlushBinlog" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_basic", + "Tags": [], + "Needs": [ + "larger-runner", + "limit-resources", + "binlog-compression" + ] + }, + "multi_vstreams_keyspace_reshard": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestMultiVStreamsKeyspaceReshard", + "-timeout", + "15m" + ], + "Command": [], + "Manual": false, + "Shard": "vstream", + "Tags": [], + "Needs": [] + }, + "vstream_failover": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "VStreamFailover" + ], + "Command": [], + "Manual": false, + "Shard": "vstream", + "Tags": [], + "Needs": [] + }, + "vstream_stoponreshard_true": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "VStreamStopOnReshardTrue" + ], + "Command": [], + "Manual": false, + "Shard": "vstream", + "Tags": [], + "Needs": [] + }, + "vstream_stoponreshard_false": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "VStreamStopOnReshardFalse" + ], + "Command": [], + "Manual": false, + "Shard": "vstream", + "Tags": [], + "Needs": [] + }, + "vstream_with_keyspaces_to_watch": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "VStreamWithKeyspacesToWatch" + ], + "Command": [], + "Manual": false, + "Shard": "vstream", + "Tags": [], + "Needs": [] + }, + "vtop_example": { + "File": "", + "Packages": [], + "Args": [], + "Command": [ + "test/vtop_example.sh" + ], + "Manual": false, + "Shard": "", + "Tags": [], + "Needs": [] + }, + "vtorc_primary_failure": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtorc/primaryfailure" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtorc", + "Tags": [], + "Needs": [ + "memory-check" + ] + }, + "vtorc_api": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtorc/api" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtorc", + "Tags": [], + "Needs": [ + "memory-check" + ] + }, + "vtorc_general": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtorc/general" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtorc", + "Tags": [], + "Needs": [ + "memory-check" + ] + }, + "vtorc_readtopologyinstance": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtorc/readtopologyinstance" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vtorc", + "Tags": [], + "Needs": [ + "memory-check" + ] + }, + "vault": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vault" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "mysql_server_vault", + "Tags": [], + "Needs": [ + "consul" + ] + }, + "vreplication_v2": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestBasicV2Workflows", + "-timeout", + "30m" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_v2", + "Tags": [], + "Needs": [ + "limit-resources", + "binlog-compression" + ] + }, + "global_routing": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestGlobalRouting", + "-timeout", + "30m" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_v2", + "Tags": [], + "Needs": [ + "limit-resources", + "binlog-compression" + ] + }, + "vreplication_fk": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestFKWorkflow" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_cellalias", + "Tags": [], + "Needs": [ + "limit-resources", + "binlog-compression" + ] + }, + "vreplication_foreign_key_stress": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestFKExt" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_foreign_key_stress", + "Tags": [], + "Needs": [ + "limit-resources", + "binlog-compression" + ] + }, + "vreplication_across_db_versions": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestV2WorkflowsAcrossDBVersions", + "-timeout", + "20m" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_across_db_versions", + "Tags": [], + "Needs": [ + "limit-resources", + "binlog-compression" + ] + }, + "vreplication_mariadb_to_mysql": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestMoveTablesMariaDBToMySQL", + "-timeout", + "20m" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_mariadb_to_mysql", + "Tags": [], + "Needs": [ + "limit-resources", + "binlog-compression" + ] + }, + "vreplication_migrate": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestMigrate", + "-timeout", + "30m" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_migrate", + "Tags": [], + "Needs": [ + "larger-runner", + "limit-resources", + "binlog-compression" + ] + }, + "vdiff2": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestVDiff2", + "-timeout", + "30m" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_vdiff2", + "Tags": [], + "Needs": [ + "limit-resources", + "binlog-compression" + ] + }, + "vreplication_vtctldclient_cli": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestVtctldclientCLI", + "-timeout", + "20m" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_vtctldclient_movetables_tz", + "Tags": [], + "Needs": [ + "limit-resources", + "binlog-compression" + ] + }, + "vreplication_movetables_tz": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestMoveTablesTZ" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_vtctldclient_movetables_tz", + "Tags": [], + "Needs": [ + "limit-resources", + "binlog-compression" + ] + }, + "loopkup_index": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vreplication" + ], + "Args": [ + "-run", + "TestLookupIndex" + ], + "Command": [], + "Manual": false, + "Shard": "vreplication_vtctldclient_movetables_tz", + "Tags": [], + "Needs": [ + "limit-resources", + "binlog-compression" + ] + }, + "vtadmin": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtadmin" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "15", + "Tags": [], + "Needs": [] + }, + "topo_connection_cache": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/topoconncache" + ], + "Args": [ + "-run", + "TestVtctldListAllTablets" + ], + "Command": [], + "Manual": false, + "Shard": "topo_connection_cache", + "Tags": [], + "Needs": [] + }, + "prscomplex": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/reparent/prscomplex" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vttablet_prscomplex", + "Tags": [ + "" + ], + "Needs": [] + }, + "prssettingspool": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/reparent/prssettingspool" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "vttablet_prscomplex", + "Tags": [ + "" + ], + "Needs": [] + }, + "vtgate_mysql80": { + "File": "unused.go", + "Packages": [ + "vitess.io/vitess/go/test/endtoend/vtgate/schematracker/multi_ks" + ], + "Args": [], + "Command": [], + "Manual": false, + "Shard": "mysql80", + "RetryMax": 1, + "Tags": [], + "Needs": [] + } + } } diff --git a/test/templates/cluster_endtoend_test.tpl b/test/templates/cluster_endtoend_test.tpl deleted file mode 100644 index 0a46fbe90de..00000000000 --- a/test/templates/cluster_endtoend_test.tpl +++ /dev/null @@ -1,231 +0,0 @@ -name: {{.Name}} -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{"{{"}} github.ref {{"}}"}}, '{{.Name}}') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{`{{ github.event.pull_request.head.sha }}`}}" -{{if .GoPrivate}} GOPRIVATE: "{{.GoPrivate}}"{{end}} - -jobs: - build: - timeout-minutes: 60 - name: Run endtoend tests on {{.Name}} - runs-on: {{.RunsOn}} - - steps: - - name: Skip CI - run: | - if [[ "{{"${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}"}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - {{if .MemoryCheck}} - - - name: Check Memory - run: | - totalMem=$(free -g | awk 'NR==2 {print $2}') - echo "total memory $totalMem GB" - if [[ "$totalMem" -lt 15 ]]; then - echo "Less memory than required" - exit 1 - fi - - {{end}} - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/{{.FileName}}' - {{- if or (contains .Name "onlineddl") (contains .Name "schemadiff") }} - - 'go/test/endtoend/onlineddl/vrepl_suite/testdata' - {{- end}} - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - -{{if .GoPrivate}} - - name: Setup GitHub access token - if: steps.changes.outputs.end_to_end == 'true' - run: git config --global url.https://${{`{{ secrets.GH_ACCESS_TOKEN }}`}}@github.com/.insteadOf https://github.com/ -{{end}} - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - {{if not .InstallXtraBackup}} - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - {{ end }} - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 10 - run: | - {{if .InstallXtraBackup}} - - # Setup Percona Server for MySQL 8.0 - sudo apt-get -qq update - sudo apt-get -qq install -y lsb-release gnupg2 - wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb - sudo DEBIAN_FRONTEND="noninteractive" dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb - sudo percona-release setup pdps8.0 - sudo apt-get -qq update - - sudo apt-get -qq install -y percona-server-server percona-server-client - - sudo service mysql stop - - sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ - sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld - - sudo apt-get -qq install -y percona-xtrabackup-80 lz4 - - {{else}} - - sudo apt-get -qq install -y mysql-shell - - {{end}} - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - - {{if .NeedsMinio }} - - name: Install Minio - run: | - wget https://dl.min.io/server/minio/release/linux-amd64/minio - chmod +x minio - mv minio /usr/local/bin - {{end}} - - {{if .MakeTools}} - - - name: Installing zookeeper and consul - if: steps.changes.outputs.end_to_end == 'true' - run: | - make tools - - {{end}} - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - {{if .LimitResourceUsage}} - # Increase our open file descriptor limit as we could hit this - ulimit -n 65536 - cat <<-EOF>>./config/mycnf/mysql8026.cnf - innodb_buffer_pool_dump_at_shutdown=OFF - innodb_buffer_pool_in_core_file=OFF - innodb_buffer_pool_load_at_startup=OFF - innodb_buffer_pool_size=64M - innodb_doublewrite=OFF - innodb_flush_log_at_trx_commit=0 - innodb_flush_method=O_DIRECT - innodb_numa_interleave=ON - innodb_adaptive_hash_index=OFF - sync_binlog=0 - sync_relay_log=0 - performance_schema=OFF - slow-query-log=OFF - EOF - {{end}} - - {{if .EnableBinlogTransactionCompression}} - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-transaction-compression=ON - EOF - {{end}} - - {{if .EnablePartialJSON}} - cat <<-EOF>>./config/mycnf/mysql8026.cnf - binlog-row-value-options=PARTIAL_JSON - EOF - {{end}} - - # Some of these tests require specific locales to be installed. - # See https://github.com/cncf/automation/commit/49f2ad7a791a62ff7d038002bbb2b1f074eed5d5 - go run test.go -docker={{if .Docker}}true -flavor={{.Platform}}{{else}}false{{end}} -follow -shard {{.Shard}}{{if .PartialKeyspace}} -partial-keyspace=true {{end}}{{if .BuildTag}} -build-tag={{.BuildTag}} {{end}} - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/test/templates/cluster_endtoend_test_docker.tpl b/test/templates/cluster_endtoend_test_docker.tpl deleted file mode 100644 index 94f2e7cd2c5..00000000000 --- a/test/templates/cluster_endtoend_test_docker.tpl +++ /dev/null @@ -1,88 +0,0 @@ -name: {{.Name}} -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' - -permissions: read-all - -env: -{{if .GoPrivate}} GOPRIVATE: "{{.GoPrivate}}"{{end}} - -jobs: - build: - name: Run endtoend tests on {{.Name}} - runs-on: {{.RunsOn}} - - steps: - - name: Skip CI - run: | - if [[ "{{"${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}"}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/{{.FileName}}' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - -{{if .GoPrivate}} - - name: Setup GitHub access token - if: steps.changes.outputs.end_to_end == 'true' - run: git config --global url.https://${{`{{ secrets.GH_ACCESS_TOKEN }}`}}@github.com/.insteadOf https://github.com/ -{{end}} - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - run: | - sudo sysctl -w net.ipv4.ip_local_port_range="22768 65535" - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 30 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - - go run test.go -docker=true --follow -shard {{.Shard}} - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "_test/junit/*.xml" - show: "fail" diff --git a/test/templates/cluster_endtoend_test_mysql57.tpl b/test/templates/cluster_endtoend_test_mysql57.tpl deleted file mode 100644 index 13a32866b3d..00000000000 --- a/test/templates/cluster_endtoend_test_mysql57.tpl +++ /dev/null @@ -1,211 +0,0 @@ -name: {{.Name}} -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{"{{"}} github.ref {{"}}"}}, '{{.Name}}') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{`{{ github.event.pull_request.head.sha }}`}}" -{{if .GoPrivate}} GOPRIVATE: "{{.GoPrivate}}"{{end}} -{{if .InstallXtraBackup}} - # This is used if we need to pin the xtrabackup version used in tests. - # If this is NOT set then the latest version available will be used. - #XTRABACKUP_VERSION: "2.4.24-1" -{{end}} - -jobs: - build: - name: Run endtoend tests on {{.Name}} - runs-on: {{.RunsOn}} - - steps: - - name: Skip CI - run: | - if [[ "{{"${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}"}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - {{if .MemoryCheck}} - - - name: Check Memory - run: | - totalMem=$(free -g | awk 'NR==2 {print $2}') - echo "total memory $totalMem GB" - if [[ "$totalMem" -lt 15 ]]; then - echo "Less memory than required" - exit 1 - fi - - {{end}} - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/onlineddl/vrepl_suite/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/{{.FileName}}' - {{- if or (contains .Name "onlineddl") (contains .Name "schemadiff") }} - - 'go/test/endtoend/onlineddl/vrepl_suite/testdata' - {{- end}} - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - -{{if .GoPrivate}} - - name: Setup GitHub access token - if: steps.changes.outputs.end_to_end == 'true' - run: git config --global url.https://${{`{{ secrets.GH_ACCESS_TOKEN }}`}}@github.com/.insteadOf https://github.com/ -{{end}} - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-5.7 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - run: | - sudo apt-get update - - sudo apt-get install -y make unzip g++ etcd-client etcd-server curl git wget - - sudo service etcd stop - - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - {{if .InstallXtraBackup}} - - wget "https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb" - sudo apt-get install -y gnupg2 - sudo dpkg -i "percona-release_latest.$(lsb_release -sc)_all.deb" - sudo percona-release enable-only tools - sudo apt-get update - if [[ -n $XTRABACKUP_VERSION ]]; then - debfile="percona-xtrabackup-24_$XTRABACKUP_VERSION.$(lsb_release -sc)_amd64.deb" - wget "https://repo.percona.com/pxb-24/apt/pool/main/p/percona-xtrabackup-24/$debfile" - sudo apt install -y "./$debfile" - else - sudo apt-get install -y percona-xtrabackup-24 - fi - - {{end}} - - {{if .MakeTools}} - - - name: Installing zookeeper and consul - if: steps.changes.outputs.end_to_end == 'true' - run: | - make tools - - {{end}} - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - - set -exo pipefail - - {{if .LimitResourceUsage}} - # Increase our local ephemeral port range as we could exhaust this - sudo sysctl -w net.ipv4.ip_local_port_range="22768 61999" - # Increase our open file descriptor limit as we could hit this - ulimit -n 65536 - cat <<-EOF>>./config/mycnf/mysql57.cnf - innodb_buffer_pool_dump_at_shutdown=OFF - innodb_buffer_pool_load_at_startup=OFF - innodb_buffer_pool_size=64M - innodb_doublewrite=OFF - innodb_flush_log_at_trx_commit=0 - innodb_flush_method=O_DIRECT - innodb_numa_interleave=ON - innodb_adaptive_hash_index=OFF - sync_binlog=0 - sync_relay_log=0 - performance_schema=OFF - slow-query-log=OFF - EOF - {{end}} - - # run the tests however you normally do, then produce a JUnit XML file - go run test.go -docker={{if .Docker}}true -flavor={{.Platform}}{{else}}false{{end}} -follow -shard {{.Shard}}{{if .PartialKeyspace}} -partial-keyspace=true {{end}} | tee -a output.txt | go-junit-report -set-exit-code > report.xml - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat output.txt - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "report.xml" - show: "fail" diff --git a/test/templates/cluster_vitess_tester.tpl b/test/templates/cluster_vitess_tester.tpl deleted file mode 100644 index e0f645bec13..00000000000 --- a/test/templates/cluster_vitess_tester.tpl +++ /dev/null @@ -1,162 +0,0 @@ -name: {{.Name}} -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{"{{"}} github.ref {{"}}"}}, '{{.Name}}') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{`{{ github.event.pull_request.head.sha }}`}}" -{{if .GoPrivate}} GOPRIVATE: "{{.GoPrivate}}"{{end}} - -jobs: - build: - name: Run endtoend tests on {{.Name}} - runs-on: {{.RunsOn}} - - steps: - - name: Skip CI - run: | - if [[ "{{"${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}"}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'go/vt/sidecardb/**/*.sql' - - 'go/test/endtoend/vtgate/vitess_tester/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/{{.FileName}}' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - -{{if .GoPrivate}} - - name: Setup GitHub access token - if: steps.changes.outputs.end_to_end == 'true' - run: git config --global url.https://${{`{{ secrets.GH_ACCESS_TOKEN }}`}}@github.com/.insteadOf https://github.com/ -{{end}} - - - name: Set up python - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/setup-mysql - with: - flavor: mysql-8.0 - - - name: Get dependencies - if: steps.changes.outputs.end_to_end == 'true' - run: | - sudo apt-get -qq update - - # Install everything else we need, and configure - sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 - - sudo service etcd stop - - go mod download - - # install JUnit report formatter - go install github.com/vitessio/go-junit-report@HEAD - - # install vitess tester - go install github.com/vitessio/vt/go/vt@e43009309f599378504905d4b804460f47822ac5 - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run cluster endtoend test - if: steps.changes.outputs.end_to_end == 'true' - timeout-minutes: 45 - run: | - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - source build.env - export NOVTADMINBUILD=1 - make build - - set -exo pipefail - - i=1 - for dir in {{.Path}}/*/; do - # We go over all the directories in the given path. - # If there is a vschema file there, we use it, otherwise we let vt tester autogenerate it. - if [ -f $dir/vschema.json ]; then - vt tester --xunit --vschema "$dir"vschema.json $dir/*.test - else - vt tester --sharded --xunit $dir/*.test - fi - # Number the reports by changing their file names. - mv report.xml report"$i".xml - i=$((i+1)) - done - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Print test output - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - run: | - # print test output - cat report*.xml - - - name: Test Summary - if: steps.changes.outputs.end_to_end == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "report*.xml" - show: "fail" diff --git a/test/templates/dockerfile.tpl b/test/templates/dockerfile.tpl deleted file mode 100644 index 53174e391ea..00000000000 --- a/test/templates/dockerfile.tpl +++ /dev/null @@ -1,48 +0,0 @@ -ARG bootstrap_version=43.6 -ARG image="vitess/bootstrap:${bootstrap_version}-{{.Platform}}" - -FROM "${image}" - -USER root - -# Re-copy sources from working tree -RUN rm -rf /vt/src/vitess.io/vitess/* -COPY . /vt/src/vitess.io/vitess - -{{if .InstallXtraBackup}} -# install XtraBackup -RUN wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb -RUN apt-get update -RUN apt-get install -y gnupg2 -RUN dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb -RUN percona-release enable-only tools -RUN apt-get update -RUN apt-get install -y percona-xtrabackup-24 -{{end}} - -# Set the working directory -WORKDIR /vt/src/vitess.io/vitess - -# Fix permissions -RUN chown -R vitess:vitess /vt - -USER vitess - -# Set environment variables -ENV VTROOT /vt/src/vitess.io/vitess -# Set the vtdataroot such that it uses the volume mount -ENV VTDATAROOT /vt/vtdataroot - -# create the vtdataroot directory -RUN mkdir -p $VTDATAROOT - -# install goimports -RUN go install golang.org/x/tools/cmd/goimports@latest - -{{if .MakeTools}} -# make tools -RUN make tools -{{end}} - -# sleep for 50 minutes -CMD sleep 3000 diff --git a/test/templates/unit_test.tpl b/test/templates/unit_test.tpl deleted file mode 100644 index a2097ac3c3d..00000000000 --- a/test/templates/unit_test.tpl +++ /dev/null @@ -1,160 +0,0 @@ -name: {{.Name}} -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -concurrency: - group: format('{0}-{1}', ${{"{{"}} github.ref {{"}}"}}, '{{.Name}}') - cancel-in-progress: true - -permissions: read-all - -env: - LAUNCHABLE_ORGANIZATION: "vitess" - LAUNCHABLE_WORKSPACE: "vitess-app" - GITHUB_PR_HEAD_SHA: "${{`{{ github.event.pull_request.head.sha }}`}}" -{{if .GoPrivate}} GOPRIVATE: "{{.GoPrivate}}"{{end}} - -jobs: - test: - name: {{.Name}} - runs-on: {{.RunsOn}} - - steps: - - name: Skip CI - run: | - if [[ "{{"${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}"}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - unit_tests: - - 'test/config.json' - - 'go/**' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - '.github/workflows/{{.FileName}}' - - - name: Set up Go - if: steps.changes.outputs.unit_tests == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - -{{if .GoPrivate}} - - name: Setup GitHub access token - if: steps.changes.outputs.unit_tests == 'true' - run: git config --global url.https://${{`{{ secrets.GH_ACCESS_TOKEN }}`}}@github.com/.insteadOf https://github.com/ -{{end}} - - - name: Set up python - if: steps.changes.outputs.unit_tests == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 - - - name: Tune the OS - if: steps.changes.outputs.unit_tests == 'true' - uses: ./.github/actions/tune-os - - - name: Setup MySQL - if: steps.changes.outputs.unit_tests == 'true' - uses: ./.github/actions/setup-mysql - with: - {{ if (eq .Platform "mysql57") -}} - flavor: mysql-5.7 - {{ end }} - {{- if (eq .Platform "mysql80") -}} - flavor: mysql-8.0 - {{ end }} - {{- if (eq .Platform "mysql84") -}} - flavor: mysql-8.4 - {{ end }} - - - name: Get dependencies - if: steps.changes.outputs.unit_tests == 'true' - run: | - export DEBIAN_FRONTEND="noninteractive" - sudo apt-get install -y make unzip g++ curl git wget ant openjdk-11-jdk - - mkdir -p dist bin - curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist - mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/ - - go mod download - go install golang.org/x/tools/cmd/goimports@latest - - - name: Run make tools - if: steps.changes.outputs.unit_tests == 'true' - run: | - make tools - - - name: Setup launchable dependencies - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' - run: | - # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up - pip3 install --user launchable~=1.0 > /dev/null - - # verify that launchable setup is all correct. - launchable verify || true - - # Tell Launchable about the build you are producing and testing - launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source . - - - name: Run test - if: steps.changes.outputs.unit_tests == 'true' - timeout-minutes: {{if .Race}}45{{else}}30{{end}} - run: | - set -exo pipefail - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. - export VTDATAROOT="/tmp/" - - export NOVTADMINBUILD=1 - export VTEVALENGINETEST="{{.Evalengine}}" - # We sometimes need to alter the behavior based on the platform we're - # testing, e.g. MySQL 5.7 vs 8.0. - export CI_DB_PLATFORM="{{.Platform}}" - - JUNIT_OUTPUT=report.xml JSON_OUTPUT=report.json make {{if .Race}}unit_test_race{{else}}unit_test{{end}} - - - name: Record test results in launchable if PR is not a draft - if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' && !cancelled() - run: | - # send recorded tests to launchable - launchable record tests --build "$GITHUB_RUN_ID" go-test . || true - - - name: Test Summary - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4 - with: - paths: "report.xml" - show: "fail" - - - name: Slowest Tests - if: steps.changes.outputs.unit_tests == 'true' && !cancelled() - run: | - echo '## Slowest Tests' >> "$GITHUB_STEP_SUMMARY" - echo '```' >> "$GITHUB_STEP_SUMMARY" - go tool gotestsum tool slowest --num 20 --jsonfile report.json | tee -a "$GITHUB_STEP_SUMMARY" - echo '```' >> "$GITHUB_STEP_SUMMARY" From 4c6d4ea3f8749f7c8991000c8c6915a5c92989b3 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Thu, 5 Feb 2026 13:15:10 -0500 Subject: [PATCH 048/112] [release-22.0] Fix go upgrade tool (#19290) (#19298) Signed-off-by: Mohamed Hamza Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- go/tools/go-upgrade/go-upgrade.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/go/tools/go-upgrade/go-upgrade.go b/go/tools/go-upgrade/go-upgrade.go index b1376e5e2be..ce2c984912c 100644 --- a/go/tools/go-upgrade/go-upgrade.go +++ b/go/tools/go-upgrade/go-upgrade.go @@ -359,7 +359,6 @@ func replaceGoVersionInCodebase(old, new *version.Version) error { return nil } explore := []string{ - "./test/templates", "./build.env", "./docker/bootstrap/Dockerfile.common", "./docker/lite/Dockerfile", @@ -438,7 +437,6 @@ func updateBootstrapVersionInCodebase(old, new string, newGoVersion *version.Ver } files, err := getListOfFilesInPaths([]string{ "./Makefile", - "./test/templates", }) if err != nil { return err From 24742c9e482ff88b1fcfc00c2ea920327784a12b Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Thu, 5 Feb 2026 18:29:28 +0000 Subject: [PATCH 049/112] [release-22.0] Switch gotestsum output format (#19215) (#19302) Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- tools/unit_test_runner.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/unit_test_runner.sh b/tools/unit_test_runner.sh index f9dadc74ddc..7edb4d22ac7 100755 --- a/tools/unit_test_runner.sh +++ b/tools/unit_test_runner.sh @@ -66,7 +66,7 @@ fi # Build gotestsum args. Failed tests are retried up to 3 times, but if more than 10 tests fail # initially we skip retries to avoid wasting time on a real widespread failure. -GOTESTSUM_ARGS="--format github-actions --rerun-fails=3 --rerun-fails-max-failures=10 --rerun-fails-run-root-test --format-hide-empty-pkg --hide-summary=skipped" +GOTESTSUM_ARGS="--format pkgname-and-test-fails --rerun-fails=3 --rerun-fails-max-failures=10 --rerun-fails-run-root-test --format-hide-empty-pkg --hide-summary=skipped" if [[ -n "${JUNIT_OUTPUT:-}" ]]; then GOTESTSUM_ARGS="$GOTESTSUM_ARGS --junitfile $JUNIT_OUTPUT" fi From 41c68e296bbb7394caaf0594801042519a7e4e2c Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Thu, 5 Feb 2026 18:56:11 +0000 Subject: [PATCH 050/112] [release-22.0] Build bootstrap image locally in ci (#19255) (#19265) Signed-off-by: Mohamed Hamza Co-authored-by: Mohamed Hamza --- .github/workflows/docker_ci.yml | 100 ++++++++++++++++++++++ .github/workflows/docker_test_cluster.yml | 64 -------------- .github/workflows/java_docker_test.yml | 65 -------------- docker/bootstrap/docker-bake.hcl | 44 ++++++++++ 4 files changed, 144 insertions(+), 129 deletions(-) create mode 100644 .github/workflows/docker_ci.yml delete mode 100644 .github/workflows/docker_test_cluster.yml delete mode 100644 .github/workflows/java_docker_test.yml create mode 100644 docker/bootstrap/docker-bake.hcl diff --git a/.github/workflows/docker_ci.yml b/.github/workflows/docker_ci.yml new file mode 100644 index 00000000000..cb7ca10bb38 --- /dev/null +++ b/.github/workflows/docker_ci.yml @@ -0,0 +1,100 @@ +name: docker_ci +on: + push: + branches: + - "main" + - "release-[0-9]+.[0-9]" + tags: "**" + pull_request: + branches: "**" +permissions: read-all + +env: + BOOTSTRAP_VERSION: "ci" + BOOTSTRAP_FLAVOR: "mysql84" + +jobs: + build: + name: ${{ matrix.name }} + runs-on: ubuntu-24.04 + + strategy: + fail-fast: false + matrix: + include: + - shard: java + name: Java Docker Test + - shard: docker_cluster + name: Docker Test Cluster + + steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 + with: + egress-policy: audit + + - name: Skip CI + run: | + if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then + echo "skipping CI due to the 'Skip CI' label" + exit 1 + fi + + - name: Check out code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: "false" + + - name: Check for changes in relevant files + uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 + id: changes + with: + token: "" + filters: | + end_to_end: + - 'test/config.json' + - 'go/**/*.go' + - 'test.go' + - 'Makefile' + - 'build.env' + - 'go.sum' + - 'go.mod' + - 'proto/*.proto' + - 'tools/**' + - 'config/**' + - 'bootstrap.sh' + - 'docker/**' + - 'java/**' + - '.github/workflows/docker_ci.yml' + + - name: Set up Docker Buildx + if: steps.changes.outputs.end_to_end == 'true' + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Build bootstrap images + if: steps.changes.outputs.end_to_end == 'true' + uses: docker/bake-action@4ba453fbc2db7735392b93edf935aaf9b1e8f747 # v6.5.0 + with: + files: docker/bootstrap/docker-bake.hcl + load: true + set: | + *.cache-from=type=gha + *.cache-to=type=gha,mode=max + env: + BOOTSTRAP_VERSION: ${{ env.BOOTSTRAP_VERSION }} + BOOTSTRAP_FLAVOR: ${{ env.BOOTSTRAP_FLAVOR }} + + - name: Set up Go + if: steps.changes.outputs.end_to_end == 'true' + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 + with: + go-version-file: go.mod + + - name: Tune the OS + if: steps.changes.outputs.end_to_end == 'true' + uses: ./.github/actions/tune-os + + - name: Run docker tests - ${{ matrix.shard }} + if: steps.changes.outputs.end_to_end == 'true' + run: | + go run test.go -docker=true -pull=false -flavor=${{ env.BOOTSTRAP_FLAVOR }} -bootstrap-version=${{ env.BOOTSTRAP_VERSION }} --follow -shard ${{ matrix.shard }} diff --git a/.github/workflows/docker_test_cluster.yml b/.github/workflows/docker_test_cluster.yml deleted file mode 100644 index 40fab087f8a..00000000000 --- a/.github/workflows/docker_test_cluster.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: docker_test_cluster -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -permissions: read-all -jobs: - - build: - name: Docker Test Cluster - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - 'docker/**' - - '.github/workflows/docker_test_cluster.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Run tests which require docker - 2 - if: steps.changes.outputs.end_to_end == 'true' - run: | - go run test.go -docker=true --follow -shard docker_cluster diff --git a/.github/workflows/java_docker_test.yml b/.github/workflows/java_docker_test.yml deleted file mode 100644 index 65e8253fd08..00000000000 --- a/.github/workflows/java_docker_test.yml +++ /dev/null @@ -1,65 +0,0 @@ -name: java_docker_test -on: - push: - branches: - - "main" - - "release-[0-9]+.[0-9]" - tags: '**' - pull_request: - branches: '**' -permissions: read-all -jobs: - - build: - name: Java Docker Test - runs-on: ubuntu-24.04 - - steps: - - name: Skip CI - run: | - if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then - echo "skipping CI due to the 'Skip CI' label" - exit 1 - fi - - - name: Check out code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - persist-credentials: 'false' - - - name: Check for changes in relevant files - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 - id: changes - with: - token: '' - filters: | - end_to_end: - - 'test/config.json' - - 'go/**/*.go' - - 'test.go' - - 'Makefile' - - 'build.env' - - 'go.sum' - - 'go.mod' - - 'proto/*.proto' - - 'tools/**' - - 'config/**' - - 'bootstrap.sh' - - 'docker/**' - - 'java/**' - - '.github/workflows/java_docker_test.yml' - - - name: Set up Go - if: steps.changes.outputs.end_to_end == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 - with: - go-version-file: go.mod - - - name: Tune the OS - if: steps.changes.outputs.end_to_end == 'true' - uses: ./.github/actions/tune-os - - - name: Run tests which require docker - 1 - if: steps.changes.outputs.end_to_end == 'true' - run: | - go run test.go -docker=true --follow -shard java diff --git a/docker/bootstrap/docker-bake.hcl b/docker/bootstrap/docker-bake.hcl new file mode 100644 index 00000000000..c9b82c7187b --- /dev/null +++ b/docker/bootstrap/docker-bake.hcl @@ -0,0 +1,44 @@ +// docker-bake.hcl defines the build targets for the Vitess bootstrap images. +// +// The bootstrap images provide a pre-configured environment for running +// Vitess tests in Docker. The common image contains shared dependencies, +// while flavor-specific images (e.g., mysql80) add database-specific packages. +// +// Usage: +// docker buildx bake -f docker/bootstrap/docker-bake.hcl +// +// Variables can be overridden: +// docker buildx bake -f docker/bootstrap/docker-bake.hcl --set *.tags=myregistry/bootstrap:mytag + +variable "BOOTSTRAP_VERSION" { + default = "ci" +} + +variable "BOOTSTRAP_FLAVOR" { + default = "mysql84" +} + +group "default" { + targets = ["common", "flavor"] +} + +target "common" { + context = "." + dockerfile = "docker/bootstrap/Dockerfile.common" + tags = ["vitess/bootstrap:${BOOTSTRAP_VERSION}-common"] +} + +target "flavor" { + context = "." + dockerfile = "docker/bootstrap/Dockerfile.${BOOTSTRAP_FLAVOR}" + tags = ["vitess/bootstrap:${BOOTSTRAP_VERSION}-${BOOTSTRAP_FLAVOR}"] + + contexts = { + "vitess/bootstrap:${BOOTSTRAP_VERSION}-common" = "target:common" + } + + args = { + bootstrap_version = BOOTSTRAP_VERSION + image = "vitess/bootstrap:${BOOTSTRAP_VERSION}-common" + } +} From 25fef4d1e9ba0e015768ac9f941a726a0a736281 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Thu, 5 Feb 2026 23:21:07 +0000 Subject: [PATCH 051/112] [release-22.0] Build boostrap image for local/region example CI (#19310) (#19316) Signed-off-by: Mohamed Hamza Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Mohamed Hamza --- .github/actions/build-bootstrap/action.yml | 30 ++++++++++++++++++++++ .github/workflows/docker_ci.yml | 16 +++--------- .github/workflows/local_example.yml | 4 +++ .github/workflows/region_example.yml | 4 +++ 4 files changed, 41 insertions(+), 13 deletions(-) create mode 100644 .github/actions/build-bootstrap/action.yml diff --git a/.github/actions/build-bootstrap/action.yml b/.github/actions/build-bootstrap/action.yml new file mode 100644 index 00000000000..365a379afd6 --- /dev/null +++ b/.github/actions/build-bootstrap/action.yml @@ -0,0 +1,30 @@ +name: "Build Bootstrap Images" +description: "Build Vitess bootstrap Docker images locally using docker buildx bake" + +inputs: + bootstrap-version: + description: "Bootstrap image version tag" + required: false + default: "ci" + bootstrap-flavor: + description: "Bootstrap image flavor (e.g. mysql84)" + required: false + default: "mysql84" + +runs: + using: "composite" + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 + + - name: Build bootstrap images + uses: docker/bake-action@5be5f02ff8819ecd3092ea6b2e6261c31774f2b4 # v6.10.0 + with: + files: docker/bootstrap/docker-bake.hcl + load: true + set: | + *.cache-from=type=gha + *.cache-to=type=gha,mode=max + env: + BOOTSTRAP_VERSION: ${{ inputs.bootstrap-version }} + BOOTSTRAP_FLAVOR: ${{ inputs.bootstrap-flavor }} diff --git a/.github/workflows/docker_ci.yml b/.github/workflows/docker_ci.yml index cb7ca10bb38..a901660a02f 100644 --- a/.github/workflows/docker_ci.yml +++ b/.github/workflows/docker_ci.yml @@ -67,22 +67,12 @@ jobs: - 'java/**' - '.github/workflows/docker_ci.yml' - - name: Set up Docker Buildx - if: steps.changes.outputs.end_to_end == 'true' - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - - name: Build bootstrap images if: steps.changes.outputs.end_to_end == 'true' - uses: docker/bake-action@4ba453fbc2db7735392b93edf935aaf9b1e8f747 # v6.5.0 + uses: ./.github/actions/build-bootstrap with: - files: docker/bootstrap/docker-bake.hcl - load: true - set: | - *.cache-from=type=gha - *.cache-to=type=gha,mode=max - env: - BOOTSTRAP_VERSION: ${{ env.BOOTSTRAP_VERSION }} - BOOTSTRAP_FLAVOR: ${{ env.BOOTSTRAP_FLAVOR }} + bootstrap-version: ${{ env.BOOTSTRAP_VERSION }} + bootstrap-flavor: ${{ env.BOOTSTRAP_FLAVOR }} - name: Set up Go if: steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/local_example.yml b/.github/workflows/local_example.yml index dbd3c9e9cea..b00d674de27 100644 --- a/.github/workflows/local_example.yml +++ b/.github/workflows/local_example.yml @@ -51,6 +51,10 @@ jobs: - 'examples/**' - '.github/workflows/local_example.yml' + - name: Build bootstrap images + if: steps.changes.outputs.examples == 'true' + uses: ./.github/actions/build-bootstrap + - name: Set up Go if: steps.changes.outputs.examples == 'true' uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 diff --git a/.github/workflows/region_example.yml b/.github/workflows/region_example.yml index f36111edd4c..57281f9b8a3 100644 --- a/.github/workflows/region_example.yml +++ b/.github/workflows/region_example.yml @@ -51,6 +51,10 @@ jobs: - 'examples/**' - '.github/workflows/region_example.yml' + - name: Build bootstrap images + if: steps.changes.outputs.examples == 'true' + uses: ./.github/actions/build-bootstrap + - name: Set up Go if: steps.changes.outputs.examples == 'true' uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 From 1fc47996778998114ec292298cafd26152cc2fcf Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 16:46:16 +0000 Subject: [PATCH 052/112] [release-22.0] Don't add "Skip CI" label for Go upgrade PRs (#19307) (#19322) Signed-off-by: Mohamed Hamza Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Mohamed Hamza --- .github/workflows/update_golang_version.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/update_golang_version.yml b/.github/workflows/update_golang_version.yml index 3fb20b3f87b..4a186fce1ba 100644 --- a/.github/workflows/update_golang_version.yml +++ b/.github/workflows/update_golang_version.yml @@ -80,15 +80,10 @@ jobs: This Pull Request bumps the Golang version to `go${{steps.detect-and-update.outputs.go-version}}` and the bootstrap version to `${{steps.detect-and-update.outputs.bootstrap-version}}`. > Do not trust the bot blindly. A thorough code review must be done to ensure all the files have been correctly modified. - - There are a few manual steps remaining: - - [ ] Make sure you update the Golang version used in the previous and next release branches for the Upgrade/Downgrade tests. - - [ ] Build and Push the bootstrap images to Docker Hub, the bot cannot handle that. cc @vitessio/release base: ${{ matrix.branch }} labels: | - Skip CI go Benchmark me Component: General From 3696abe45c036b84b93a1b2c350748c552d5dd40 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Sun, 8 Feb 2026 00:25:37 +0000 Subject: [PATCH 053/112] [release-22.0] Explicitly pass local image tags in example CI (#19320) (#19325) Signed-off-by: Mohamed Hamza Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Mohamed Hamza --- .github/workflows/local_example.yml | 7 ++++++- .github/workflows/region_example.yml | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/local_example.yml b/.github/workflows/local_example.yml index b00d674de27..87311ffec6a 100644 --- a/.github/workflows/local_example.yml +++ b/.github/workflows/local_example.yml @@ -8,6 +8,11 @@ on: pull_request: branches: '**' permissions: read-all + +env: + BOOTSTRAP_VERSION: "ci" + BOOTSTRAP_FLAVOR: "mysql84" + jobs: build: @@ -88,7 +93,7 @@ jobs: if [ "${{matrix.os}}" = "macos-latest" ]; then export PATH="/usr/local/opt/mysql@5.7/bin:$PATH" fi - go run test.go -print-log -follow local_example + go run test.go -print-log -follow -pull=false -flavor=${{ env.BOOTSTRAP_FLAVOR }} -bootstrap-version=${{ env.BOOTSTRAP_VERSION }} local_example consul: name: Local example using consul on Ubuntu diff --git a/.github/workflows/region_example.yml b/.github/workflows/region_example.yml index 57281f9b8a3..210f917d808 100644 --- a/.github/workflows/region_example.yml +++ b/.github/workflows/region_example.yml @@ -8,6 +8,11 @@ on: pull_request: branches: '**' permissions: read-all + +env: + BOOTSTRAP_VERSION: "ci" + BOOTSTRAP_FLAVOR: "mysql84" + jobs: build: @@ -88,4 +93,4 @@ jobs: if [ "${{matrix.os}}" = "macos-latest" ]; then export PATH="/usr/local/opt/mysql@5.7/bin:$PATH" fi - go run test.go -print-log -follow region_example + go run test.go -print-log -follow -pull=false -flavor=${{ env.BOOTSTRAP_FLAVOR }} -bootstrap-version=${{ env.BOOTSTRAP_VERSION }} region_example From 3a3f2ead2a130e945a6cbafead0faa73ce2b4fe3 Mon Sep 17 00:00:00 2001 From: vitess-go-upgrade-bot <139342327+vitess-bot@users.noreply.github.com> Date: Sat, 7 Feb 2026 22:48:45 -0400 Subject: [PATCH 054/112] [release-22.0] Upgrade the Golang version to `go1.24.13` (#19305) Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: frouioui <35779988+frouioui@users.noreply.github.com> --- Makefile | 2 +- build.env | 2 +- docker/bootstrap/CHANGELOG.md | 6 +++++- docker/bootstrap/Dockerfile.common | 2 +- docker/lite/Dockerfile | 2 +- docker/lite/Dockerfile.mysql84 | 2 +- docker/lite/Dockerfile.percona80 | 2 +- docker/vttestserver/Dockerfile.mysql80 | 2 +- docker/vttestserver/Dockerfile.mysql84 | 2 +- go.mod | 2 +- test.go | 2 +- 11 files changed, 15 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index b2346fc63b0..30779a0ddf4 100644 --- a/Makefile +++ b/Makefile @@ -286,7 +286,7 @@ $(PROTO_GO_OUTS): minimaltools install_protoc-gen-go proto/*.proto # This rule builds the bootstrap images for all flavors. DOCKER_IMAGES_FOR_TEST = mysql80 mysql84 percona80 DOCKER_IMAGES = common $(DOCKER_IMAGES_FOR_TEST) -BOOTSTRAP_VERSION=43.6 +BOOTSTRAP_VERSION=43.7 ensure_bootstrap_version: find docker/ -type f -exec sed -i "s/^\(ARG bootstrap_version\)=.*/\1=${BOOTSTRAP_VERSION}/" {} \; sed -i 's/\(^.*flag.String(\"bootstrap-version\",\) *\"[^\"]\+\"/\1 \"${BOOTSTRAP_VERSION}\"/' test.go diff --git a/build.env b/build.env index 6ae62334ef0..fe66cd0f23e 100755 --- a/build.env +++ b/build.env @@ -17,7 +17,7 @@ source ./tools/shell_functions.inc go version >/dev/null 2>&1 || fail "Go is not installed or is not in \$PATH. See https://vitess.io/contributing/build-from-source for install instructions." -goversion_min 1.24.12 || echo "Go version reported: `go version`. Version 1.24.12+ recommended. See https://vitess.io/contributing/build-from-source for install instructions." +goversion_min 1.24.13 || echo "Go version reported: `go version`. Version 1.24.13+ recommended. See https://vitess.io/contributing/build-from-source for install instructions." mkdir -p dist mkdir -p bin diff --git a/docker/bootstrap/CHANGELOG.md b/docker/bootstrap/CHANGELOG.md index 04630166b29..23a01287f8c 100644 --- a/docker/bootstrap/CHANGELOG.md +++ b/docker/bootstrap/CHANGELOG.md @@ -198,4 +198,8 @@ List of changes between bootstrap image versions. ## [43.6] - 2026-01-27 ### Changes -- Update build to golang 1.24.12 \ No newline at end of file +- Update build to golang 1.24.12 + +## [43.7] - 2026-02-08 +### Changes +- Update build to golang 1.24.13 \ No newline at end of file diff --git a/docker/bootstrap/Dockerfile.common b/docker/bootstrap/Dockerfile.common index 9117c401407..39e734b7892 100644 --- a/docker/bootstrap/Dockerfile.common +++ b/docker/bootstrap/Dockerfile.common @@ -1,4 +1,4 @@ -FROM --platform=linux/amd64 golang:1.24.12-bookworm@sha256:8972893fa12177951b8bd4118470f338eaecea133c323be84066cd64f844fc03 +FROM --platform=linux/amd64 golang:1.24.13-bookworm@sha256:98d673f18a1aac43da744209873cb79323e11706f909251bcfb131828b95559d # Install Vitess build dependencies RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ diff --git a/docker/lite/Dockerfile b/docker/lite/Dockerfile index a23413c473d..dbe5263d745 100644 --- a/docker/lite/Dockerfile +++ b/docker/lite/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.24.12-bookworm@sha256:8972893fa12177951b8bd4118470f338eaecea133c323be84066cd64f844fc03 AS builder +FROM --platform=linux/amd64 golang:1.24.13-bookworm@sha256:98d673f18a1aac43da744209873cb79323e11706f909251bcfb131828b95559d AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER diff --git a/docker/lite/Dockerfile.mysql84 b/docker/lite/Dockerfile.mysql84 index a2d0b08ac18..3239362d497 100644 --- a/docker/lite/Dockerfile.mysql84 +++ b/docker/lite/Dockerfile.mysql84 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.24.12-bookworm@sha256:8972893fa12177951b8bd4118470f338eaecea133c323be84066cd64f844fc03 AS builder +FROM --platform=linux/amd64 golang:1.24.13-bookworm@sha256:98d673f18a1aac43da744209873cb79323e11706f909251bcfb131828b95559d AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER diff --git a/docker/lite/Dockerfile.percona80 b/docker/lite/Dockerfile.percona80 index b4ed5bb0098..6e9356a2c23 100644 --- a/docker/lite/Dockerfile.percona80 +++ b/docker/lite/Dockerfile.percona80 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.24.12-bookworm@sha256:8972893fa12177951b8bd4118470f338eaecea133c323be84066cd64f844fc03 AS builder +FROM --platform=linux/amd64 golang:1.24.13-bookworm@sha256:98d673f18a1aac43da744209873cb79323e11706f909251bcfb131828b95559d AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER diff --git a/docker/vttestserver/Dockerfile.mysql80 b/docker/vttestserver/Dockerfile.mysql80 index 5b4dfac9cff..89999824a5d 100644 --- a/docker/vttestserver/Dockerfile.mysql80 +++ b/docker/vttestserver/Dockerfile.mysql80 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.24.12-bookworm@sha256:8972893fa12177951b8bd4118470f338eaecea133c323be84066cd64f844fc03 AS builder +FROM --platform=linux/amd64 golang:1.24.13-bookworm@sha256:98d673f18a1aac43da744209873cb79323e11706f909251bcfb131828b95559d AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER diff --git a/docker/vttestserver/Dockerfile.mysql84 b/docker/vttestserver/Dockerfile.mysql84 index ac727de46cb..13f247acf07 100644 --- a/docker/vttestserver/Dockerfile.mysql84 +++ b/docker/vttestserver/Dockerfile.mysql84 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.24.12-bookworm@sha256:8972893fa12177951b8bd4118470f338eaecea133c323be84066cd64f844fc03 AS builder +FROM --platform=linux/amd64 golang:1.24.13-bookworm@sha256:98d673f18a1aac43da744209873cb79323e11706f909251bcfb131828b95559d AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER diff --git a/go.mod b/go.mod index 073f0126ab7..23718d40909 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module vitess.io/vitess -go 1.24.12 +go 1.24.13 tool gotest.tools/gotestsum diff --git a/test.go b/test.go index 3b213ac4813..3087a42b9c6 100755 --- a/test.go +++ b/test.go @@ -77,7 +77,7 @@ For example: // Flags var ( flavor = flag.String("flavor", "mysql80", "comma-separated bootstrap flavor(s) to run against (when using Docker mode). Available flavors: all,"+flavors) - bootstrapVersion = flag.String("bootstrap-version", "43.6", "the version identifier to use for the docker images") + bootstrapVersion = flag.String("bootstrap-version", "43.7", "the version identifier to use for the docker images") runCount = flag.Int("runs", 1, "run each test this many times") logPass = flag.Bool("log-pass", false, "log test output even if it passes") timeout = flag.Duration("timeout", 30*time.Minute, "timeout for each test") From 1837be9f9763002ada653250542a97e401fff60c Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Sun, 8 Feb 2026 02:06:33 -0500 Subject: [PATCH 055/112] [release-22.0] Add lite image build CI job (#19321) (#19329) --- .github/workflows/docker_lite_build_check.yml | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 .github/workflows/docker_lite_build_check.yml diff --git a/.github/workflows/docker_lite_build_check.yml b/.github/workflows/docker_lite_build_check.yml new file mode 100644 index 00000000000..83923fd2c85 --- /dev/null +++ b/.github/workflows/docker_lite_build_check.yml @@ -0,0 +1,68 @@ +name: Docker Lite Build Check + +on: + pull_request: + branches: '**' + push: + branches: + - "main" + - "release-[0-9]+.[0-9]" + +permissions: read-all + +jobs: + generate-matrix: + name: Generate matrix + runs-on: ubuntu-24.04 + outputs: + dockerfiles: ${{ steps.generate-matrix.outputs.dockerfiles }} + steps: + - name: Check out code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: 'false' + + - name: Generate matrix + id: generate-matrix + run: | + dockerfiles=$(ls docker/lite/Dockerfile* | jq -Rnc '[inputs]') + echo "dockerfiles=${dockerfiles}" >> "$GITHUB_OUTPUT" + + build: + name: Build ${{ matrix.dockerfile }} + runs-on: ubuntu-24.04 + needs: generate-matrix + + strategy: + fail-fast: false + matrix: + dockerfile: ${{ fromJson(needs.generate-matrix.outputs.dockerfiles) }} + + steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 + with: + egress-policy: audit + + - name: Skip CI + run: | + if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then + echo "skipping CI due to the 'Skip CI' label" + exit 1 + fi + + - name: Check out code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: 'false' + + - name: Build lite image + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + with: + context: . + file: ${{ matrix.dockerfile }} + push: false + + concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.dockerfile }} + cancel-in-progress: true From ade3859ae9dee9f74a77be10a4692cfb9c0e107a Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Mon, 9 Feb 2026 20:13:06 +0100 Subject: [PATCH 056/112] [release-22.0] vtgate: fix handling of session variables on targeted connections (#19318) (#19334) Signed-off-by: Arthur Schreiber Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Arthur Schreiber --- .../vtgate/reservedconn/sysvar_test.go | 95 ++++++++++++------- go/vt/vtgate/engine/set.go | 13 +-- go/vt/vtgate/engine/set_test.go | 6 +- 3 files changed, 66 insertions(+), 48 deletions(-) diff --git a/go/test/endtoend/vtgate/reservedconn/sysvar_test.go b/go/test/endtoend/vtgate/reservedconn/sysvar_test.go index 8bda7dea121..e529355ef80 100644 --- a/go/test/endtoend/vtgate/reservedconn/sysvar_test.go +++ b/go/test/endtoend/vtgate/reservedconn/sysvar_test.go @@ -422,42 +422,65 @@ func checkOltpAndOlapInterchangingTx(t *testing.T, conn *mysql.Conn) { } func TestSysVarTxIsolation(t *testing.T) { - conn, err := mysql.Connect(context.Background(), &vtParams) - require.NoError(t, err) - defer conn.Close() - - // will run every check twice to see that the isolation level is set for all the queries in the session and - - // default from mysql - utils.AssertMatches(t, conn, "select @@transaction_isolation", `[[VARCHAR("REPEATABLE-READ")]]`) - // ensuring it goes to mysql - utils.AssertContains(t, conn, "select @@transaction_isolation, connection_id()", `REPEATABLE-READ`) - // second run, ensuring it has the same value. - utils.AssertContains(t, conn, "select @@transaction_isolation, connection_id()", `REPEATABLE-READ`) - - // setting to different value. - utils.Exec(t, conn, "set @@transaction_isolation = 'read-committed'") - utils.AssertMatches(t, conn, "select @@transaction_isolation", `[[VARCHAR("READ-COMMITTED")]]`) - // ensuring it goes to mysql - utils.AssertContains(t, conn, "select @@transaction_isolation, connection_id()", `READ-COMMITTED`) - // second run, to ensuring the setting is applied on the session and not just on next query after settings. - utils.AssertContains(t, conn, "select @@transaction_isolation, connection_id()", `READ-COMMITTED`) - - // changing setting to different value. - utils.Exec(t, conn, "set session transaction isolation level read uncommitted") - utils.AssertMatches(t, conn, "select @@transaction_isolation", `[[VARCHAR("READ-UNCOMMITTED")]]`) - // ensuring it goes to mysql - utils.AssertContains(t, conn, "select @@transaction_isolation, connection_id()", `READ-UNCOMMITTED`) - // second run, to ensuring the setting is applied on the session and not just on next query after settings. - utils.AssertContains(t, conn, "select @@transaction_isolation, connection_id()", `READ-UNCOMMITTED`) - - // changing setting to different value. - utils.Exec(t, conn, "set transaction isolation level serializable") - utils.AssertMatches(t, conn, "select @@transaction_isolation", `[[VARCHAR("SERIALIZABLE")]]`) - // ensuring it goes to mysql - utils.AssertContains(t, conn, "select @@transaction_isolation, connection_id()", `SERIALIZABLE`) - // second run, to ensuring the setting is applied on the session and not just on next query after settings. - utils.AssertContains(t, conn, "select @@transaction_isolation, connection_id()", `SERIALIZABLE`) + t.Run("returns the default isolation level if unchanged", func(t *testing.T) { + conn, err := mysql.Connect(context.Background(), &vtParams) + require.NoError(t, err) + defer conn.Close() + + // default from mysql + utils.AssertMatches(t, conn, "select @@transaction_isolation", `[[VARCHAR("REPEATABLE-READ")]]`) + // ensuring it goes to mysql + utils.AssertContains(t, conn, "select @@transaction_isolation, connection_id()", `REPEATABLE-READ`) + // second run, ensuring it has the same value. + utils.AssertContains(t, conn, "select @@transaction_isolation, connection_id()", `REPEATABLE-READ`) + + // Switch to shard targeting + utils.Exec(t, conn, "use `"+keyspaceName+":-80`") + + utils.AssertMatches(t, conn, "select @@transaction_isolation", `[[VARCHAR("REPEATABLE-READ")]]`) + utils.AssertContains(t, conn, "select @@transaction_isolation, connection_id()", `REPEATABLE-READ`) + utils.AssertContains(t, conn, "select @@transaction_isolation, connection_id()", `REPEATABLE-READ`) + }) + + t.Run("allows changing the isolation level via special syntax", func(t *testing.T) { + conn, err := mysql.Connect(context.Background(), &vtParams) + require.NoError(t, err) + defer conn.Close() + + // setting to different value. + utils.Exec(t, conn, "set session transaction isolation level read committed") + + utils.AssertMatches(t, conn, "select @@transaction_isolation", `[[VARCHAR("READ-COMMITTED")]]`) + utils.AssertContains(t, conn, "select @@transaction_isolation, connection_id()", `READ-COMMITTED`) + utils.AssertContains(t, conn, "select @@transaction_isolation, connection_id()", `READ-COMMITTED`) + + // Switch to shard targeting + utils.Exec(t, conn, "use `"+keyspaceName+":-80`") + utils.AssertMatches(t, conn, "select @@transaction_isolation", `[[VARCHAR("READ-COMMITTED")]]`) + + utils.Exec(t, conn, "set session transaction isolation level read uncommitted") + utils.AssertMatches(t, conn, "select @@transaction_isolation", `[[VARCHAR("READ-UNCOMMITTED")]]`) + }) + + t.Run("allows changing the isolation level via session variable", func(t *testing.T) { + conn, err := mysql.Connect(context.Background(), &vtParams) + require.NoError(t, err) + defer conn.Close() + + // setting to different value. + utils.Exec(t, conn, "set @@session.transaction_isolation = 'read-committed'") + + utils.AssertMatches(t, conn, "select @@transaction_isolation", `[[VARCHAR("READ-COMMITTED")]]`) + utils.AssertContains(t, conn, "select @@transaction_isolation, connection_id()", `READ-COMMITTED`) + utils.AssertContains(t, conn, "select @@transaction_isolation, connection_id()", `READ-COMMITTED`) + + // Switch to shard targeting + utils.Exec(t, conn, "use `"+keyspaceName+":-80`") + utils.AssertMatches(t, conn, "select @@transaction_isolation", `[[VARCHAR("READ-COMMITTED")]]`) + + utils.Exec(t, conn, "set @@session.transaction_isolation = 'read-uncommitted'") + utils.AssertMatches(t, conn, "select @@transaction_isolation", `[[VARCHAR("READ-UNCOMMITTED")]]`) + }) } // TestSysVarInnodbWaitTimeout tests the innodb_lock_wait_timeout system variable diff --git a/go/vt/vtgate/engine/set.go b/go/vt/vtgate/engine/set.go index 32a297404f3..f32584ca6f3 100644 --- a/go/vt/vtgate/engine/set.go +++ b/go/vt/vtgate/engine/set.go @@ -277,6 +277,7 @@ func (svs *SysVarReservedConn) Execute(ctx context.Context, vcursor VCursor, env return err } vcursor.Session().NeedsReservedConn() + vcursor.Session().SetSysVar(svs.Name, svs.Expr) return svs.execSetStatement(ctx, vcursor, rss, env) } needReservedConn, err := svs.checkAndUpdateSysVar(ctx, vcursor, env) @@ -292,22 +293,14 @@ func (svs *SysVarReservedConn) Execute(ctx context.Context, vcursor VCursor, env if len(rss) == 0 { return nil } - queries := make([]*querypb.BoundQuery, len(rss)) - for i := 0; i < len(rss); i++ { - queries[i] = &querypb.BoundQuery{ - Sql: fmt.Sprintf("set %s = %s", svs.Name, svs.Expr), - BindVariables: env.BindVars, - } - } - _, errs := vcursor.ExecuteMultiShard(ctx, nil /*primitive*/, rss, queries, false /*rollbackOnError*/, false /*canAutocommit*/, false /*fetchLastInsertID*/) - return vterrors.Aggregate(errs) + return svs.execSetStatement(ctx, vcursor, rss, env) } func (svs *SysVarReservedConn) execSetStatement(ctx context.Context, vcursor VCursor, rss []*srvtopo.ResolvedShard, env *evalengine.ExpressionEnv) error { queries := make([]*querypb.BoundQuery, len(rss)) for i := 0; i < len(rss); i++ { queries[i] = &querypb.BoundQuery{ - Sql: fmt.Sprintf("set @@%s = %s", svs.Name, svs.Expr), + Sql: fmt.Sprintf("set %s = %s", svs.Name, svs.Expr), BindVariables: env.BindVars, } } diff --git a/go/vt/vtgate/engine/set_test.go b/go/vt/vtgate/engine/set_test.go index 688c47c6f47..4f012fa4137 100644 --- a/go/vt/vtgate/engine/set_test.go +++ b/go/vt/vtgate/engine/set_test.go @@ -243,7 +243,8 @@ func TestSetTable(t *testing.T) { expectedQueryLog: []string{ `ResolveDestinations ks [] Destinations:DestinationAnyShard()`, `Needs Reserved Conn`, - `ExecuteMultiShard ks.-20: set @@x = dummy_expr {} false false`, + `SysVar set with (x,dummy_expr)`, + `ExecuteMultiShard ks.-20: set x = dummy_expr {} false false`, }, }, { testName: "sysvar set not modifying setting", @@ -609,7 +610,8 @@ func TestSysVarSetErr(t *testing.T) { expectedQueryLog := []string{ `ResolveDestinations ks [] Destinations:DestinationAnyShard()`, "Needs Reserved Conn", - `ExecuteMultiShard ks.-20: set @@x = dummy_expr {} false false`, + "SysVar set with (x,dummy_expr)", + `ExecuteMultiShard ks.-20: set x = dummy_expr {} false false`, } set := &Set{ From 9f36f93ced8a2104ced1d17be863f2264839f981 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 20:03:59 +0100 Subject: [PATCH 057/112] [release-22.0] vtgate: defer implicit transaction start until after query planning (#19277) (#19341) Signed-off-by: Arthur Schreiber Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- .../vtgate/reservedconn/sysvar_test.go | 373 ++++++++++++++++++ go/vt/vtgate/plan_execute.go | 88 ++++- 2 files changed, 453 insertions(+), 8 deletions(-) diff --git a/go/test/endtoend/vtgate/reservedconn/sysvar_test.go b/go/test/endtoend/vtgate/reservedconn/sysvar_test.go index e529355ef80..6bb5762b4a8 100644 --- a/go/test/endtoend/vtgate/reservedconn/sysvar_test.go +++ b/go/test/endtoend/vtgate/reservedconn/sysvar_test.go @@ -195,6 +195,35 @@ func TestSetSystemVariableAndThenSuccessfulAutocommitDML(t *testing.T) { utils.AssertMatches(t, conn, `select @@sql_safe_updates`, `[[INT64(1)]]`) } +// This test ensures that when autocommit is disabled, `SET` commands do not +// cause an implicit transaction to be started. +// +// We test this via `set session transaction isolation level` because +// changing the session transaction isolation level affects only the next +// transaction that's started. +func TestSetSystemVariableWithAutocommitDisabled(t *testing.T) { + conn1, err := mysql.Connect(context.Background(), &vtParams) + require.NoError(t, err) + defer conn1.Close() + + conn2, err := mysql.Connect(context.Background(), &vtParams) + require.NoError(t, err) + defer conn2.Close() + + utils.Exec(t, conn1, "delete from test") + utils.Exec(t, conn1, "delete from test_vdx") + + utils.Exec(t, conn1, "set autocommit = 0") + + utils.Exec(t, conn1, "set session transaction isolation level read uncommitted") + utils.AssertMatches(t, conn1, "select @@transaction_isolation", `[[VARCHAR("READ-UNCOMMITTED")]]`) + + utils.Exec(t, conn2, "begin") + utils.Exec(t, conn2, "insert into test (id, val1) values (80, null)") + + utils.AssertMatches(t, conn1, "select id from test where id = 80", `[[INT64(80)]]`) +} + func TestStartTxAndSetSystemVariableAndThenSuccessfulCommit(t *testing.T) { conn, err := mysql.Connect(context.Background(), &vtParams) @@ -427,6 +456,9 @@ func TestSysVarTxIsolation(t *testing.T) { require.NoError(t, err) defer conn.Close() + utils.Exec(t, conn, "delete from test") + utils.Exec(t, conn, "delete from test_vdx") + // default from mysql utils.AssertMatches(t, conn, "select @@transaction_isolation", `[[VARCHAR("REPEATABLE-READ")]]`) // ensuring it goes to mysql @@ -447,6 +479,9 @@ func TestSysVarTxIsolation(t *testing.T) { require.NoError(t, err) defer conn.Close() + utils.Exec(t, conn, "delete from test") + utils.Exec(t, conn, "delete from test_vdx") + // setting to different value. utils.Exec(t, conn, "set session transaction isolation level read committed") @@ -467,6 +502,9 @@ func TestSysVarTxIsolation(t *testing.T) { require.NoError(t, err) defer conn.Close() + utils.Exec(t, conn, "delete from test") + utils.Exec(t, conn, "delete from test_vdx") + // setting to different value. utils.Exec(t, conn, "set @@session.transaction_isolation = 'read-committed'") @@ -514,3 +552,338 @@ func TestSysVarInnodbWaitTimeout(t *testing.T) { // second run, to ensuring the setting is applied on the session and not just on next query after settings. utils.AssertContains(t, conn, "select @@innodb_lock_wait_timeout, connection_id()", `INT64(240)`) } + +// TestImplicitTxOnAutocommitOff verifies that vtgate only starts implicit +// transactions for statements that access real table data when autocommit=0, +// matching MySQL's behavior. +func TestImplicitTxOnAutocommitOff(t *testing.T) { + tests := []struct { + name string + query string + startsTx bool + }{ + { + name: "SELECT from real table starts tx", + query: "select id from test where id = 1", + startsTx: true, + }, + { + name: "SELECT @@variable does not start tx", + query: "select @@autocommit", + startsTx: false, + }, + { + name: "SELECT 1 does not start tx", + query: "select 1", + startsTx: false, + }, + { + name: "SELECT from dual does not start tx", + query: "select 1 from dual", + startsTx: false, + }, + { + name: "INSERT starts tx", + query: "insert into test (id, val1) values (999, null)", + startsTx: true, + }, + { + name: "UPDATE starts tx", + query: "update test set val1 = 'x' where id = 999", + startsTx: true, + }, + { + name: "DELETE starts tx", + query: "delete from test where id = 999", + startsTx: true, + }, + { + name: "SET variable does not start tx", + query: "set sql_safe_updates = 1", + startsTx: false, + }, + { + name: "COMMIT does not start tx", + query: "commit", + startsTx: false, + }, + { + name: "ROLLBACK does not start tx", + query: "rollback", + startsTx: false, + }, + // SHOW commands that start implicit transactions (access information_schema / data dictionaries): + { + name: "SHOW TABLES starts tx", + query: "show tables", + startsTx: true, + }, + { + name: "SHOW DATABASES starts tx", + query: "show databases", + startsTx: true, + }, + { + name: "SHOW COLUMNS starts tx", + query: "show columns from test", + startsTx: true, + }, + { + name: "SHOW INDEX starts tx", + query: "show index from test", + startsTx: true, + }, + { + name: "SHOW TABLE STATUS starts tx", + query: "show table status", + startsTx: true, + }, + { + name: "SHOW TRIGGERS starts tx", + query: "show triggers", + startsTx: true, + }, + { + name: "SHOW CHARSET starts tx", + query: "show charset", + startsTx: true, + }, + { + name: "SHOW COLLATION starts tx", + query: "show collation", + startsTx: true, + }, + { + name: "SHOW FUNCTION STATUS starts tx", + query: "show function status", + startsTx: true, + }, + { + name: "SHOW PROCEDURE STATUS starts tx", + query: "show procedure status", + startsTx: true, + }, + // SHOW commands that do NOT start implicit transactions (read server state only): + { + name: "SHOW VARIABLES does not start tx", + query: "show variables like 'version'", + startsTx: false, + }, + { + name: "SHOW SESSION VARIABLES does not start tx", + query: "show session variables like 'version'", + startsTx: false, + }, + { + name: "SHOW GLOBAL VARIABLES does not start tx", + query: "show global variables like 'version'", + startsTx: false, + }, + { + name: "SHOW STATUS does not start tx", + query: "show status like 'Uptime'", + startsTx: false, + }, + { + name: "SHOW GLOBAL STATUS does not start tx", + query: "show global status like 'Uptime'", + startsTx: false, + }, + { + name: "SHOW WARNINGS does not start tx", + query: "show warnings", + startsTx: false, + }, + { + name: "SHOW ENGINES does not start tx", + query: "show engines", + startsTx: false, + }, + { + name: "SHOW PLUGINS does not start tx", + query: "show plugins", + startsTx: false, + }, + { + name: "SHOW PRIVILEGES does not start tx", + query: "show privileges", + startsTx: false, + }, + { + name: "SHOW OPEN TABLES does not start tx", + query: "show open tables", + startsTx: false, + }, + // ShowCreate commands do not start implicit transactions. + { + name: "SHOW CREATE TABLE does not start tx", + query: "show create table test", + startsTx: false, + }, + { + name: "SHOW CREATE DATABASE does not start tx", + query: "show create database " + keyspaceName, + startsTx: false, + }, + // ShowOther commands are sent to MySQL as-is and do not start implicit transactions. + { + name: "SHOW PROCESSLIST does not start tx", + query: "show processlist", + startsTx: false, + }, + { + name: "SHOW BINARY LOGS does not start tx", + query: "show binary logs", + startsTx: false, + }, + { + name: "SHOW GRANTS does not start tx", + query: "show grants", + startsTx: false, + }, + { + name: "SHOW ERRORS does not start tx", + query: "show errors", + startsTx: false, + }, + { + name: "SHOW EVENTS does not start tx", + query: "show events", + startsTx: false, + }, + { + name: "SHOW PROFILES does not start tx", + query: "show profiles", + startsTx: false, + }, + { + name: "SHOW REPLICA STATUS does not start tx", + query: "show replica status", + startsTx: false, + }, + { + name: "SHOW ENGINE INNODB STATUS does not start tx", + query: "show engine innodb status", + startsTx: false, + }, + // Vitess-specific SHOW commands are handled internally by vtgate + // and should not start implicit transactions. + { + name: "SHOW VITESS_TABLETS does not start tx", + query: "show vitess_tablets", + startsTx: false, + }, + { + name: "SHOW VITESS_SHARDS does not start tx", + query: "show vitess_shards", + startsTx: false, + }, + { + name: "SHOW VITESS_TARGET does not start tx", + query: "show vitess_target", + startsTx: false, + }, + { + name: "SHOW VSCHEMA TABLES does not start tx", + query: "show vschema tables", + startsTx: false, + }, + { + name: "SHOW VSCHEMA KEYSPACES does not start tx", + query: "show vschema keyspaces", + startsTx: false, + }, + { + name: "SHOW VSCHEMA VINDEXES does not start tx", + query: "show vschema vindexes", + startsTx: false, + }, + { + name: "SHOW KEYSPACES does not start tx", + query: "show keyspaces", + startsTx: false, + }, + { + name: "SHOW VITESS_MIGRATIONS does not start tx", + query: "show vitess_migrations", + startsTx: false, + }, + { + name: "SHOW VITESS_REPLICATION_STATUS does not start tx", + query: "show vitess_replication_status", + startsTx: false, + }, + { + name: "SHOW GLOBAL GTID_EXECUTED does not start tx", + query: "show global gtid_executed", + startsTx: false, + }, + { + name: "SHOW GLOBAL VGTID_EXECUTED does not start tx", + query: "show global vgtid_executed", + startsTx: false, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + conn, err := mysql.Connect(context.Background(), &vtParams) + require.NoError(t, err) + defer conn.Close() + + utils.Exec(t, conn, "delete from test") + utils.Exec(t, conn, "delete from test_vdx") + + utils.Exec(t, conn, "set autocommit = 0") + + result := utils.Exec(t, conn, tc.query) + + inTx := result.StatusFlags&mysql.ServerStatusInTrans != 0 + if tc.startsTx { + assert.True(t, inTx, "expected %q to start an implicit transaction", tc.query) + } else { + assert.False(t, inTx, "expected %q to NOT start an implicit transaction", tc.query) + } + }) + } + + t.Run("ROLLBACK TO SAVEPOINT returns an error when no transaction has been started", func(t *testing.T) { + conn, err := mysql.Connect(context.Background(), &vtParams) + require.NoError(t, err) + defer conn.Close() + + utils.Exec(t, conn, "set autocommit = 0") + + _, err = utils.ExecAllowError(t, conn, "ROLLBACK TO SAVEPOINT sp1") + require.Error(t, err) + sqlErr, ok := err.(*sqlerror.SQLError) + require.True(t, ok, "not a mysql error: %T", err) + assert.Equal(t, sqlerror.ERSPDoesNotExist, sqlErr.Number()) + assert.Equal(t, sqlerror.SSClientError, sqlErr.SQLState()) + assert.Contains(t, sqlErr.Error(), "SAVEPOINT does not exist: ROLLBACK TO SAVEPOINT sp1 (errno 1305) (sqlstate 42000)") + + result := utils.Exec(t, conn, "select 1") + inTx := result.StatusFlags&mysql.ServerStatusInTrans != 0 + assert.False(t, inTx, "expected ROLLBACK TO SAVEPOINT to not start a transaction") + }) + + t.Run("RELEASE SAVEPOINT returns an error when no transaction has been started", func(t *testing.T) { + conn, err := mysql.Connect(context.Background(), &vtParams) + require.NoError(t, err) + defer conn.Close() + + utils.Exec(t, conn, "set autocommit = 0") + + _, err = utils.ExecAllowError(t, conn, "RELEASE SAVEPOINT sp1") + require.Error(t, err) + sqlErr, ok := err.(*sqlerror.SQLError) + require.True(t, ok, "not a mysql error: %T", err) + assert.Equal(t, sqlerror.ERSPDoesNotExist, sqlErr.Number()) + assert.Equal(t, sqlerror.SSClientError, sqlErr.SQLState()) + assert.Contains(t, sqlErr.Error(), "SAVEPOINT does not exist: RELEASE SAVEPOINT sp1 (errno 1305) (sqlstate 42000)") + + result := utils.Exec(t, conn, "select 1") + inTx := result.StatusFlags&mysql.ServerStatusInTrans != 0 + assert.False(t, inTx, "expected RELEASE SAVEPOINT to not start a transaction") + }) +} diff --git a/go/vt/vtgate/plan_execute.go b/go/vt/vtgate/plan_execute.go index 6e0672d845b..f2dcb05632f 100644 --- a/go/vt/vtgate/plan_execute.go +++ b/go/vt/vtgate/plan_execute.go @@ -19,6 +19,7 @@ package vtgate import ( "context" "fmt" + "slices" "strings" "time" @@ -70,12 +71,6 @@ func (e *Executor) newExecute( execPlan planExec, // used when there is a plan to execute recResult txResult, // used when it's something simple like begin/commit/rollback/savepoint ) (err error) { - // Start an implicit transaction if necessary. - err = e.startTxIfNecessary(ctx, safeSession) - if err != nil { - return err - } - if bindVars == nil { bindVars = make(map[string]*querypb.BindVariable) } @@ -130,6 +125,14 @@ func (e *Executor) newExecute( return err } + // Start an implicit transaction if necessary. This is done after plan + // creation so we can check whether the plan actually accesses real table + // data, matching MySQL's behavior where only data-accessing statements + // start implicit transactions when autocommit=0. + if err = e.startTxIfNecessary(ctx, plan, stmt, safeSession); err != nil { + return err + } + if plan.QueryType != sqlparser.StmtShow { safeSession.ClearWarnings() } @@ -264,8 +267,8 @@ func (e *Executor) handleTransactions( return nil, nil } -func (e *Executor) startTxIfNecessary(ctx context.Context, safeSession *econtext.SafeSession) error { - if !safeSession.Autocommit && !safeSession.InTransaction() { +func (e *Executor) startTxIfNecessary(ctx context.Context, plan *engine.Plan, stmt sqlparser.Statement, safeSession *econtext.SafeSession) error { + if !safeSession.Autocommit && !safeSession.InTransaction() && planStartsImplicitTx(plan, stmt) { if err := e.txConn.Begin(ctx, safeSession, nil); err != nil { return err } @@ -273,6 +276,75 @@ func (e *Executor) startTxIfNecessary(ctx context.Context, safeSession *econtext return nil } +// planStartsImplicitTx returns true if the given plan should start an implicit +// transaction when autocommit is disabled. This matches MySQL's behavior where +// only statements that access real table data start implicit transactions. +// +// The default is to start a transaction (matching the previous behavior), +// and we opt out for specific statement types we've verified against MySQL +// that don't start implicit transactions. +func planStartsImplicitTx(plan *engine.Plan, stmt sqlparser.Statement) bool { + switch plan.QueryType { + case sqlparser.StmtSelect: + // Only start an implicit tx if the plan accesses real tables, not just dual. + return slices.ContainsFunc(plan.TablesUsed, func(table string) bool { + return !strings.HasSuffix(table, ".dual") + }) + case sqlparser.StmtSet, sqlparser.StmtUse: + return false + case sqlparser.StmtShow: + return showStartsImplicitTx(stmt) + case sqlparser.StmtBegin, sqlparser.StmtCommit, sqlparser.StmtRollback, sqlparser.StmtSRollback, sqlparser.StmtRelease: + // Transaction control statements are handled by handleTransactions and should not + // trigger an implicit transaction start. + return false + default: + return true + } +} + +// showStartsImplicitTx returns true for SHOW commands that start implicit +// transactions in MySQL when autocommit=0. Verified experimentally against +// MySQL 8.0. Commands that only read server state (variables, status, +// warnings, engines, plugins, privileges) do not start transactions. +// +// The default is true (start a transaction) for safety — we only return +// false for commands we've explicitly verified against MySQL. +func showStartsImplicitTx(stmt sqlparser.Statement) bool { + show, ok := stmt.(*sqlparser.Show) + if !ok { + return true + } + switch internal := show.Internal.(type) { + case *sqlparser.ShowCreate: + // SHOW CREATE TABLE/DATABASE/etc. do not start implicit transactions in MySQL. + return false + case *sqlparser.ShowOther: + // ShowOther covers SHOW PROCESSLIST, SHOW ENGINE STATUS, SHOW BINARY LOGS, + // SHOW GRANTS, SHOW REPLICA STATUS, etc. These are server-state commands + // that don't start implicit transactions in MySQL. + return false + case *sqlparser.ShowBasic: + // Some SHOW commands do not start implicit transactions in MySQL, but we need to look at the command to determine which ones. + switch internal.Command { + case sqlparser.VariableSession, sqlparser.VariableGlobal, + sqlparser.StatusSession, sqlparser.StatusGlobal, + sqlparser.Warnings, sqlparser.Engines, sqlparser.Plugins, sqlparser.Privilege, + sqlparser.OpenTable, + // Vitess-specific SHOW commands are handled internally by vtgate and don't access InnoDB data. + sqlparser.GtidExecGlobal, sqlparser.VGtidExecGlobal, + sqlparser.VitessMigrations, sqlparser.VitessReplicationStatus, + sqlparser.VitessShards, sqlparser.VitessTablets, sqlparser.VitessTarget, sqlparser.VitessVariables, + sqlparser.VschemaTables, sqlparser.VschemaKeyspaces, sqlparser.VschemaVindexes, sqlparser.Keyspace: + return false + default: + return true + } + default: + return true + } +} + func (e *Executor) insideTransaction(ctx context.Context, safeSession *econtext.SafeSession, logStats *logstats.LogStats, execPlan func() error) error { mustCommit := false if safeSession.Autocommit && !safeSession.InTransaction() { From 1b2485e766a63676c2811569181381fd022e3ea1 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 20:05:19 +0100 Subject: [PATCH 058/112] [release-22.0] fix(backup): propagate file hashes to manifest after retry (#19336) (#19343) Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- go/vt/mysqlctl/blackbox/backup_test.go | 58 ++++++++++++++++++++++++++ go/vt/mysqlctl/builtinbackupengine.go | 7 ++++ 2 files changed, 65 insertions(+) diff --git a/go/vt/mysqlctl/blackbox/backup_test.go b/go/vt/mysqlctl/blackbox/backup_test.go index b7e35304904..b7eafbbb335 100644 --- a/go/vt/mysqlctl/blackbox/backup_test.go +++ b/go/vt/mysqlctl/blackbox/backup_test.go @@ -20,6 +20,7 @@ package blackbox import ( "bytes" "context" + "encoding/json" "errors" "fmt" "io" @@ -926,3 +927,60 @@ func TestExecuteRestoreFailToReadEachFileTwice(t *testing.T) { require.Equal(t, 5, ss.SourceOpenStats) require.Equal(t, 5, ss.SourceReadStats) } + +func TestBackupRetryPropagatesHashToManifest(t *testing.T) { + ctx := utils.LeakCheckContext(t) + backupRoot, keyspace, shard, ts := SetupCluster(ctx, t, 2, 2) + + bufferPerFiles := make(map[string]*rwCloseFailFirstCall) + be := &mysqlctl.BuiltinBackupEngine{} + bh := &mysqlctl.FakeBackupHandle{} + bh.AddFileReturnF = func(filename string) mysqlctl.FakeBackupHandleAddFileReturn { + _, isRetry := bufferPerFiles[filename] + newBuffer := newWriteCloseFailFirstWrite(isRetry) + bufferPerFiles[filename] = newBuffer + return mysqlctl.FakeBackupHandleAddFileReturn{WriteCloser: newBuffer} + } + + fakedb := fakesqldb.New(t) + defer fakedb.Close() + mysqld := mysqlctl.NewFakeMysqlDaemon(fakedb) + defer mysqld.Close() + mysqld.ExpectedExecuteSuperQueryList = []string{"STOP REPLICA", "START REPLICA"} + + ctx, cancel := context.WithCancel(ctx) + backupResult, err := be.ExecuteBackup(ctx, mysqlctl.BackupParams{ + Logger: logutil.NewMemoryLogger(), + Mysqld: mysqld, + Cnf: &mysqlctl.Mycnf{ + InnodbDataHomeDir: path.Join(backupRoot, "innodb"), + InnodbLogGroupHomeDir: path.Join(backupRoot, "log"), + DataDir: path.Join(backupRoot, "datadir"), + }, + Stats: backupstats.NewFakeStats(), + Concurrency: 1, + HookExtraEnv: map[string]string{}, + TopoServer: ts, + Keyspace: keyspace, + Shard: shard, + MysqlShutdownTimeout: MysqlShutdownTimeout, + }, bh) + cancel() + + require.NoError(t, err) + require.Equal(t, mysqlctl.BackupUsable, backupResult) + + // Parse the MANIFEST and verify all file entries have non-empty hashes. + manifestBuf, ok := bufferPerFiles["MANIFEST"] + require.True(t, ok, "MANIFEST should have been written") + + var manifest struct { + FileEntries []mysqlctl.FileEntry + } + require.NoError(t, json.Unmarshal(manifestBuf.Bytes(), &manifest)) + + require.NotEmpty(t, manifest.FileEntries, "manifest should contain file entries") + for _, fe := range manifest.FileEntries { + assert.NotEmptyf(t, fe.Hash, "file %s should have a non-empty hash in the manifest", fe.Name) + } +} diff --git a/go/vt/mysqlctl/builtinbackupengine.go b/go/vt/mysqlctl/builtinbackupengine.go index 61855ee9db6..b88c70c6953 100644 --- a/go/vt/mysqlctl/builtinbackupengine.go +++ b/go/vt/mysqlctl/builtinbackupengine.go @@ -653,6 +653,13 @@ func (be *BuiltinBackupEngine) backupFiles( if err != nil { return err } + // Propagate retry results back to the original entries so the + // manifest records correct hashes and metadata. + for i, fe := range newFEs { + if fe.Name != "" { + fes[i] = fe + } + } } // Backup the MANIFEST file and apply retry logic. From 7a8ceee49799632dffdae5dcc322674e2ff01213 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 21:37:39 +0000 Subject: [PATCH 059/112] [release-22.0] Performance: use `IsSingleShard()` check in `pushDerived` instead of just `engine.EqualUnique` opcode (#18974) (#19345) Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Mohamed Hamza --- .../planbuilder/operators/route_planning.go | 2 +- .../planbuilder/testdata/reference_cases.json | 25 ++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/go/vt/vtgate/planbuilder/operators/route_planning.go b/go/vt/vtgate/planbuilder/operators/route_planning.go index 200388365bd..5f64d8acff6 100644 --- a/go/vt/vtgate/planbuilder/operators/route_planning.go +++ b/go/vt/vtgate/planbuilder/operators/route_planning.go @@ -44,7 +44,7 @@ func pushDerived(ctx *plancontext.PlanningContext, op *Horizon) (Operator, *Appl return op, NoRewrite } - if !(innerRoute.Routing.OpCode() == engine.EqualUnique) && !op.IsMergeable(ctx) { + if !innerRoute.Routing.OpCode().IsSingleShard() && !op.IsMergeable(ctx) { // no need to check anything if we are sure that we will only hit a single shard return op, NoRewrite } diff --git a/go/vt/vtgate/planbuilder/testdata/reference_cases.json b/go/vt/vtgate/planbuilder/testdata/reference_cases.json index 424f80417f9..b14d85121c6 100644 --- a/go/vt/vtgate/planbuilder/testdata/reference_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/reference_cases.json @@ -934,5 +934,28 @@ "user.music" ] } + }, + { + "comment": "Derived table pushdown optimization", + "query": "SELECT * FROM (SELECT DISTINCT col FROM user.ref WHERE col = 1 LIMIT 10) as sub", + "plan": { + "Type": "Passthrough", + "QueryType": "SELECT", + "Original": "SELECT * FROM (SELECT DISTINCT col FROM user.ref WHERE col = 1 LIMIT 10) as sub", + "Instructions": { + "OperatorType": "Route", + "Variant": "Reference", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select col from (select col from ref where 1 != 1) as sub where 1 != 1", + "Query": "select col from (select distinct col from ref where col = 1 limit 10) as sub", + "Table": "ref" + }, + "TablesUsed": [ + "user.ref" + ] + } } -] +] \ No newline at end of file From 387c58c9ee1ef4b59bb5b6beba79d55f79e3efa8 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Fri, 13 Feb 2026 09:02:45 -0500 Subject: [PATCH 060/112] [release-22.0] try to fix setup mysql (#19371) (#19375) --- .github/actions/setup-mysql/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/setup-mysql/action.yml b/.github/actions/setup-mysql/action.yml index 444c2133a82..921e7733770 100644 --- a/.github/actions/setup-mysql/action.yml +++ b/.github/actions/setup-mysql/action.yml @@ -24,7 +24,7 @@ runs: # We have to install this old version of libaio1. See also: # https://bugs.launchpad.net/ubuntu/+source/libaio/+bug/2067501 - wget http://mirrors.kernel.org/ubuntu/pool/main/liba/libaio/libaio1_0.3.112-13build1_amd64.deb && \ + wget http://archive.ubuntu.com/ubuntu/pool/main/liba/libaio/libaio1_0.3.112-13build1_amd64.deb && \ sudo dpkg -i libaio1_0.3.112-13build1_amd64.deb && \ rm libaio1_0.3.112-13build1_amd64.deb @@ -40,7 +40,7 @@ runs: sudo DEBIAN_FRONTEND="noninteractive" dpkg -i mysql-apt-config* sudo apt-get update # libtinfo5 is also needed for older MySQL 5.7 builds. - curl -L -O http://mirrors.kernel.org/ubuntu/pool/universe/n/ncurses/libtinfo5_6.3-2ubuntu0.1_amd64.deb + curl -L -O http://archive.ubuntu.com/ubuntu/pool/universe/n/ncurses/libtinfo5_6.3-2ubuntu0.1_amd64.deb sudo dpkg -i libtinfo5_6.3-2ubuntu0.1_amd64.deb sudo DEBIAN_FRONTEND="noninteractive" apt-get install -y mysql-client=5.7* mysql-community-server=5.7* mysql-server=5.7* libncurses6 elif [[ "${{ inputs.flavor }}" == "mysql-8.0" ]]; then From a41949377253e0ac15d2294d5ff528dbf8e20532 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Tue, 17 Feb 2026 21:47:50 +0000 Subject: [PATCH 061/112] [release-22.0] CI: Fix workflows that install xtrabackup (#19383) (#19384) Signed-off-by: Matt Lord Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Matt Lord --- .github/workflows/cluster_endtoend.yml | 2 ++ .github/workflows/upgrade_downgrade_test_backups_e2e.yml | 5 +++-- .../upgrade_downgrade_test_backups_e2e_next_release.yml | 5 +++-- .github/workflows/upgrade_downgrade_test_backups_manual.yml | 5 +++-- .../upgrade_downgrade_test_backups_manual_next_release.yml | 5 +++-- .../upgrade_downgrade_test_reparent_new_vttablet.yml | 5 +++-- .github/workflows/upgrade_downgrade_test_semi_sync.yml | 5 +++-- 7 files changed, 20 insertions(+), 12 deletions(-) diff --git a/.github/workflows/cluster_endtoend.yml b/.github/workflows/cluster_endtoend.yml index d15a6bf47b0..6109a9a2e77 100644 --- a/.github/workflows/cluster_endtoend.yml +++ b/.github/workflows/cluster_endtoend.yml @@ -153,6 +153,8 @@ jobs: wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb sudo DEBIAN_FRONTEND="noninteractive" dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb sudo percona-release setup pdps8.0 + sudo percona-release setup pxb-80 + sudo percona-release enable ps-80 release sudo apt-get -qq update sudo apt-get -qq install -y percona-server-server percona-server-client sudo service mysql stop diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml index 698c52a834c..b4d61f87368 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml @@ -88,9 +88,10 @@ jobs: sudo service etcd stop wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb - sudo apt-get install -y gnupg2 + sudo apt-get install -y gnupg2 lz4 sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb - sudo percona-release enable-only tools + sudo percona-release enable tools + sudo percona-release setup pxb-80 sudo apt-get update sudo apt-get install -y percona-xtrabackup-80 diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml index bf51101fd69..098479787f1 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml @@ -90,9 +90,10 @@ jobs: sudo service etcd stop wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb - sudo apt-get install -y gnupg2 + sudo apt-get install -y gnupg2 lz4 sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb - sudo percona-release enable-only tools + sudo percona-release enable tools + sudo percona-release setup pxb-80 sudo apt-get update sudo apt-get install -y percona-xtrabackup-80 diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual.yml b/.github/workflows/upgrade_downgrade_test_backups_manual.yml index f45941ac7b0..c6129b636ee 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_manual.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_manual.yml @@ -93,9 +93,10 @@ jobs: sudo service etcd stop wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb - sudo apt-get install -y gnupg2 + sudo apt-get install -y gnupg2 lz4 sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb - sudo percona-release enable-only tools + sudo percona-release enable tools + sudo percona-release setup pxb-80 sudo apt-get update sudo apt-get install -y percona-xtrabackup-80 diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml b/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml index 0f100171b47..42cdd5ee7e3 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml @@ -94,9 +94,10 @@ jobs: sudo service etcd stop wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb - sudo apt-get install -y gnupg2 + sudo apt-get install -y gnupg2 lz4 sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb - sudo percona-release enable-only tools + sudo percona-release enable tools + sudo percona-release setup pxb-80 sudo apt-get update sudo apt-get install -y percona-xtrabackup-80 diff --git a/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml b/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml index 0a7690d1630..170baa58c4b 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml @@ -92,9 +92,10 @@ jobs: sudo service etcd stop wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb - sudo apt-get install -y gnupg2 + sudo apt-get install -y gnupg2 lz4 sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb - sudo percona-release enable-only tools + sudo percona-release enable tools + sudo percona-release setup pxb-80 sudo apt-get update sudo apt-get install -y percona-xtrabackup-80 diff --git a/.github/workflows/upgrade_downgrade_test_semi_sync.yml b/.github/workflows/upgrade_downgrade_test_semi_sync.yml index 01417975ce9..b5e64799c35 100644 --- a/.github/workflows/upgrade_downgrade_test_semi_sync.yml +++ b/.github/workflows/upgrade_downgrade_test_semi_sync.yml @@ -89,9 +89,10 @@ jobs: sudo service etcd stop wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb - sudo apt-get install -y gnupg2 + sudo apt-get install -y gnupg2 lz4 sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb - sudo percona-release enable-only tools + sudo percona-release enable tools + sudo percona-release setup pxb-80 sudo apt-get update sudo apt-get install -y percona-xtrabackup-80 From 8e01c0d8aa13c55fd98493347d0d8c72e7fef823 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Wed, 18 Feb 2026 14:51:53 +0000 Subject: [PATCH 062/112] [release-22.0] fix streaming binary row corruption in prepared statements (#19381) (#19414) Signed-off-by: Mohamed Hamza Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- go/sqltypes/proto3.go | 2 +- .../endtoend/vtgate/queries/misc/misc_test.go | 45 +++++++++++++++++ go/vt/vtgate/executor.go | 1 + go/vt/vtgate/executor_select_test.go | 4 ++ go/vt/vtgate/grpcvtgateconn/conn.go | 7 +++ go/vt/vtgate/plugin_mysql_server_test.go | 48 +++++++++++++++++++ go/vt/vtgate/vtgate_test.go | 3 +- .../tabletconntest/fakequeryservice.go | 10 ++++ 8 files changed, 118 insertions(+), 2 deletions(-) diff --git a/go/sqltypes/proto3.go b/go/sqltypes/proto3.go index 73e2faf654c..b9500bd5cb2 100644 --- a/go/sqltypes/proto3.go +++ b/go/sqltypes/proto3.go @@ -135,7 +135,7 @@ func CustomProto3ToResult(fields []*querypb.Field, qr *querypb.QueryResult) *Res return nil } return &Result{ - Fields: qr.Fields, + Fields: fields, RowsAffected: qr.RowsAffected, InsertID: qr.InsertId, InsertIDChanged: qr.InsertIdChanged, diff --git a/go/test/endtoend/vtgate/queries/misc/misc_test.go b/go/test/endtoend/vtgate/queries/misc/misc_test.go index 0755b98ec55..b720a4c04eb 100644 --- a/go/test/endtoend/vtgate/queries/misc/misc_test.go +++ b/go/test/endtoend/vtgate/queries/misc/misc_test.go @@ -374,6 +374,51 @@ func TestHighNumberOfParams(t *testing.T) { require.Equal(t, 5, count) } +// TestPreparedStatementInOLAP verifies that streaming prepared statements +// return correct binary-encoded rows when result fields are only sent in the +// first chunk. +func TestPreparedStatementInOLAP(t *testing.T) { + _, closer := start(t) + defer closer() + + // Use the binary protocol by disabling client-side parameter interpolation. + db, err := sql.Open("mysql", fmt.Sprintf("@tcp(%s:%v)/%s?interpolateParams=false", vtParams.Host, vtParams.Port, vtParams.DbName)) + require.NoError(t, err) + defer db.Close() + + // Pin a single connection so the session variable persists across operations. + conn, err := db.Conn(t.Context()) + require.NoError(t, err) + defer conn.Close() + + // Seed test data and switch to OLAP streaming mode. + _, err = conn.ExecContext(t.Context(), "delete from t1") + require.NoError(t, err) + _, err = conn.ExecContext(t.Context(), "insert into t1(id1, id2) values (1, 2)") + require.NoError(t, err) + _, err = conn.ExecContext(t.Context(), "set workload = olap") + require.NoError(t, err) + + // Select 7 columns: the null bitmap crosses a byte boundary at this count, + // making corruption from missing fields visible. + stmt, err := conn.PrepareContext(t.Context(), "select id1, id2, id1, id2, id1, id2, id1 from t1 where id1 = ?") + require.NoError(t, err) + defer stmt.Close() + + // Verify every column decoded correctly; corruption would show as NULL or + // wrong values. + var c1, c2, c3, c4, c5, c6, c7 int64 + err = stmt.QueryRow(1).Scan(&c1, &c2, &c3, &c4, &c5, &c6, &c7) + require.NoError(t, err) + require.Equal(t, int64(1), c1) + require.Equal(t, int64(2), c2) + require.Equal(t, int64(1), c3) + require.Equal(t, int64(2), c4) + require.Equal(t, int64(1), c5) + require.Equal(t, int64(2), c6) + require.Equal(t, int64(1), c7) +} + func TestPrepareStatements(t *testing.T) { mcmp, closer := start(t) defer closer() diff --git a/go/vt/vtgate/executor.go b/go/vt/vtgate/executor.go index 8621a107bf7..bab11fc272b 100644 --- a/go/vt/vtgate/executor.go +++ b/go/vt/vtgate/executor.go @@ -326,6 +326,7 @@ func (e *Executor) StreamExecute( // the framework currently sends all results as one packet. byteCount := 0 if len(qr.Fields) > 0 { + result.Fields = qr.Fields if err := callback(qr.Metadata()); err != nil { return err } diff --git a/go/vt/vtgate/executor_select_test.go b/go/vt/vtgate/executor_select_test.go index b9139556f8c..3bffe39c5ee 100644 --- a/go/vt/vtgate/executor_select_test.go +++ b/go/vt/vtgate/executor_select_test.go @@ -673,6 +673,10 @@ func TestStreamBuffering(t *testing.T) { {Name: "col", Type: sqltypes.VarChar, Charset: uint32(collations.MySQL8().DefaultConnectionCharset())}, }, }, { + Fields: []*querypb.Field{ + {Name: "id", Type: sqltypes.Int32, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_NUM_FLAG)}, + {Name: "col", Type: sqltypes.VarChar, Charset: uint32(collations.MySQL8().DefaultConnectionCharset())}, + }, Rows: [][]sqltypes.Value{{ sqltypes.NewInt32(1), sqltypes.NewVarChar("01234567890123456789"), diff --git a/go/vt/vtgate/grpcvtgateconn/conn.go b/go/vt/vtgate/grpcvtgateconn/conn.go index 86967de9662..27c7eed3655 100644 --- a/go/vt/vtgate/grpcvtgateconn/conn.go +++ b/go/vt/vtgate/grpcvtgateconn/conn.go @@ -238,6 +238,13 @@ func (a *streamExecuteMultiAdapter) Recv() (*sqltypes.Result, bool, error) { // we reach here, only when it is the last packet. // as in the last packet we receive the session and there is no result } + + // When a new result set starts, clear cached fields from the previous + // result set. + if newResult { + a.fields = nil + } + if err != nil { return nil, newResult, err } diff --git a/go/vt/vtgate/plugin_mysql_server_test.go b/go/vt/vtgate/plugin_mysql_server_test.go index a77d66d32b0..1eac6b350ae 100644 --- a/go/vt/vtgate/plugin_mysql_server_test.go +++ b/go/vt/vtgate/plugin_mysql_server_test.go @@ -565,6 +565,14 @@ func TestComQueryMulti(t *testing.T) { }, { QueryResult: &sqltypes.Result{ + Fields: []*querypb.Field{ + { + Name: "1", + Type: sqltypes.Int64, + Flags: uint32(querypb.MySqlFlag_NUM_FLAG | querypb.MySqlFlag_NOT_NULL_FLAG), + Charset: collations.CollationBinaryID, + }, + }, Rows: [][]sqltypes.Value{ { sqltypes.NewInt64(1), @@ -610,6 +618,14 @@ func TestComQueryMulti(t *testing.T) { }, { QueryResult: &sqltypes.Result{ + Fields: []*querypb.Field{ + { + Name: "1", + Type: sqltypes.Int64, + Flags: uint32(querypb.MySqlFlag_NUM_FLAG | querypb.MySqlFlag_NOT_NULL_FLAG), + Charset: collations.CollationBinaryID, + }, + }, Rows: [][]sqltypes.Value{ { sqltypes.NewInt64(1), @@ -646,6 +662,14 @@ func TestComQueryMulti(t *testing.T) { }, { QueryResult: &sqltypes.Result{ + Fields: []*querypb.Field{ + { + Name: "2", + Type: sqltypes.Int64, + Flags: uint32(querypb.MySqlFlag_NUM_FLAG | querypb.MySqlFlag_NOT_NULL_FLAG), + Charset: collations.CollationBinaryID, + }, + }, Rows: [][]sqltypes.Value{ { sqltypes.NewInt64(2), @@ -682,6 +706,14 @@ func TestComQueryMulti(t *testing.T) { }, { QueryResult: &sqltypes.Result{ + Fields: []*querypb.Field{ + { + Name: "3", + Type: sqltypes.Int64, + Flags: uint32(querypb.MySqlFlag_NUM_FLAG | querypb.MySqlFlag_NOT_NULL_FLAG), + Charset: collations.CollationBinaryID, + }, + }, Rows: [][]sqltypes.Value{ { sqltypes.NewInt64(3), @@ -727,6 +759,14 @@ func TestComQueryMulti(t *testing.T) { }, { QueryResult: &sqltypes.Result{ + Fields: []*querypb.Field{ + { + Name: "1", + Type: sqltypes.Int64, + Flags: uint32(querypb.MySqlFlag_NUM_FLAG | querypb.MySqlFlag_NOT_NULL_FLAG), + Charset: collations.CollationBinaryID, + }, + }, Rows: [][]sqltypes.Value{ { sqltypes.NewInt64(1), @@ -763,6 +803,14 @@ func TestComQueryMulti(t *testing.T) { }, { QueryResult: &sqltypes.Result{ + Fields: []*querypb.Field{ + { + Name: "2", + Type: sqltypes.Int64, + Flags: uint32(querypb.MySqlFlag_NUM_FLAG | querypb.MySqlFlag_NOT_NULL_FLAG), + Charset: collations.CollationBinaryID, + }, + }, Rows: [][]sqltypes.Value{ { sqltypes.NewInt64(2), diff --git a/go/vt/vtgate/vtgate_test.go b/go/vt/vtgate/vtgate_test.go index eea3618cec9..d1a53d324c2 100644 --- a/go/vt/vtgate/vtgate_test.go +++ b/go/vt/vtgate/vtgate_test.go @@ -271,7 +271,8 @@ func TestVTGateStreamExecute(t *testing.T) { want := []*sqltypes.Result{{ Fields: sandboxconn.StreamRowResult.Fields, }, { - Rows: sandboxconn.StreamRowResult.Rows, + Fields: sandboxconn.StreamRowResult.Fields, + Rows: sandboxconn.StreamRowResult.Rows, }} utils.MustMatch(t, want, qrs) if !proto.Equal(sbc.Options[0], executeOptions) { diff --git a/go/vt/vttablet/tabletconntest/fakequeryservice.go b/go/vt/vttablet/tabletconntest/fakequeryservice.go index e63cd028d05..faa4f59b96e 100644 --- a/go/vt/vttablet/tabletconntest/fakequeryservice.go +++ b/go/vt/vttablet/tabletconntest/fakequeryservice.go @@ -459,6 +459,16 @@ var StreamExecuteQueryResult1 = sqltypes.Result{ // StreamExecuteQueryResult2 is the second packet of a streaming result. var StreamExecuteQueryResult2 = sqltypes.Result{ + Fields: []*querypb.Field{ + { + Name: "field1", + Type: sqltypes.Int8, + }, + { + Name: "field2", + Type: sqltypes.Char, + }, + }, Rows: [][]sqltypes.Value{ { sqltypes.TestValue(sqltypes.Int8, "1"), From ce32eff0be5bc414500b8fc35a3588ce9eec71b9 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Wed, 18 Feb 2026 17:50:11 +0000 Subject: [PATCH 063/112] [release-22.0] sidecardb: make ALTER TABLE algorithm version-aware (#19358) (#19403) Signed-off-by: Mohamed Hamza Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Mohamed Hamza --- go/vt/sidecardb/sidecardb.go | 78 +++++++++++++++++++++- go/vt/sidecardb/sidecardb_test.go | 107 ++++++++++++++++++++++-------- 2 files changed, 158 insertions(+), 27 deletions(-) diff --git a/go/vt/sidecardb/sidecardb.go b/go/vt/sidecardb/sidecardb.go index 9cbe0540033..b8d79baa2bd 100644 --- a/go/vt/sidecardb/sidecardb.go +++ b/go/vt/sidecardb/sidecardb.go @@ -21,6 +21,7 @@ import ( "embed" "fmt" "io/fs" + "log/slog" "path/filepath" "regexp" "runtime" @@ -29,6 +30,8 @@ import ( "vitess.io/vitess/go/constants/sidecar" "vitess.io/vitess/go/history" + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/mysql/capabilities" "vitess.io/vitess/go/mysql/collations" "vitess.io/vitess/go/mysql/config" "vitess.io/vitess/go/mysql/sqlerror" @@ -51,6 +54,7 @@ const ( sidecarDBExistsQuery = "select 'true' as 'dbexists' from information_schema.SCHEMATA where SCHEMA_NAME = %a" showCreateTableQuery = "show create table %s.%s" sidecarCollationQuery = "select @@global.collation_server" + sidecarVersionQuery = "select @@version" maxDDLErrorHistoryLength = 100 @@ -202,6 +206,9 @@ type schemaInit struct { exec Exec dbCreated bool // The first upgrade/create query will also create the sidecar database if required. coll collations.ID + + // serverVersion is the version of the MySQL server. + serverVersion string } // Exec is a callback that has to be passed to Init() to @@ -389,6 +396,65 @@ func (si *schemaInit) getCurrentSchema(tableName string) (string, error) { return currentTableSchema, nil } +// serverVersionString returns the MySQL server version reported by the +// live sidecar connection. +func (si *schemaInit) serverVersionString() string { + if si.serverVersion != "" { + return si.serverVersion + } + + if si.exec == nil { + return si.env.MySQLVersion() + } + + rs, err := si.exec(si.ctx, sidecarVersionQuery, 1, false) + if err != nil { + log.Warningf("Error getting MySQL version during sidecar database initialization %s", slog.Any("error", err)) + return "" + } + + if len(rs.Rows) != 1 || len(rs.Rows[0]) == 0 { + log.Warningf("Invalid results for SidecarDB version query %s %s", slog.String("query", sidecarVersionQuery), slog.Int("rows", len(rs.Rows))) + return "" + } + + si.serverVersion = rs.Rows[0][0].ToString() + if si.serverVersion == "" { + log.Warning("MySQL version query returned empty result during sidecar database initialization") + } + + return si.serverVersion +} + +// alterTableAlgorithmStrategy returns the algorithm strategy to use for +// sidecar table ALTER statements. On MySQL < 8.0.32 we force ALGORITHM=COPY +// to work around a MySQL bug in the INSTANT DDL redo log format (8.0.29-8.0.31) +// that could cause data corruption during crash recovery. On MySQL >= 8.0.32 +// the bug is fixed and we omit the clause, letting MySQL choose the most +// efficient algorithm. +func (si *schemaInit) alterTableAlgorithmStrategy() int { + version := si.serverVersionString() + if version == "" { + return schemadiff.AlterTableAlgorithmStrategyCopy + } + + capableOf := mysql.ServerVersionCapableOf(version) + if capableOf == nil { + return schemadiff.AlterTableAlgorithmStrategyCopy + } + + capable, err := capableOf(capabilities.InstantDDLXtrabackupCapability) + if err != nil { + return schemadiff.AlterTableAlgorithmStrategyCopy + } + + if capable { + return schemadiff.AlterTableAlgorithmStrategyNone + } + + return schemadiff.AlterTableAlgorithmStrategyCopy +} + // findTableSchemaDiff gets the diff which needs to be applied // to the current table schema in order to reach the desired one. // The result will be an empty string if they match. @@ -397,7 +463,7 @@ func (si *schemaInit) getCurrentSchema(tableName string) (string, error) { func (si *schemaInit) findTableSchemaDiff(tableName, current, desired string) (string, error) { hints := &schemadiff.DiffHints{ TableCharsetCollateStrategy: schemadiff.TableCharsetCollateIgnoreEmpty, - AlterTableAlgorithmStrategy: schemadiff.AlterTableAlgorithmStrategyCopy, + AlterTableAlgorithmStrategy: si.alterTableAlgorithmStrategy(), } env := schemadiff.NewEnv(si.env, si.coll) diff, err := schemadiff.DiffCreateTablesQueries(env, current, desired, hints) @@ -514,6 +580,13 @@ func AddSchemaInitQueries(db *fakesqldb.DB, populateTables bool, parser *sqlpars sqlparser.String(sqlparser.NewIdentifierCS(table.name))).Query, result) } + mysqlVersionResult := sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "@@version", + "varchar"), + config.DefaultMySQLVersion, + ) + db.AddQuery(sidecarVersionQuery, mysqlVersionResult) + sqlModeResult := sqltypes.MakeTestResult(sqltypes.MakeTestFields( "sql_mode", "varchar"), @@ -543,6 +616,9 @@ func MatchesInitQuery(query string) bool { if strings.EqualFold(sdbe, query) { return true } + if strings.EqualFold(sidecarVersionQuery, query) { + return true + } for _, q := range sidecar.DBInitQueryPatterns { q = strings.ToLower(q) if strings.Contains(query, q) { diff --git a/go/vt/sidecardb/sidecardb_test.go b/go/vt/sidecardb/sidecardb_test.go index 78210f19150..71c29ea094f 100644 --- a/go/vt/sidecardb/sidecardb_test.go +++ b/go/vt/sidecardb/sidecardb_test.go @@ -215,7 +215,9 @@ func TestValidateSchema(t *testing.T) { } } -// TestAlterTableAlgorithm confirms that we use ALGORITHM=COPY during alter tables +// TestAlterTableAlgorithm confirms that ALTER TABLE statements use +// ALGORITHM=COPY on MySQL < 8.0.32 (to work around a MySQL bug in the +// INSTANT DDL redo log format) and omit the clause on MySQL >= 8.0.32. func TestAlterTableAlgorithm(t *testing.T) { type testCase struct { testName string @@ -227,28 +229,81 @@ func TestAlterTableAlgorithm(t *testing.T) { {"add column", "t1", "create table if not exists _vt.t1(i int)", "create table if not exists _vt.t1(i int, i1 int)"}, {"modify column", "t1", "create table if not exists _vt.t1(i int)", "create table if not exists _vt.t(i float)"}, } - si := &schemaInit{ - env: vtenv.NewTestEnv(), - } + copyAlgo := sqlparser.AlgorithmValue("COPY") - for _, tc := range testCases { - t.Run(tc.testName, func(t *testing.T) { - diff, err := si.findTableSchemaDiff(tc.tableName, tc.currentSchema, tc.desiredSchema) - require.NoError(t, err) - stmt, err := si.env.Parser().Parse(diff) - require.NoError(t, err) - alterTable, ok := stmt.(*sqlparser.AlterTable) - require.True(t, ok) - require.NotNil(t, alterTable) - var alterAlgo sqlparser.AlterOption - for i, opt := range alterTable.AlterOptions { - if _, ok := opt.(sqlparser.AlgorithmValue); ok { - alterAlgo = alterTable.AlterOptions[i] - } + + newSchemaInit := func(t *testing.T, envVersion, serverVersion string) *schemaInit { + t.Helper() + + env, err := vtenv.New(vtenv.Options{MySQLServerVersion: envVersion}) + require.NoError(t, err) + + versionResult := sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "@@version", + "varchar"), + serverVersion, + ) + + exec := func(ctx context.Context, query string, maxRows int, useDB bool) (*sqltypes.Result, error) { + if strings.EqualFold(query, sidecarVersionQuery) { + return versionResult, nil } - require.Equal(t, copyAlgo, alterAlgo) - }) + return nil, errors.New("unexpected query: " + query) + } + + return &schemaInit{ + env: env, + exec: exec, + } } + + t.Run("omitted on MySQL >= 8.0.32", func(t *testing.T) { + si := newSchemaInit(t, "8.0.31", "8.0.32") + + for _, tc := range testCases { + t.Run(tc.testName, func(t *testing.T) { + diff, err := si.findTableSchemaDiff(tc.tableName, tc.currentSchema, tc.desiredSchema) + require.NoError(t, err) + + stmt, err := si.env.Parser().Parse(diff) + require.NoError(t, err) + + alterTable, ok := stmt.(*sqlparser.AlterTable) + require.True(t, ok) + require.NotNil(t, alterTable) + + for _, opt := range alterTable.AlterOptions { + _, isAlgo := opt.(sqlparser.AlgorithmValue) + require.False(t, isAlgo, "expected no ALGORITHM hint on MySQL >= 8.0.32") + } + }) + } + }) + + t.Run("COPY on MySQL < 8.0.32", func(t *testing.T) { + si := newSchemaInit(t, "8.4.6", "8.0.31") + + for _, tc := range testCases { + t.Run(tc.testName, func(t *testing.T) { + diff, err := si.findTableSchemaDiff(tc.tableName, tc.currentSchema, tc.desiredSchema) + require.NoError(t, err) + + stmt, err := si.env.Parser().Parse(diff) + require.NoError(t, err) + + alterTable, ok := stmt.(*sqlparser.AlterTable) + require.True(t, ok) + require.NotNil(t, alterTable) + var found sqlparser.AlterOption + for _, opt := range alterTable.AlterOptions { + if _, ok := opt.(sqlparser.AlgorithmValue); ok { + found = opt + } + } + require.Equal(t, copyAlgo, found, "expected ALGORITHM=COPY on MySQL < 8.0.32") + }) + } + }) } // TestTableSchemaDiff ensures that the diff produced by schemaInit.findTableSchemaDiff @@ -272,7 +327,7 @@ func TestTableSchemaDiff(t *testing.T) { table: "t1", oldSchema: "create table if not exists _vt.t1(i int) charset=utf8mb4", newSchema: "create table if not exists _vt.t(i int) charset=utf8mb3", - expectedAlter: "alter table _vt.t1 charset utf8mb3, algorithm = copy", + expectedAlter: "alter table _vt.t1 charset utf8mb3", }, { name: "empty charset", @@ -286,35 +341,35 @@ func TestTableSchemaDiff(t *testing.T) { table: "t1", oldSchema: "create table if not exists _vt.t1(i int) engine=myisam", newSchema: "create table if not exists _vt.t(i int) engine=innodb", - expectedAlter: "alter table _vt.t1 engine innodb, algorithm = copy", + expectedAlter: "alter table _vt.t1 engine innodb", }, { name: "add, modify, transfer PK", table: "t1", oldSchema: "create table _vt.t1 (i int primary key, i1 varchar(10)) charset utf8mb4", newSchema: "create table _vt.t1 (i int, i1 varchar(20) character set utf8mb3 collate utf8mb3_bin, i2 int, primary key (i2)) charset utf8mb4", - expectedAlter: "alter table _vt.t1 drop primary key, modify column i1 varchar(20) character set utf8mb3 collate utf8mb3_bin, add column i2 int, add primary key (i2), algorithm = copy", + expectedAlter: "alter table _vt.t1 drop primary key, modify column i1 varchar(20) character set utf8mb3 collate utf8mb3_bin, add column i2 int, add primary key (i2)", }, { name: "modify visibility and add comment", table: "t1", oldSchema: "create table if not exists _vt.t1(c1 int, c2 int, c3 varchar(100)) charset utf8mb4", newSchema: "create table if not exists _vt.t1(c1 int, c2 int, c3 varchar(100) invisible comment 'hoping to drop') charset utf8mb4", - expectedAlter: "alter table _vt.t1 modify column c3 varchar(100) comment 'hoping to drop' invisible, algorithm = copy", + expectedAlter: "alter table _vt.t1 modify column c3 varchar(100) comment 'hoping to drop' invisible", }, { name: "add PK and remove index", table: "t1", oldSchema: "create table if not exists _vt.t1(c1 int, c2 int, c3 varchar(100), key (c2)) charset utf8mb4", newSchema: "create table if not exists _vt.t1(c1 int primary key, c2 int, c3 varchar(100)) charset utf8mb4", - expectedAlter: "alter table _vt.t1 drop key c2, add primary key (c1), algorithm = copy", + expectedAlter: "alter table _vt.t1 drop key c2, add primary key (c1)", }, { name: "add generated col", table: "t1", oldSchema: "create table if not exists _vt.t1(c1 int primary key) charset utf8mb4", newSchema: "create table if not exists _vt.t1(c1 int primary key, c2 varchar(10) generated always as ('hello')) charset utf8mb4", - expectedAlter: "alter table _vt.t1 add column c2 varchar(10) as ('hello') virtual, algorithm = copy", + expectedAlter: "alter table _vt.t1 add column c2 varchar(10) as ('hello') virtual", }, } From bb16a3507531bfc3d742e4f8d7d99536913ade2c Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Wed, 18 Feb 2026 13:19:12 -0500 Subject: [PATCH 064/112] [release-22.0] CI: Deflake two flaky tests (#19364) (#19411) Signed-off-by: Matt Lord Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Matt Lord --- .../transaction/twopc/fuzz/fuzzer_test.go | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/go/test/endtoend/transaction/twopc/fuzz/fuzzer_test.go b/go/test/endtoend/transaction/twopc/fuzz/fuzzer_test.go index f4e18c2b220..3a1601529ce 100644 --- a/go/test/endtoend/transaction/twopc/fuzz/fuzzer_test.go +++ b/go/test/endtoend/transaction/twopc/fuzz/fuzzer_test.go @@ -60,6 +60,7 @@ var ( insertIntoFuzzInsert = "INSERT INTO twopc_fuzzer_insert (id, updateSet, threadId) VALUES (%d, %d, %d)" selectFromFuzzUpdate = "SELECT col FROM twopc_fuzzer_update WHERE id = %d" selectIdFromFuzzInsert = "SELECT threadId FROM twopc_fuzzer_insert WHERE updateSet = %d AND id = %d ORDER BY col" + vtgateQueryTimeout = 5 * time.Second ) // TestTwoPCFuzzTest tests 2PC transactions in a fuzzer environment. @@ -277,7 +278,7 @@ func (fz *fuzzer) runFuzzerThread(t *testing.T, threadId int) { return } // Run an atomic transaction - fz.generateAndExecuteTransaction(threadId) + fz.generateAndExecuteTransaction(t, threadId) } } @@ -306,13 +307,15 @@ func (fz *fuzzer) initialize(t *testing.T, conn *mysql.Conn) { } // generateAndExecuteTransaction generates the queries of the transaction and then executes them. -func (fz *fuzzer) generateAndExecuteTransaction(threadId int) { +func (fz *fuzzer) generateAndExecuteTransaction(t *testing.T, threadId int) { // Create a connection to the vtgate to run transactions. - conn, err := mysql.Connect(context.Background(), &vtParams) - if err != nil { - return - } + ctx, cancel := context.WithTimeout(context.Background(), vtgateQueryTimeout) + defer cancel() + conn, err := mysql.Connect(ctx, &vtParams) + require.NoError(t, err) defer conn.Close() + _, err = conn.ExecuteFetch(fmt.Sprintf("set @@query_timeout = %d", vtgateQueryTimeout.Milliseconds()), 0, false) + require.NoError(t, err) // randomly generate an update set to use and the value to increment it by. updateSetVal := rand.IntN(fz.updateSets) incrementVal := rand.Int32() @@ -335,7 +338,12 @@ func (fz *fuzzer) generateAndExecuteTransaction(threadId int) { break } } - _, _ = conn.ExecuteFetch(finalCommand, 0, false) + _, err = conn.ExecuteFetch(finalCommand, 0, false) + // We don't care about the following case of errors here as the transaction is aborted, which is what we ultimately wanted: + // target: ks.80-.primary: vttablet: rpc error: code = Aborted desc = transaction 1771351525769549550: in use: for query (CallerID: userData1) (errno 1317) (sqlstate 70100) during query: rollback + if finalCommand != "rollback" { + require.NoError(t, err) + } } func getUpdateQuery(incrementVal int32, id int) string { @@ -485,6 +493,7 @@ func vttabletRestarts(t *testing.T) { return } tablet.VttabletProcess.ServingStatus = "SERVING" + deadline := time.Now().Add(2 * time.Minute) for { err = tablet.VttabletProcess.Setup() if err == nil { @@ -493,6 +502,10 @@ func vttabletRestarts(t *testing.T) { // Sometimes vttablets fail to connect to the topo server due to a minor blip there. // We don't want to fail the test, so we retry setting up the vttablet. log.Errorf("error restarting vttablet - %v", err) + if time.Now().After(deadline) { + log.Errorf("giving up restarting vttablet after timeout: %v", tablet.Alias) + return + } time.Sleep(1 * time.Second) } } From 0ea371ff052a8e31c25bd43aca06f14fcfe3d180 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Thu, 19 Feb 2026 10:54:48 -0500 Subject: [PATCH 065/112] [release-22.0] CI: Deflake Code Coverage workflow (#19388) (#19393) Signed-off-by: Matt Lord Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Matt Lord --- go/cmd/zkctl/command/teardown.go | 15 +++- go/mysql/auth_server_static_test.go | 19 ++--- go/vt/topo/zk2topo/server_test.go | 18 ++++- go/vt/topo/zk2topo/zk_conn_test.go | 18 ++++- .../semisyncmonitor/monitor_test.go | 4 +- .../tabletserver/tabletserver_test.go | 24 ++++-- go/vt/zkctl/zkctl_local.go | 22 ++++-- go/vt/zkctl/zkctl_test.go | 73 +++++++++++++++---- 8 files changed, 153 insertions(+), 40 deletions(-) diff --git a/go/cmd/zkctl/command/teardown.go b/go/cmd/zkctl/command/teardown.go index 14fe7278835..791ac2cf4a4 100644 --- a/go/cmd/zkctl/command/teardown.go +++ b/go/cmd/zkctl/command/teardown.go @@ -16,14 +16,25 @@ limitations under the License. package command -import "github.com/spf13/cobra" +import ( + "time" + + "github.com/spf13/cobra" +) var Teardown = &cobra.Command{ Use: "teardown", Short: "Shuts down the zookeeper server and removes its data dir.", Args: cobra.ExactArgs(0), RunE: func(cmd *cobra.Command, args []string) error { - return zkd.Teardown() + var err error + for range 3 { + if err = zkd.Teardown(); err == nil { + break + } + time.Sleep(1 * time.Second) + } + return err }, } diff --git a/go/mysql/auth_server_static_test.go b/go/mysql/auth_server_static_test.go index ee7815d0647..352f74ec38c 100644 --- a/go/mysql/auth_server_static_test.go +++ b/go/mysql/auth_server_static_test.go @@ -24,6 +24,7 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "vitess.io/vitess/go/test/utils" @@ -177,11 +178,12 @@ func hupTest(t *testing.T, aStatic *AuthServerStatic, tmpFile *os.File, oldStr, require.Equal(t, oldStr, aStatic.getEntries()[oldStr][0].Password, "%s's Password should still be '%s'", oldStr, oldStr) syscall.Kill(syscall.Getpid(), syscall.SIGHUP) - time.Sleep(100 * time.Millisecond) - // wait for signal handler - require.Nil(t, aStatic.getEntries()[oldStr], "Should not have old %s after config reload", oldStr) - require.Equal(t, newStr, aStatic.getEntries()[newStr][0].Password, "%s's Password should be '%s'", newStr, newStr) + // wait for signal handler + require.EventuallyWithT(t, func(c *assert.CollectT) { + require.Nil(c, aStatic.getEntries()[oldStr], "Should not have old %s after config reload", oldStr) + require.Equal(c, newStr, aStatic.getEntries()[newStr][0].Password, "%s's Password should be '%s'", newStr, newStr) + }, 30*time.Second, 10*time.Millisecond, "config should be reloaded with new file after rotation") } func hupTestWithRotation(t *testing.T, aStatic *AuthServerStatic, tmpFile *os.File, oldStr, newStr string) { @@ -190,11 +192,10 @@ func hupTestWithRotation(t *testing.T, aStatic *AuthServerStatic, tmpFile *os.Fi t.Fatalf("couldn't overwrite temp file: %v", err) } - time.Sleep(20 * time.Millisecond) - // wait for signal handler - require.Nil(t, aStatic.getEntries()[oldStr], "Should not have old %s after config reload", oldStr) - require.Equal(t, newStr, aStatic.getEntries()[newStr][0].Password, "%s's Password should be '%s'", newStr, newStr) - + require.EventuallyWithT(t, func(c *assert.CollectT) { + require.Nil(c, aStatic.getEntries()[oldStr], "Should not have old %s after config reload", oldStr) + require.Equal(c, newStr, aStatic.getEntries()[newStr][0].Password, "%s's Password should be '%s'", newStr, newStr) + }, 30*time.Second, 10*time.Millisecond, "config should be reloaded with new file after rotation") } func TestStaticMysqlNativePasswords(t *testing.T) { diff --git a/go/vt/topo/zk2topo/server_test.go b/go/vt/topo/zk2topo/server_test.go index 9fd36740913..836b55e4f5e 100644 --- a/go/vt/topo/zk2topo/server_test.go +++ b/go/vt/topo/zk2topo/server_test.go @@ -19,6 +19,7 @@ package zk2topo import ( "context" "fmt" + "os" "path" "testing" "time" @@ -34,9 +35,24 @@ import ( ) func TestZk2Topo(t *testing.T) { + if testing.Short() || os.Getenv("CI") == "true" { + t.Skip("skipping integration test in short mode and in CI (it's too flaky).") + } + // Start a real single ZK daemon, and close it after all tests are done. zkd, serverAddr := zkctl.StartLocalZk(testfiles.GoVtTopoZk2topoZkID, testfiles.GoVtTopoZk2topoPort) - defer zkd.Teardown() + defer func() { + var lastErr error + for range 3 { + if lastErr = zkd.Teardown(); lastErr == nil { + return + } + time.Sleep(1 * time.Second) + } + if lastErr != nil { + t.Logf("zkd.Teardown failed after retries: %v", lastErr) + } + }() // Run the test suite. testIndex := 0 diff --git a/go/vt/topo/zk2topo/zk_conn_test.go b/go/vt/topo/zk2topo/zk_conn_test.go index e79987b562f..2b953934c77 100644 --- a/go/vt/topo/zk2topo/zk_conn_test.go +++ b/go/vt/topo/zk2topo/zk_conn_test.go @@ -18,6 +18,7 @@ package zk2topo import ( "context" + "os" "testing" "time" @@ -29,8 +30,23 @@ import ( ) func TestZkConnClosedOnDisconnect(t *testing.T) { + if testing.Short() || os.Getenv("CI") == "true" { + t.Skip("skipping integration test in short mode and in CI (it's too flaky).") + } + zkd, serverAddr := zkctl.StartLocalZk(testfiles.GoVtTopoZk2topoZkID, testfiles.GoVtTopoZk2topoPort) - defer zkd.Teardown() + defer func() { + var lastErr error + for range 3 { + if lastErr = zkd.Teardown(); lastErr == nil { + return + } + time.Sleep(1 * time.Second) + } + if lastErr != nil { + t.Logf("zkd.Teardown failed after retries: %v", lastErr) + } + }() conn := Connect(serverAddr) defer conn.Close() diff --git a/go/vt/vttablet/tabletmanager/semisyncmonitor/monitor_test.go b/go/vt/vttablet/tabletmanager/semisyncmonitor/monitor_test.go index 5137d77ef97..b26cccfa549 100644 --- a/go/vt/vttablet/tabletmanager/semisyncmonitor/monitor_test.go +++ b/go/vt/vttablet/tabletmanager/semisyncmonitor/monitor_test.go @@ -656,12 +656,12 @@ func TestMonitorWriteBlocked(t *testing.T) { m.mu.Lock() defer m.mu.Unlock() return m.inProgressWriteCount > 0 - }, 2*time.Second, 5*time.Microsecond) + }, 15*time.Second, 1*time.Microsecond) // Check that the writes finished successfully. require.Eventually(t, func() bool { return writeFinished.Load() - }, 2*time.Second, 100*time.Millisecond) + }, 10*time.Second, 100*time.Millisecond) // After write completes, count should be back to zero. m.mu.Lock() diff --git a/go/vt/vttablet/tabletserver/tabletserver_test.go b/go/vt/vttablet/tabletserver/tabletserver_test.go index 23a65deafd1..11f28deb0f3 100644 --- a/go/vt/vttablet/tabletserver/tabletserver_test.go +++ b/go/vt/vttablet/tabletserver/tabletserver_test.go @@ -221,7 +221,9 @@ func TestTabletServerRedoLogIsKeptBetweenRestarts(t *testing.T) { db.AddQuery(tpc.readAllRedo, &sqltypes.Result{}) turnOnTxEngine() - assert.Empty(t, tsv.te.preparedPool.conns, "tsv.te.preparedPool.conns") + require.EventuallyWithT(t, func(c *assert.CollectT) { + require.Empty(c, tsv.te.preparedPool.conns, "tsv.te.preparedPool.conns") + }, 5*time.Second, 10*time.Millisecond, "prepared transactions should be empty initially") turnOffTxEngine() db.AddQuery(tpc.readAllRedo, &sqltypes.Result{ @@ -241,14 +243,18 @@ func TestTabletServerRedoLogIsKeptBetweenRestarts(t *testing.T) { }}, }) turnOnTxEngine() - assert.EqualValues(t, 1, len(tsv.te.preparedPool.conns), "len(tsv.te.preparedPool.conns)") + require.EventuallyWithT(t, func(c *assert.CollectT) { + require.EqualValues(c, 1, len(tsv.te.preparedPool.conns), "len(tsv.te.preparedPool.conns)") + }, 5*time.Second, 10*time.Millisecond, "prepared transactions should be loaded from redo log") got := tsv.te.preparedPool.conns["dtid0"].TxProperties().Queries want := []tx.Query{{ Sql: "update test_table set `name` = 2 where pk = 1 limit 10001", Tables: []string{"test_table"}}} utils.MustMatch(t, want, got, "Prepared queries") turnOffTxEngine() - assert.Empty(t, tsv.te.preparedPool.conns, "tsv.te.preparedPool.conns") + require.EventuallyWithT(t, func(c *assert.CollectT) { + require.Empty(c, tsv.te.preparedPool.conns, "tsv.te.preparedPool.conns") + }, 5*time.Second, 10*time.Millisecond, "prepared transactions should be cleared when transaction engine is turned off") tsv.te.txPool.scp.lastID.Store(1) // Ensure we continue past errors. @@ -281,7 +287,9 @@ func TestTabletServerRedoLogIsKeptBetweenRestarts(t *testing.T) { }}, }) turnOnTxEngine() - assert.EqualValues(t, 1, len(tsv.te.preparedPool.conns), "len(tsv.te.preparedPool.conns)") + require.EventuallyWithT(t, func(c *assert.CollectT) { + require.EqualValues(c, 1, len(tsv.te.preparedPool.conns), "len(tsv.te.preparedPool.conns)") + }, 5*time.Second, 10*time.Millisecond, "only valid prepared transactions should be loaded from redo log") got = tsv.te.preparedPool.conns["a:b:10"].TxProperties().Queries want = []tx.Query{{ Sql: "update test_table set `name` = 2 where pk = 1 limit 10001", @@ -293,9 +301,13 @@ func TestTabletServerRedoLogIsKeptBetweenRestarts(t *testing.T) { } utils.MustMatch(t, tsv.te.preparedPool.reserved, wantFailed, fmt.Sprintf("Failed dtids: %v, want %v", tsv.te.preparedPool.reserved, wantFailed)) // Verify last id got adjusted. - assert.EqualValues(t, 20, tsv.te.txPool.scp.lastID.Load(), "tsv.te.txPool.lastID.Get()") + require.EventuallyWithT(t, func(c *assert.CollectT) { + require.EqualValues(c, 20, tsv.te.txPool.scp.lastID.Load(), "tsv.te.txPool.lastID.Get()") + }, 5*time.Second, 10*time.Millisecond, "lastID should be adjusted to the max id in redo log") turnOffTxEngine() - assert.Empty(t, tsv.te.preparedPool.conns, "tsv.te.preparedPool.conns") + require.EventuallyWithT(t, func(c *assert.CollectT) { + require.Empty(c, tsv.te.preparedPool.conns, "tsv.te.preparedPool.conns") + }, 5*time.Second, 10*time.Millisecond, "prepared transactions should be cleared when transaction engine is turned off") } func TestTabletServerCreateTransaction(t *testing.T) { diff --git a/go/vt/zkctl/zkctl_local.go b/go/vt/zkctl/zkctl_local.go index dfb11e28cd6..d6f44c37b08 100644 --- a/go/vt/zkctl/zkctl_local.go +++ b/go/vt/zkctl/zkctl_local.go @@ -18,9 +18,10 @@ package zkctl import ( "fmt" + "log" + "time" "vitess.io/vitess/go/netutil" - "vitess.io/vitess/go/vt/log" ) // StartLocalZk is a helper method to create a local ZK process. Used @@ -34,10 +35,19 @@ func StartLocalZk(id, port int) (*Zkd, string) { zkConfig := MakeZkConfigFromString(zkCfg, uint32(id)) zkd := NewZkd(zkConfig) - // Init & start zk. - if err := zkd.Init(); err != nil { - log.Exitf("zkd.Init(%d, %d) failed: %v", id, port, err) + // Init & start ZK. + retryTimer := time.NewTimer(10 * time.Minute) + defer retryTimer.Stop() + var err error + for { + if err = zkd.Init(); err == nil || err.Error() == "zk already inited" { + return zkd, fmt.Sprintf("%v:%v", hostname, port+2) + } + select { + case <-retryTimer.C: + log.Fatalf("zkd.Init(%d, %d) failed: %v", id, port, err) + default: + time.Sleep(1 * time.Second) + } } - - return zkd, fmt.Sprintf("%v:%v", hostname, port+2) } diff --git a/go/vt/zkctl/zkctl_test.go b/go/vt/zkctl/zkctl_test.go index a0c03a58df2..54417387401 100644 --- a/go/vt/zkctl/zkctl_test.go +++ b/go/vt/zkctl/zkctl_test.go @@ -18,7 +18,10 @@ package zkctl import ( "fmt" + "math/rand/v2" + "os" "testing" + "time" "github.com/stretchr/testify/require" ) @@ -28,16 +31,20 @@ import ( // so some manual cleanup may be required. func TestLifeCycle(t *testing.T) { - if testing.Short() { - t.Skip("skipping integration test in short mode.") + if testing.Short() || os.Getenv("CI") == "true" { + t.Skip("skipping integration test in short mode and in CI (it's too flaky).") } - config := "255@voltron:2888:3888:2181" - myID := 255 + leaderPort := 2888 + rand.IntN(100) + electionPort := 3888 + rand.IntN(100) + clientPort := 2181 + rand.IntN(100) + adminPort := 8081 + rand.IntN(100) + myID := 200 + rand.IntN(100) + config := fmt.Sprintf("%d@voltron:%d:%d:%d", myID, leaderPort, electionPort, clientPort) zkConf := MakeZkConfigFromString(config, uint32(myID)) tpcKeepAliveCfg := "tcpKeepAlive=true" - adminServerCfg := "admin.serverPort=8081" + adminServerCfg := fmt.Sprintf("admin.serverPort=%d", adminPort) zkConf.Extra = []string{tpcKeepAliveCfg, adminServerCfg} zkObservedConf, err := MakeZooCfg([]string{zkConf.ConfigFile()}, zkConf, "header") @@ -45,16 +52,56 @@ func TestLifeCycle(t *testing.T) { require.Contains(t, zkObservedConf, fmt.Sprintf("\n%s\n", tpcKeepAliveCfg), "Expected tpcKeepAliveCfg in zkObservedConf") require.Contains(t, zkObservedConf, fmt.Sprintf("\n%s\n", adminServerCfg), "Expected adminServerCfg in zkObservedConf") + retryTimer := time.NewTimer(10 * time.Minute) + defer retryTimer.Stop() + zkd := NewZkd(zkConf) - err = zkd.Init() - require.NoError(t, err) - err = zkd.Shutdown() - require.NoError(t, err) + for { + if err = zkd.Init(); err == nil { + break + } + select { + case <-retryTimer.C: + require.FailNow(t, "timeout waiting for Zkd.Init() to succeed: ", err) + default: + time.Sleep(1 * time.Second) + } + } - err = zkd.Start() - require.NoError(t, err) + for { + if err = zkd.Shutdown(); err == nil { + break + } + select { + case <-retryTimer.C: + require.FailNow(t, "timeout waiting for Zkd.Shutdown() to succeed: ", err) + default: + time.Sleep(1 * time.Second) + } + } - err = zkd.Teardown() - require.NoError(t, err) + for { + if err = zkd.Start(); err == nil { + break + } + select { + case <-retryTimer.C: + require.FailNow(t, "timeout waiting for Zkd.Start() to succeed: ", err) + default: + time.Sleep(1 * time.Second) + } + } + + for { + if err = zkd.Teardown(); err == nil { + break + } + select { + case <-retryTimer.C: + require.FailNow(t, "timeout waiting for Zkd.Teardown() to succeed: ", err) + default: + time.Sleep(1 * time.Second) + } + } } From 433c2b9afa21d7d4a39261282851677397e46b19 Mon Sep 17 00:00:00 2001 From: Matt Lord Date: Thu, 19 Feb 2026 23:17:14 -0500 Subject: [PATCH 066/112] [release-22.0] Bug fix: Add missing db_name filters to vreplication and vdiff queries #19378 (#19430) Signed-off-by: dleibovic Signed-off-by: Matt Lord Co-authored-by: David Leibovic Co-authored-by: Claude Opus 4.6 --- go/vt/sidecardb/schema/vdiff/vdiff.sql | 2 +- .../tabletmanager/rpc_vreplication.go | 5 ++- .../tabletmanager/rpc_vreplication_test.go | 11 ++--- go/vt/vttablet/tabletmanager/vdiff/action.go | 12 +++++- .../tabletmanager/vdiff/action_test.go | 43 +++++++++---------- .../tabletmanager/vdiff/controller.go | 3 +- go/vt/vttablet/tabletmanager/vdiff/engine.go | 18 +++++--- .../tabletmanager/vdiff/engine_test.go | 22 +++++----- .../tabletmanager/vdiff/framework_test.go | 9 ++-- go/vt/vttablet/tabletmanager/vdiff/schema.go | 32 +++++++------- .../vdiff/workflow_differ_test.go | 8 ++-- 11 files changed, 91 insertions(+), 74 deletions(-) diff --git a/go/vt/sidecardb/schema/vdiff/vdiff.sql b/go/vt/sidecardb/schema/vdiff/vdiff.sql index 862e6e0e9d3..447119dd748 100644 --- a/go/vt/sidecardb/schema/vdiff/vdiff.sql +++ b/go/vt/sidecardb/schema/vdiff/vdiff.sql @@ -30,7 +30,7 @@ CREATE TABLE IF NOT EXISTS vdiff `completed_at` timestamp NULL DEFAULT NULL, `last_error` varbinary(1024) DEFAULT NULL, PRIMARY KEY (`id`), - UNIQUE KEY `uuid_idx` (`vdiff_uuid`), + UNIQUE KEY `uuid_idx` (`vdiff_uuid`, `db_name`), KEY `state` (`state`), KEY `ks_wf_idx` (`keyspace`(64), `workflow`(64)) ) ENGINE = InnoDB CHARSET = utf8mb4 diff --git a/go/vt/vttablet/tabletmanager/rpc_vreplication.go b/go/vt/vttablet/tabletmanager/rpc_vreplication.go index ad4dbe97f73..937794ef905 100644 --- a/go/vt/vttablet/tabletmanager/rpc_vreplication.go +++ b/go/vt/vttablet/tabletmanager/rpc_vreplication.go @@ -59,7 +59,7 @@ const ( // Delete VReplication records for the given workflow. sqlDeleteVReplicationWorkflow = "delete from %s.vreplication where workflow = %a and db_name = %a" // Retrieve the current configuration values for a workflow's vreplication stream(s). - sqlSelectVReplicationWorkflowConfig = "select id, source, cell, tablet_types, state, message from %s.vreplication where workflow = %a" + sqlSelectVReplicationWorkflowConfig = "select id, source, cell, tablet_types, state, message from %s.vreplication where workflow = %a and db_name = %a" // Update the configuration values for a workflow's vreplication stream. sqlUpdateVReplicationWorkflowStreamConfig = "update %s.vreplication set state = %a, source = %a, cell = %a, tablet_types = %a, message = %a %s where id = %a" // Update field values for multiple workflows. The final format specifier is @@ -524,8 +524,9 @@ func isStreamCopying(tm *TabletManager, id int64) (bool, error) { func (tm *TabletManager) UpdateVReplicationWorkflow(ctx context.Context, req *tabletmanagerdatapb.UpdateVReplicationWorkflowRequest) (*tabletmanagerdatapb.UpdateVReplicationWorkflowResponse, error) { bindVars := map[string]*querypb.BindVariable{ "wf": sqltypes.StringBindVariable(req.Workflow), + "db": sqltypes.StringBindVariable(tm.DBConfigs.DBName), } - parsed := sqlparser.BuildParsedQuery(sqlSelectVReplicationWorkflowConfig, sidecar.GetIdentifier(), ":wf") + parsed := sqlparser.BuildParsedQuery(sqlSelectVReplicationWorkflowConfig, sidecar.GetIdentifier(), ":wf", ":db") stmt, err := parsed.GenerateQuery(bindVars, nil) if err != nil { return nil, err diff --git a/go/vt/vttablet/tabletmanager/rpc_vreplication_test.go b/go/vt/vttablet/tabletmanager/rpc_vreplication_test.go index bb2ef7bfead..16e805055a7 100644 --- a/go/vt/vttablet/tabletmanager/rpc_vreplication_test.go +++ b/go/vt/vttablet/tabletmanager/rpc_vreplication_test.go @@ -80,7 +80,7 @@ const ( readAllWorkflows = "select workflow, id, source, pos, stop_pos, max_tps, max_replication_lag, cell, tablet_types, time_updated, transaction_timestamp, state, message, db_name, rows_copied, tags, time_heartbeat, workflow_type, time_throttled, component_throttled, workflow_sub_type, defer_secondary_keys, options from _vt.vreplication where db_name = '%s'%s order by workflow, id" readWorkflowsLimited = "select workflow, id, source, pos, stop_pos, max_tps, max_replication_lag, cell, tablet_types, time_updated, transaction_timestamp, state, message, db_name, rows_copied, tags, time_heartbeat, workflow_type, time_throttled, component_throttled, workflow_sub_type, defer_secondary_keys, options from _vt.vreplication where db_name = '%s' and workflow in ('%s') order by workflow, id" readWorkflow = "select id, source, pos, stop_pos, max_tps, max_replication_lag, cell, tablet_types, time_updated, transaction_timestamp, state, message, db_name, rows_copied, tags, time_heartbeat, workflow_type, time_throttled, component_throttled, workflow_sub_type, defer_secondary_keys, options from _vt.vreplication where workflow = '%s' and db_name = '%s'" - readWorkflowConfig = "select id, source, cell, tablet_types, state, message from _vt.vreplication where workflow = '%s'" + readWorkflowConfig = "select id, source, cell, tablet_types, state, message from _vt.vreplication where workflow = '%s' and db_name = '%s'" updateWorkflow = "update _vt.vreplication set state = '%s', source = '%s', cell = '%s', tablet_types = '%s', message = '%s' where id in (%d)" getNonEmptyTableQuery = "select 1 from `%s` limit 1" ) @@ -438,7 +438,7 @@ func TestMoveTablesUnsharded(t *testing.T) { ), fmt.Sprintf("%d|%s|%s|NULL|0|0|||1686577659|0|Stopped||%s|1||0|0|0||0|1|{}", vreplID, bls, position, targetKs), )) - ftc.vrdbClient.ExpectRequest(fmt.Sprintf(readWorkflowConfig, wf), sqltypes.MakeTestResult( + ftc.vrdbClient.ExpectRequest(fmt.Sprintf(readWorkflowConfig, wf, tenv.dbName), sqltypes.MakeTestResult( sqltypes.MakeTestFields( "id|source|cell|tablet_types|state|message", "int64|blob|varchar|varchar|varchar|varchar", @@ -707,7 +707,7 @@ func TestMoveTablesSharded(t *testing.T) { ), fmt.Sprintf("%d|%s|%s|NULL|0|0|||1686577659|0|Stopped||%s|1||0|0|0||0|1|{}", vreplID, bls, position, targetKs), )) - ftc.vrdbClient.ExpectRequest(fmt.Sprintf(readWorkflowConfig, wf), sqltypes.MakeTestResult( + ftc.vrdbClient.ExpectRequest(fmt.Sprintf(readWorkflowConfig, wf, tenv.dbName), sqltypes.MakeTestResult( sqltypes.MakeTestFields( "id|source|cell|tablet_types|state|message", "int64|blob|varchar|varchar|varchar|varchar", @@ -890,9 +890,10 @@ func TestUpdateVReplicationWorkflow(t *testing.T) { tablet := tenv.addTablet(t, tabletUID, keyspace, shard) defer tenv.deleteTablet(tablet.tablet) - parsed := sqlparser.BuildParsedQuery(sqlSelectVReplicationWorkflowConfig, sidecar.GetIdentifier(), ":wf") + parsed := sqlparser.BuildParsedQuery(sqlSelectVReplicationWorkflowConfig, sidecar.GetIdentifier(), ":wf", ":db") bindVars := map[string]*querypb.BindVariable{ "wf": sqltypes.StringBindVariable(workflow), + "db": sqltypes.StringBindVariable(tenv.dbName), } selectQuery, err := parsed.GenerateQuery(bindVars, nil) require.NoError(t, err) @@ -2155,7 +2156,7 @@ func TestExternalizeLookupVindex(t *testing.T) { targetTablet.vrdbClient.ExpectRequest(fmt.Sprintf(readWorkflow, tcase.request.Name, tenv.dbName), tcase.vrResponse, nil) // Update queries are required only if the Vindex is owned. if tcase.expectStopped && len(tcase.expectedVschema.Vindexes) > 0 && tcase.expectedVschema.Vindexes[tcase.request.Name].Owner != "" { - targetTablet.vrdbClient.ExpectRequest(fmt.Sprintf(readWorkflowConfig, tcase.request.Name), sqltypes.MakeTestResult( + targetTablet.vrdbClient.ExpectRequest(fmt.Sprintf(readWorkflowConfig, tcase.request.Name, tenv.dbName), sqltypes.MakeTestResult( sqltypes.MakeTestFields( "id|source|cell|tablet_types|state|message", "int64|blob|varchar|varchar|varchar|varchar", diff --git a/go/vt/vttablet/tabletmanager/vdiff/action.go b/go/vt/vttablet/tabletmanager/vdiff/action.go index 9cfb145c1e0..c238a11f772 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/action.go +++ b/go/vt/vttablet/tabletmanager/vdiff/action.go @@ -118,7 +118,7 @@ func (vde *Engine) getVDiffSummary(vdiffID int64, dbClient binlogplayer.DBClient var qr *sqltypes.Result var err error - query, err := sqlparser.ParseAndBind(sqlVDiffSummary, sqltypes.Int64BindVariable(vdiffID)) + query, err := sqlparser.ParseAndBind(sqlVDiffSummary, sqltypes.Int64BindVariable(vdiffID), sqltypes.StringBindVariable(vde.dbName)) if err != nil { return nil, err } @@ -176,7 +176,7 @@ func (vde *Engine) handleCreateResumeAction(ctx context.Context, dbClient binlog var qr *sqltypes.Result options := req.GetOptions() - query, err := sqlparser.ParseAndBind(sqlGetVDiffID, sqltypes.StringBindVariable(req.VdiffUuid)) + query, err := sqlparser.ParseAndBind(sqlGetVDiffID, sqltypes.StringBindVariable(req.VdiffUuid), sqltypes.StringBindVariable(vde.dbName)) if err != nil { return err } @@ -235,6 +235,7 @@ func (vde *Engine) handleCreateResumeAction(ctx context.Context, dbClient binlog execResume := func(query string) (rowsAffected uint64, err error) { query, err = sqlparser.ParseAndBind(query, sqltypes.StringBindVariable(req.VdiffUuid), + sqltypes.StringBindVariable(vde.dbName), ) if err != nil { return 0, err @@ -296,6 +297,7 @@ func (vde *Engine) handleShowAction(ctx context.Context, dbClient binlogplayer.D query, err := sqlparser.ParseAndBind(sqlGetMostRecentVDiffByKeyspaceWorkflow, sqltypes.StringBindVariable(req.Keyspace), sqltypes.StringBindVariable(req.Workflow), + sqltypes.StringBindVariable(vde.dbName), sqltypes.Int64BindVariable(1), ) if err != nil { @@ -319,6 +321,7 @@ func (vde *Engine) handleShowAction(ctx context.Context, dbClient binlogplayer.D sqltypes.StringBindVariable(req.Keyspace), sqltypes.StringBindVariable(req.Workflow), sqltypes.StringBindVariable(vdiffUUID), + sqltypes.StringBindVariable(vde.dbName), ) if err != nil { return err @@ -348,6 +351,7 @@ func (vde *Engine) handleShowAction(ctx context.Context, dbClient binlogplayer.D query, err := sqlparser.ParseAndBind(sqlGetMostRecentVDiffByKeyspaceWorkflow, sqltypes.StringBindVariable(req.Keyspace), sqltypes.StringBindVariable(req.Workflow), + sqltypes.StringBindVariable(vde.dbName), sqltypes.Int64BindVariable(maxVDiffsToReport), ) if err != nil { @@ -404,6 +408,7 @@ func (vde *Engine) handleDeleteAction(ctx context.Context, dbClient binlogplayer query, err := sqlparser.ParseAndBind(sqlGetVDiffIDsByKeyspaceWorkflow, sqltypes.StringBindVariable(req.Keyspace), sqltypes.StringBindVariable(req.Workflow), + sqltypes.StringBindVariable(vde.dbName), ) if err != nil { return err @@ -418,6 +423,7 @@ func (vde *Engine) handleDeleteAction(ctx context.Context, dbClient binlogplayer deleteQuery, err = sqlparser.ParseAndBind(sqlDeleteVDiffs, sqltypes.StringBindVariable(req.Keyspace), sqltypes.StringBindVariable(req.Workflow), + sqltypes.StringBindVariable(vde.dbName), ) if err != nil { return err @@ -431,6 +437,7 @@ func (vde *Engine) handleDeleteAction(ctx context.Context, dbClient binlogplayer // it's still running, before we delete the vdiff record. query, err := sqlparser.ParseAndBind(sqlGetVDiffID, sqltypes.StringBindVariable(uuid.String()), + sqltypes.StringBindVariable(vde.dbName), ) if err != nil { return err @@ -447,6 +454,7 @@ func (vde *Engine) handleDeleteAction(ctx context.Context, dbClient binlogplayer cleanupController(vde.controllers[row.AsInt64("id", -1)]) deleteQuery, err = sqlparser.ParseAndBind(sqlDeleteVDiffByUUID, sqltypes.StringBindVariable(uuid.String()), + sqltypes.StringBindVariable(vde.dbName), ) if err != nil { return err diff --git a/go/vt/vttablet/tabletmanager/vdiff/action_test.go b/go/vt/vttablet/tabletmanager/vdiff/action_test.go index 6bdc7044878..d885f7b180b 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/action_test.go +++ b/go/vt/vttablet/tabletmanager/vdiff/action_test.go @@ -85,7 +85,7 @@ func TestPerformVDiffAction(t *testing.T) { }, expectQueries: []queryAndResult{ { - query: fmt.Sprintf("select id as id from _vt.vdiff where vdiff_uuid = %s", encodeString(uuid)), + query: "select id as id from _vt.vdiff where vdiff_uuid = " + encodeString(uuid) + " and db_name = " + encodeString(vdiffDBName), }, { query: fmt.Sprintf(`insert into _vt.vdiff(keyspace, workflow, state, options, shard, db_name, vdiff_uuid) values('', '', 'pending', '{"picker_options":{"source_cell":"cell1,zone100_test","target_cell":"cell1,zone100_test"}}', '0', 'vt_vttest', %s)`, encodeString(uuid)), @@ -109,7 +109,7 @@ func TestPerformVDiffAction(t *testing.T) { }, expectQueries: []queryAndResult{ { - query: fmt.Sprintf("select id as id from _vt.vdiff where vdiff_uuid = %s", encodeString(uuid)), + query: "select id as id from _vt.vdiff where vdiff_uuid = " + encodeString(uuid) + " and db_name = " + encodeString(vdiffDBName), }, { query: fmt.Sprintf(`insert into _vt.vdiff(keyspace, workflow, state, options, shard, db_name, vdiff_uuid) values('', '', 'stopped', '{"picker_options":{"source_cell":"cell1","target_cell":"cell1"},"core_options":{"auto_start":false}}', '0', 'vt_vttest', %s)`, encodeString(uuid)), @@ -140,7 +140,7 @@ func TestPerformVDiffAction(t *testing.T) { }, expectQueries: []queryAndResult{ { - query: fmt.Sprintf("select id as id from _vt.vdiff where vdiff_uuid = %s", encodeString(uuid)), + query: "select id as id from _vt.vdiff where vdiff_uuid = " + encodeString(uuid) + " and db_name = " + encodeString(vdiffDBName), }, { query: fmt.Sprintf(`insert into _vt.vdiff(keyspace, workflow, state, options, shard, db_name, vdiff_uuid) values('', '', 'pending', '{"picker_options":{"source_cell":"all","target_cell":"all"}}', '0', 'vt_vttest', %s)`, encodeString(uuid)), @@ -163,7 +163,7 @@ func TestPerformVDiffAction(t *testing.T) { }, expectQueries: []queryAndResult{ { - query: fmt.Sprintf("select id as id from _vt.vdiff where vdiff_uuid = %s", encodeString(uuid)), + query: "select id as id from _vt.vdiff where vdiff_uuid = " + encodeString(uuid) + " and db_name = " + encodeString(vdiffDBName), result: sqltypes.MakeTestResult( sqltypes.MakeTestFields( "id", @@ -174,23 +174,23 @@ func TestPerformVDiffAction(t *testing.T) { }, { query: fmt.Sprintf(`update _vt.vdiff as vd, _vt.vdiff_table as vdt set vd.started_at = NULL, vd.completed_at = NULL, vd.state = 'pending', - vdt.state = 'pending' where vd.vdiff_uuid = %s and vd.id = vdt.vdiff_id and vd.state in ('completed', 'stopped') - and vdt.state in ('completed', 'stopped')`, encodeString(uuid)), + vdt.state = 'pending' where vd.vdiff_uuid = %s and vd.db_name = %s and vd.id = vdt.vdiff_id and vd.state in ('completed', 'stopped') + and vdt.state in ('completed', 'stopped')`, encodeString(uuid), encodeString(vdiffDBName)), result: &sqltypes.Result{ RowsAffected: 0, // No _vt.vdiff_table records }, }, { - query: fmt.Sprintf(`update _vt.vdiff as vd set vd.state = 'pending' where vd.vdiff_uuid = %s and vd.state = 'stopped' and + query: fmt.Sprintf(`update _vt.vdiff as vd set vd.state = 'pending' where vd.vdiff_uuid = %s and vd.db_name = %s and vd.state = 'stopped' and vd.started_at is NULL and vd.completed_at is NULL and (select count(*) as cnt from _vt.vdiff_table as vdt where vd.id = vdt.vdiff_id) = 0`, - encodeString(uuid)), + encodeString(uuid), encodeString(vdiffDBName)), result: &sqltypes.Result{ RowsAffected: 1, }, }, { - query: "select * from _vt.vdiff where id = 1", + query: "select * from _vt.vdiff where id = 1 and db_name = " + encodeString(vdiffDBName), }, }, }, @@ -204,7 +204,7 @@ func TestPerformVDiffAction(t *testing.T) { }, expectQueries: []queryAndResult{ { - query: fmt.Sprintf("select id as id from _vt.vdiff where vdiff_uuid = %s", encodeString(uuid)), + query: "select id as id from _vt.vdiff where vdiff_uuid = " + encodeString(uuid) + " and db_name = " + encodeString(vdiffDBName), result: sqltypes.MakeTestResult( sqltypes.MakeTestFields( "id", @@ -215,14 +215,14 @@ func TestPerformVDiffAction(t *testing.T) { }, { query: fmt.Sprintf(`update _vt.vdiff as vd, _vt.vdiff_table as vdt set vd.started_at = NULL, vd.completed_at = NULL, vd.state = 'pending', - vdt.state = 'pending' where vd.vdiff_uuid = %s and vd.id = vdt.vdiff_id and vd.state in ('completed', 'stopped') - and vdt.state in ('completed', 'stopped')`, encodeString(uuid)), + vdt.state = 'pending' where vd.vdiff_uuid = %s and vd.db_name = %s and vd.id = vdt.vdiff_id and vd.state in ('completed', 'stopped') + and vdt.state in ('completed', 'stopped')`, encodeString(uuid), encodeString(vdiffDBName)), result: &sqltypes.Result{ RowsAffected: 1, }, }, { - query: "select * from _vt.vdiff where id = 1", + query: "select * from _vt.vdiff where id = 1 and db_name = " + encodeString(vdiffDBName), }, }, }, @@ -234,7 +234,7 @@ func TestPerformVDiffAction(t *testing.T) { }, expectQueries: []queryAndResult{ { - query: fmt.Sprintf("select id as id from _vt.vdiff where vdiff_uuid = %s", encodeString(uuid)), + query: "select id as id from _vt.vdiff where vdiff_uuid = " + encodeString(uuid) + " and db_name = " + encodeString(vdiffDBName), result: sqltypes.MakeTestResult( sqltypes.MakeTestFields( "id", @@ -244,8 +244,7 @@ func TestPerformVDiffAction(t *testing.T) { ), }, { - query: fmt.Sprintf(`delete from vd, vdt using _vt.vdiff as vd left join _vt.vdiff_table as vdt on (vd.id = vdt.vdiff_id) - where vd.vdiff_uuid = %s`, encodeString(uuid)), + query: "delete from vd, vdt using _vt.vdiff as vd left join _vt.vdiff_table as vdt on (vd.id = vdt.vdiff_id)\n\t\t\t\t\t\t\twhere vd.vdiff_uuid = " + encodeString(uuid) + " and vd.db_name = " + encodeString(vdiffDBName), }, }, }, @@ -259,7 +258,7 @@ func TestPerformVDiffAction(t *testing.T) { }, expectQueries: []queryAndResult{ { - query: fmt.Sprintf("select id as id from _vt.vdiff where keyspace = %s and workflow = %s", encodeString(keyspace), encodeString(workflow)), + query: fmt.Sprintf("select id as id from _vt.vdiff where keyspace = %s and workflow = %s and db_name = %s", encodeString(keyspace), encodeString(workflow), encodeString(vdiffDBName)), result: sqltypes.MakeTestResult( sqltypes.MakeTestFields( "id", @@ -272,7 +271,7 @@ func TestPerformVDiffAction(t *testing.T) { { query: fmt.Sprintf(`delete from vd, vdt, vdl using _vt.vdiff as vd left join _vt.vdiff_table as vdt on (vd.id = vdt.vdiff_id) left join _vt.vdiff_log as vdl on (vd.id = vdl.vdiff_id) - where vd.keyspace = %s and vd.workflow = %s`, encodeString(keyspace), encodeString(workflow)), + where vd.keyspace = %s and vd.workflow = %s and vd.db_name = %s`, encodeString(keyspace), encodeString(workflow), encodeString(vdiffDBName)), }, }, }, @@ -286,8 +285,8 @@ func TestPerformVDiffAction(t *testing.T) { }, expectQueries: []queryAndResult{ { - query: fmt.Sprintf("select * from _vt.vdiff where keyspace = %s and workflow = %s order by id desc limit %d", - encodeString(keyspace), encodeString(workflow), 1), + query: fmt.Sprintf("select * from _vt.vdiff where keyspace = %s and workflow = %s and db_name = %s order by id desc limit %d", + encodeString(keyspace), encodeString(workflow), encodeString(vdiffDBName), 1), result: noResults, }, }, @@ -302,8 +301,8 @@ func TestPerformVDiffAction(t *testing.T) { }, expectQueries: []queryAndResult{ { - query: fmt.Sprintf("select * from _vt.vdiff where keyspace = %s and workflow = %s order by id desc limit %d", - encodeString(keyspace), encodeString(workflow), maxVDiffsToReport), + query: fmt.Sprintf("select * from _vt.vdiff where keyspace = %s and workflow = %s and db_name = %s order by id desc limit %d", + encodeString(keyspace), encodeString(workflow), encodeString(vdiffDBName), maxVDiffsToReport), result: noResults, }, }, diff --git a/go/vt/vttablet/tabletmanager/vdiff/controller.go b/go/vt/vttablet/tabletmanager/vdiff/controller.go index 7b5e1311066..0ce41a64c86 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/controller.go +++ b/go/vt/vttablet/tabletmanager/vdiff/controller.go @@ -176,6 +176,7 @@ func (ct *controller) updateState(dbClient binlogplayer.DBClient, state VDiffSta encodeString(err.Error()), extraCols, ct.id, + encodeString(ct.vde.dbName), ) if _, err := dbClient.ExecuteFetch(query.Query, 1); err != nil { return err @@ -274,7 +275,7 @@ func (ct *controller) markStoppedByRequest() error { } defer dbClient.Close() - query, err := sqlparser.ParseAndBind(sqlUpdateVDiffStopped, sqltypes.Int64BindVariable(ct.id)) + query, err := sqlparser.ParseAndBind(sqlUpdateVDiffStopped, sqltypes.Int64BindVariable(ct.id), sqltypes.StringBindVariable(ct.vde.dbName)) if err != nil { return err } diff --git a/go/vt/vttablet/tabletmanager/vdiff/engine.go b/go/vt/vttablet/tabletmanager/vdiff/engine.go index cd3771accfd..cb27e4c84f0 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/engine.go +++ b/go/vt/vttablet/tabletmanager/vdiff/engine.go @@ -292,7 +292,11 @@ func (vde *Engine) getVDiffsToRun(ctx context.Context) (*sqltypes.Result, error) // We have to use ExecIgnore here so as not to block quick tablet state // transitions from primary to non-primary when starting the engine - qr, err := dbClient.ExecuteFetch(sqlGetVDiffsToRun, -1) + query, err := sqlparser.ParseAndBind(sqlGetVDiffsToRun, sqltypes.StringBindVariable(vde.dbName)) + if err != nil { + return nil, err + } + qr, err := dbClient.ExecuteFetch(query, -1) if err != nil { return nil, err } @@ -303,7 +307,11 @@ func (vde *Engine) getVDiffsToRun(ctx context.Context) (*sqltypes.Result, error) } func (vde *Engine) getVDiffsToRetry(ctx context.Context, dbClient binlogplayer.DBClient) (*sqltypes.Result, error) { - qr, err := dbClient.ExecuteFetch(sqlGetVDiffsToRetry, -1) + query, err := sqlparser.ParseAndBind(sqlGetVDiffsToRetry, sqltypes.StringBindVariable(vde.dbName)) + if err != nil { + return nil, err + } + qr, err := dbClient.ExecuteFetch(query, -1) if err != nil { return nil, err } @@ -314,7 +322,7 @@ func (vde *Engine) getVDiffsToRetry(ctx context.Context, dbClient binlogplayer.D } func (vde *Engine) getVDiffByID(ctx context.Context, dbClient binlogplayer.DBClient, id int64) (*sqltypes.Result, error) { - query, err := sqlparser.ParseAndBind(sqlGetVDiffByID, sqltypes.Int64BindVariable(id)) + query, err := sqlparser.ParseAndBind(sqlGetVDiffByID, sqltypes.Int64BindVariable(id), sqltypes.StringBindVariable(vde.dbName)) if err != nil { return nil, err } @@ -360,8 +368,8 @@ func (vde *Engine) retryVDiffs(ctx context.Context) error { if err != nil { return err } - log.Infof("Retrying vdiff %s that had an ephemeral error of '%v'", uuid, lastError) - query, err := sqlparser.ParseAndBind(sqlRetryVDiff, sqltypes.Int64BindVariable(id)) + log.Info(fmt.Sprintf("Retrying vdiff %s that had an ephemeral error of '%v'", uuid, lastError)) + query, err := sqlparser.ParseAndBind(sqlRetryVDiff, sqltypes.Int64BindVariable(id), sqltypes.StringBindVariable(vde.dbName)) if err != nil { return err } diff --git a/go/vt/vttablet/tabletmanager/vdiff/engine_test.go b/go/vt/vttablet/tabletmanager/vdiff/engine_test.go index 374756418c6..94aa99b0737 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/engine_test.go +++ b/go/vt/vttablet/tabletmanager/vdiff/engine_test.go @@ -69,8 +69,8 @@ func TestEngineOpen(t *testing.T) { fmt.Sprintf("1|%s|%s|%s|%s|%s|%s|%s|", UUID, vdenv.workflow, tstenv.KeyspaceName, tstenv.ShardName, vdiffDBName, tt.state, optionsJS), ) - vdenv.dbClient.ExpectRequest("select * from _vt.vdiff where state in ('started','pending')", initialQR, nil) - vdenv.dbClient.ExpectRequest("select * from _vt.vdiff where id = 1", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + vdenv.dbClient.ExpectRequest("select * from _vt.vdiff where state in ('started','pending') and db_name = "+encodeString(vdiffDBName), initialQR, nil) + vdenv.dbClient.ExpectRequest("select * from _vt.vdiff where id = 1 and db_name = "+encodeString(vdiffDBName), sqltypes.MakeTestResult(sqltypes.MakeTestFields( vdiffTestCols, vdiffTestColTypes, ), @@ -84,7 +84,7 @@ func TestEngineOpen(t *testing.T) { ), nil) // Now let's short circuit the vdiff as we know that the open has worked as expected. - shortCircuitTestAfterQuery("update _vt.vdiff set state = 'started', last_error = left('', 1024) , started_at = utc_timestamp() where id = 1", vdiffenv.dbClient) + shortCircuitTestAfterQuery("update _vt.vdiff set state = 'started', last_error = left('', 1024) , started_at = utc_timestamp() where id = 1 and db_name = 'vttest'", vdiffenv.dbClient) vdenv.vde.Open(context.Background(), vdiffenv.vre) defer vdenv.vde.Close() @@ -124,14 +124,14 @@ func TestVDiff(t *testing.T) { fmt.Sprintf("1|%s|%s|%s|%s|%s|pending|%s|", UUID, vdenv.workflow, tstenv.KeyspaceName, tstenv.ShardName, vdiffDBName, optionsJS), ) - vdenv.dbClient.ExpectRequest("select * from _vt.vdiff where id = 1", controllerQR, nil) + vdenv.dbClient.ExpectRequest("select * from _vt.vdiff where id = 1 and db_name = "+encodeString(vdiffDBName), controllerQR, nil) vdenv.dbClient.ExpectRequest(fmt.Sprintf("select * from _vt.vreplication where workflow = '%s' and db_name = '%s'", vdiffenv.workflow, vdiffDBName), sqltypes.MakeTestResult(sqltypes.MakeTestFields( "id|workflow|source|pos|stop_pos|max_tps|max_replication_lag|cell|tablet_types|time_updated|transaction_timestamp|state|message|db_name|rows_copied|tags|time_heartbeat|workflow_type|time_throttled|component_throttled|workflow_sub_type|options", "int64|varbinary|blob|varbinary|varbinary|int64|int64|varbinary|varbinary|int64|int64|varbinary|varbinary|varbinary|int64|varbinary|int64|int64|int64|varchar|int64|varchar", ), fmt.Sprintf("1|%s|%s|%s||9223372036854775807|9223372036854775807||PRIMARY,REPLICA|1669511347|0|Running||%s|200||1669511347|1|0||1|{}", vdiffenv.workflow, vreplSource, vdiffSourceGtid, vdiffDBName), ), nil) - vdenv.dbClient.ExpectRequest("update _vt.vdiff set state = 'started', last_error = left('', 1024) , started_at = utc_timestamp() where id = 1", singleRowAffected, nil) + vdenv.dbClient.ExpectRequest("update _vt.vdiff set state = 'started', last_error = left('', 1024) , started_at = utc_timestamp() where id = 1 and db_name = 'vttest'", singleRowAffected, nil) vdenv.dbClient.ExpectRequest("insert into _vt.vdiff_log(vdiff_id, message) values (1, 'State changed to: started')", singleRowAffected, nil) vdenv.dbClient.ExpectRequest(`select vdt.lastpk as lastpk, vdt.mismatch as mismatch, vdt.report as report from _vt.vdiff as vd inner join _vt.vdiff_table as vdt on (vd.id = vdt.vdiff_id) @@ -193,7 +193,7 @@ func TestVDiff(t *testing.T) { vdenv.dbClient.ExpectRequest("update _vt.vdiff_table set state = 'completed' where vdiff_id = 1 and table_name = 't1'", singleRowAffected, nil) vdenv.dbClient.ExpectRequest(`insert into _vt.vdiff_log(vdiff_id, message) values (1, 'completed: table \'t1\'')`, singleRowAffected, nil) vdenv.dbClient.ExpectRequest("select table_name as table_name from _vt.vdiff_table where vdiff_id = 1 and state != 'completed' order by table_name", singleRowAffected, nil) - vdenv.dbClient.ExpectRequest("update _vt.vdiff set state = 'completed', last_error = left('', 1024) , completed_at = utc_timestamp() where id = 1", singleRowAffected, nil) + vdenv.dbClient.ExpectRequest("update _vt.vdiff set state = 'completed', last_error = left('', 1024) , completed_at = utc_timestamp() where id = 1 and db_name = 'vttest'", singleRowAffected, nil) vdenv.dbClient.ExpectRequest("insert into _vt.vdiff_log(vdiff_id, message) values (1, 'State changed to: completed')", singleRowAffected, nil) vdenv.vde.mu.Lock() @@ -243,7 +243,7 @@ func TestEngineRetryErroredVDiffs(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - vdiffenv.dbClient.ExpectRequest("select * from _vt.vdiff where state = 'error' and json_unquote(json_extract(options, '$.core_options.auto_retry')) = 'true'", tt.retryQueryResults, nil) + vdiffenv.dbClient.ExpectRequest("select * from _vt.vdiff where state = 'error' and json_unquote(json_extract(options, '$.core_options.auto_retry')) = 'true' and db_name = "+encodeString(vdiffDBName), tt.retryQueryResults, nil) // Right now this only supports a single row as with multiple rows we have // multiple controllers in separate goroutines and the order is not @@ -255,8 +255,8 @@ func TestEngineRetryErroredVDiffs(t *testing.T) { for _, row := range tt.retryQueryResults.Rows { id := row[0].ToString() if tt.expectRetry { - vdiffenv.dbClient.ExpectRequestRE("update _vt.vdiff as vd left join _vt.vdiff_table as vdt on \\(vd.id = vdt.vdiff_id\\) set vd.state = 'pending'.*", singleRowAffected, nil) - vdiffenv.dbClient.ExpectRequest(fmt.Sprintf("select * from _vt.vdiff where id = %s", id), sqltypes.MakeTestResult(sqltypes.MakeTestFields( + vdiffenv.dbClient.ExpectRequestRE("update _vt.vdiff as vd left join _vt.vdiff_table as vdt on \\(vd.id = vdt.vdiff_id\\) set vd.state = 'pending'[\\s\\S]*vd.db_name[\\s\\S]*", singleRowAffected, nil) + vdiffenv.dbClient.ExpectRequest("select * from _vt.vdiff where id = "+id+" and db_name = "+encodeString(vdiffDBName), sqltypes.MakeTestResult(sqltypes.MakeTestFields( vdiffTestCols, vdiffTestColTypes, ), @@ -270,12 +270,10 @@ func TestEngineRetryErroredVDiffs(t *testing.T) { ), nil) // At this point we know that we kicked off the expected retry so we can short circuit the vdiff. - shortCircuitTestAfterQuery(fmt.Sprintf("update _vt.vdiff set state = 'started', last_error = left('', 1024) , started_at = utc_timestamp() where id = %s", id), vdiffenv.dbClient) - + shortCircuitTestAfterQuery("update _vt.vdiff set state = 'started', last_error = left('', 1024) , started_at = utc_timestamp() where id = "+id+" and db_name = 'vttest'", vdiffenv.dbClient) expectedControllerCnt++ } } - err := vdiffenv.vde.retryVDiffs(vdiffenv.vde.ctx) assert.NoError(t, err) assert.Equal(t, expectedControllerCnt, len(vdiffenv.vde.controllers)) diff --git a/go/vt/vttablet/tabletmanager/vdiff/framework_test.go b/go/vt/vttablet/tabletmanager/vdiff/framework_test.go index 4c1c7e8f3b8..e63607b8380 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/framework_test.go +++ b/go/vt/vttablet/tabletmanager/vdiff/framework_test.go @@ -18,6 +18,7 @@ package vdiff import ( "context" + "errors" "fmt" "io" "os" @@ -210,8 +211,8 @@ func resetBinlogClient() { // This can be used to end a vdiff, by returning an error from the specified query, once the test // has verified the necessary behavior. func shortCircuitTestAfterQuery(query string, dbClient *binlogplayer.MockDBClient) { - dbClient.ExpectRequest(query, singleRowAffected, fmt.Errorf("Short circuiting test")) - dbClient.ExpectRequest("update _vt.vdiff set state = 'error', last_error = left('Short circuiting test', 1024) where id = 1", singleRowAffected, nil) + dbClient.ExpectRequest(query, singleRowAffected, errors.New("Short circuiting test")) + dbClient.ExpectRequest("update _vt.vdiff set state = 'error', last_error = left('Short circuiting test', 1024) where id = 1 and db_name = "+encodeString(vdiffDBName), singleRowAffected, nil) dbClient.ExpectRequest("insert into _vt.vdiff_log(vdiff_id, message) values (1, 'State changed to: error')", singleRowAffected, nil) dbClient.ExpectRequest("insert into _vt.vdiff_log(vdiff_id, message) values (1, 'Error: Short circuiting test')", singleRowAffected, nil) } @@ -610,7 +611,7 @@ func newTestVDiffEnv(t *testing.T) *testVDiffEnv { // vdiff.restartTargets vdiffenv.tmc.setVRResults(primary.tablet, fmt.Sprintf("update _vt.vreplication set state='Running', message='', stop_pos='' where db_name='%s' and workflow='%s'", vdiffDBName, vdiffenv.workflow), singleRowAffected) - vdiffenv.dbClient.ExpectRequest("select * from _vt.vdiff where state in ('started','pending')", noResults, nil) + vdiffenv.dbClient.ExpectRequest("select * from _vt.vdiff where state in ('started','pending') and db_name = "+encodeString(vdiffDBName), noResults, nil) vdiffenv.vde.Open(context.Background(), vdiffenv.vre) assert.True(t, vdiffenv.vde.IsOpen()) assert.Equal(t, 0, len(vdiffenv.vde.controllers)) @@ -675,7 +676,7 @@ func (tvde *testVDiffEnv) createController(t *testing.T, id int) *controller { ), fmt.Sprintf("%d|%s|%s|%s|%s|%s|%s|%s|", id, uuid.New(), tvde.workflow, tstenv.KeyspaceName, tstenv.ShardName, vdiffDBName, PendingState, optionsJS), ) - tvde.dbClient.ExpectRequest(fmt.Sprintf("select * from _vt.vdiff where id = %d", id), noResults, nil) + tvde.dbClient.ExpectRequest(fmt.Sprintf("select * from _vt.vdiff where id = %d and db_name = %s", id, encodeString(vdiffDBName)), noResults, nil) ct := tvde.newController(t, controllerQR) ct.sources = map[string]*migrationSource{ tstenv.ShardName: { diff --git a/go/vt/vttablet/tabletmanager/vdiff/schema.go b/go/vt/vttablet/tabletmanager/vdiff/schema.go index bb238cb8a7a..f87bd9cd970 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/schema.go +++ b/go/vt/vttablet/tabletmanager/vdiff/schema.go @@ -20,37 +20,37 @@ const ( sqlAnalyzeTable = "analyze table `%s`.`%s`" sqlNewVDiff = "insert into _vt.vdiff(keyspace, workflow, state, options, shard, db_name, vdiff_uuid) values(%a, %a, %a, %a, %a, %a, %a)" sqlResumeVDiff = `update _vt.vdiff as vd, _vt.vdiff_table as vdt set vd.started_at = NULL, vd.completed_at = NULL, vd.state = 'pending', - vdt.state = 'pending' where vd.vdiff_uuid = %a and vd.id = vdt.vdiff_id and vd.state in ('completed', 'stopped') + vdt.state = 'pending' where vd.vdiff_uuid = %a and vd.db_name = %a and vd.id = vdt.vdiff_id and vd.state in ('completed', 'stopped') and vdt.state in ('completed', 'stopped')` - sqlStartVDiff = `update _vt.vdiff as vd set vd.state = 'pending' where vd.vdiff_uuid = %a and vd.state = 'stopped' and + sqlStartVDiff = `update _vt.vdiff as vd set vd.state = 'pending' where vd.vdiff_uuid = %a and vd.db_name = %a and vd.state = 'stopped' and vd.started_at is NULL and vd.completed_at is NULL and (select count(*) as cnt from _vt.vdiff_table as vdt where vd.id = vdt.vdiff_id) = 0` sqlRetryVDiff = `update _vt.vdiff as vd left join _vt.vdiff_table as vdt on (vd.id = vdt.vdiff_id) set vd.state = 'pending', - vd.last_error = '', vdt.state = 'pending' where vd.id = %a and (vd.state = 'error' or vdt.state = 'error')` - sqlGetVDiffByKeyspaceWorkflowUUID = "select * from _vt.vdiff where keyspace = %a and workflow = %a and vdiff_uuid = %a" - sqlGetMostRecentVDiffByKeyspaceWorkflow = "select * from _vt.vdiff where keyspace = %a and workflow = %a order by id desc limit %a" - sqlGetVDiffByID = "select * from _vt.vdiff where id = %a" + vd.last_error = '', vdt.state = 'pending' where vd.id = %a and vd.db_name = %a and (vd.state = 'error' or vdt.state = 'error')` + sqlGetVDiffByKeyspaceWorkflowUUID = "select * from _vt.vdiff where keyspace = %a and workflow = %a and vdiff_uuid = %a and db_name = %a" + sqlGetMostRecentVDiffByKeyspaceWorkflow = "select * from _vt.vdiff where keyspace = %a and workflow = %a and db_name = %a order by id desc limit %a" + sqlGetVDiffByID = "select * from _vt.vdiff where id = %a and db_name = %a" sqlDeleteVDiffs = `delete from vd, vdt, vdl using _vt.vdiff as vd left join _vt.vdiff_table as vdt on (vd.id = vdt.vdiff_id) left join _vt.vdiff_log as vdl on (vd.id = vdl.vdiff_id) - where vd.keyspace = %a and vd.workflow = %a` + where vd.keyspace = %a and vd.workflow = %a and vd.db_name = %a` sqlDeleteVDiffByUUID = `delete from vd, vdt using _vt.vdiff as vd left join _vt.vdiff_table as vdt on (vd.id = vdt.vdiff_id) - where vd.vdiff_uuid = %a` + where vd.vdiff_uuid = %a and vd.db_name = %a` sqlVDiffSummary = `select vd.state as vdiff_state, vd.last_error as last_error, vdt.table_name as table_name, vd.vdiff_uuid as 'uuid', vdt.state as table_state, vdt.table_rows as table_rows, vd.started_at as started_at, vdt.rows_compared as rows_compared, vd.completed_at as completed_at, IF(vdt.mismatch = 1, 1, 0) as has_mismatch, vdt.report as report from _vt.vdiff as vd left join _vt.vdiff_table as vdt on (vd.id = vdt.vdiff_id) - where vd.id = %a` + where vd.id = %a and vd.db_name = %a` // sqlUpdateVDiffState has a penultimate placeholder for any additional columns you want to update, e.g. `, foo = 1`. // It also truncates the error if needed to ensure that we can save the state when the error text is very long. - sqlUpdateVDiffState = "update _vt.vdiff set state = %s, last_error = left(%s, 1024) %s where id = %d" + sqlUpdateVDiffState = "update _vt.vdiff set state = %s, last_error = left(%s, 1024) %s where id = %d and db_name = %s" sqlUpdateVDiffStopped = `update _vt.vdiff as vd, _vt.vdiff_table as vdt set vd.state = 'stopped', vdt.state = 'stopped', vd.last_error = '' - where vd.id = vdt.vdiff_id and vd.id = %a and vd.state != 'completed'` - sqlGetVReplicationEntry = "select * from _vt.vreplication %s" // A filter/where is added by the caller - sqlGetVDiffsToRun = "select * from _vt.vdiff where state in ('started','pending')" // what VDiffs have not been stopped or completed - sqlGetVDiffsToRetry = "select * from _vt.vdiff where state = 'error' and json_unquote(json_extract(options, '$.core_options.auto_retry')) = 'true'" - sqlGetVDiffID = "select id as id from _vt.vdiff where vdiff_uuid = %a" - sqlGetVDiffIDsByKeyspaceWorkflow = "select id as id from _vt.vdiff where keyspace = %a and workflow = %a" + where vd.id = vdt.vdiff_id and vd.id = %a and vd.db_name = %a and vd.state != 'completed'` + sqlGetVReplicationEntry = "select * from _vt.vreplication %s" // A filter/where is added by the caller + sqlGetVDiffsToRun = "select * from _vt.vdiff where state in ('started','pending') and db_name = %a" // what VDiffs have not been stopped or completed + sqlGetVDiffsToRetry = "select * from _vt.vdiff where state = 'error' and json_unquote(json_extract(options, '$.core_options.auto_retry')) = 'true' and db_name = %a" + sqlGetVDiffID = "select id as id from _vt.vdiff where vdiff_uuid = %a and db_name = %a" + sqlGetVDiffIDsByKeyspaceWorkflow = "select id as id from _vt.vdiff where keyspace = %a and workflow = %a and db_name = %a" sqlGetTableRows = "select table_rows as table_rows from INFORMATION_SCHEMA.TABLES where table_schema = %a and table_name = %a" sqlGetAllTableRows = "select table_name as table_name, table_rows as table_rows from INFORMATION_SCHEMA.TABLES where table_schema = %s and table_name in (%s) order by table_name" diff --git a/go/vt/vttablet/tabletmanager/vdiff/workflow_differ_test.go b/go/vt/vttablet/tabletmanager/vdiff/workflow_differ_test.go index 591acc756e8..6ece3dc83f6 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/workflow_differ_test.go +++ b/go/vt/vttablet/tabletmanager/vdiff/workflow_differ_test.go @@ -58,7 +58,7 @@ func TestReconcileExtraRows(t *testing.T) { fmt.Sprintf("1|%s|%s|%s|%s|%s|%s|%s|", UUID, vdiffenv.workflow, tstenv.KeyspaceName, tstenv.ShardName, vdiffDBName, PendingState, optionsJS), ) - vdiffenv.dbClient.ExpectRequest("select * from _vt.vdiff where id = 1", noResults, nil) + vdiffenv.dbClient.ExpectRequest("select * from _vt.vdiff where id = 1 and db_name = "+encodeString(vdiffDBName), noResults, nil) ct := vdenv.newController(t, controllerQR) wd, err := newWorkflowDiffer(ct, vdiffenv.opts, collations.MySQL8()) require.NoError(t, err) @@ -316,7 +316,7 @@ func TestReconcileReferenceTables(t *testing.T) { fmt.Sprintf("1|%s|%s|%s|%s|%s|%s|%s|", UUID, vdiffenv.workflow, tstenv.KeyspaceName, tstenv.ShardName, vdiffDBName, PendingState, optionsJS), ) - vdiffenv.dbClient.ExpectRequest("select * from _vt.vdiff where id = 1", noResults, nil) + vdiffenv.dbClient.ExpectRequest("select * from _vt.vdiff where id = 1 and db_name = "+encodeString(vdiffDBName), noResults, nil) ct := vdenv.newController(t, controllerQR) ct.sourceKeyspace = tstenv.KeyspaceName wd, err := newWorkflowDiffer(ct, vdiffenv.opts, collations.MySQL8()) @@ -427,7 +427,7 @@ func TestBuildPlanSuccess(t *testing.T) { fmt.Sprintf("1|%s|%s|%s|%s|%s|%s|%s|", UUID, vdiffenv.workflow, tstenv.KeyspaceName, tstenv.ShardName, vdiffDBName, PendingState, optionsJS), ) - vdiffenv.dbClient.ExpectRequest("select * from _vt.vdiff where id = 1", noResults, nil) + vdiffenv.dbClient.ExpectRequest("select * from _vt.vdiff where id = 1 and db_name = "+encodeString(vdiffDBName), noResults, nil) ct := vdenv.newController(t, controllerQR) ct.sources = map[string]*migrationSource{ tstenv.ShardName: { @@ -1075,7 +1075,7 @@ func TestBuildPlanFailure(t *testing.T) { ), fmt.Sprintf("1|%s|%s|%s|%s|%s|%s|%s|", UUID, vdiffenv.workflow, tstenv.KeyspaceName, tstenv.ShardName, vdiffDBName, PendingState, optionsJS), ) - vdiffenv.dbClient.ExpectRequest("select * from _vt.vdiff where id = 1", noResults, nil) + vdiffenv.dbClient.ExpectRequest("select * from _vt.vdiff where id = 1 and db_name = "+encodeString(vdiffDBName), noResults, nil) ct := vdenv.newController(t, controllerQR) testcases := []struct { input *binlogdatapb.Rule From d5a7039e375d564257aeed1f8413c392272eb8f8 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 19:27:56 -0500 Subject: [PATCH 067/112] [release-22.0] CI: Use larger runners for vreplication workflows (#19433) (#19434) Signed-off-by: Matt Lord Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- test/config.json | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/test/config.json b/test/config.json index fb111c47bef..0635dc4bd6c 100644 --- a/test/config.json +++ b/test/config.json @@ -1282,7 +1282,9 @@ "Manual": false, "Shard": "vtgate_transaction", "Tags": [], - "Needs": [], + "Needs": [ + "larger-runner" + ], "BuildTag": "debug2PC" }, "vtgate_transaction_restart": { @@ -1373,7 +1375,9 @@ "Manual": false, "Shard": "vtgate_transaction", "Tags": [], - "Needs": [], + "Needs": [ + "larger-runner" + ], "BuildTag": "debug2PC" }, "vtgate_transaction_partial_exec": { @@ -1697,6 +1701,7 @@ "Shard": "vreplication_partial_movetables_and_materialize", "Tags": [], "Needs": [ + "larger-runner", "limit-resources", "binlog-compression" ] @@ -1715,6 +1720,7 @@ "Shard": "vreplication_partial_movetables_and_materialize", "Tags": [], "Needs": [ + "larger-runner", "limit-resources", "binlog-compression" ] @@ -1733,6 +1739,7 @@ "Shard": "vreplication_cellalias", "Tags": [], "Needs": [ + "larger-runner", "limit-resources", "binlog-compression" ] @@ -1751,6 +1758,7 @@ "Shard": "vreplication_cellalias", "Tags": [], "Needs": [ + "larger-runner", "limit-resources", "binlog-compression" ] @@ -1769,6 +1777,7 @@ "Shard": "vreplication_multi_tenant", "Tags": [], "Needs": [ + "larger-runner", "limit-resources", "binlog-compression" ] @@ -1787,6 +1796,7 @@ "Shard": "vreplication_partial_movetables_and_materialize", "Tags": [], "Needs": [ + "larger-runner", "limit-resources", "binlog-compression" ] @@ -1805,6 +1815,7 @@ "Shard": "vreplication_partial_movetables_and_materialize", "Tags": [], "Needs": [ + "larger-runner", "limit-resources", "binlog-compression" ] @@ -1823,6 +1834,7 @@ "Shard": "vreplication_cellalias", "Tags": [], "Needs": [ + "larger-runner", "limit-resources", "binlog-compression" ] @@ -1841,6 +1853,7 @@ "Shard": "vreplication_cellalias", "Tags": [], "Needs": [ + "larger-runner", "limit-resources", "binlog-compression" ] @@ -1859,6 +1872,7 @@ "Shard": "vreplication_cellalias", "Tags": [], "Needs": [ + "larger-runner", "limit-resources", "binlog-compression" ] @@ -1917,6 +1931,7 @@ "Shard": "vreplication_copy_parallel", "Tags": [], "Needs": [ + "larger-runner", "limit-resources", "binlog-compression" ] @@ -1935,6 +1950,7 @@ "Shard": "vreplication_partial_movetables_and_materialize", "Tags": [], "Needs": [ + "larger-runner", "limit-resources", "binlog-compression" ] @@ -1953,6 +1969,7 @@ "Shard": "vreplication_partial_movetables_and_materialize", "Tags": [], "Needs": [ + "larger-runner", "limit-resources", "binlog-compression" ] @@ -2076,6 +2093,7 @@ "Shard": "vtorc", "Tags": [], "Needs": [ + "larger-runner", "memory-check" ] }, @@ -2151,6 +2169,7 @@ "Shard": "vreplication_v2", "Tags": [], "Needs": [ + "larger-runner", "limit-resources", "binlog-compression" ] @@ -2189,6 +2208,7 @@ "Shard": "vreplication_cellalias", "Tags": [], "Needs": [ + "larger-runner", "limit-resources", "binlog-compression" ] @@ -2207,6 +2227,7 @@ "Shard": "vreplication_foreign_key_stress", "Tags": [], "Needs": [ + "larger-runner", "limit-resources", "binlog-compression" ] @@ -2227,6 +2248,7 @@ "Shard": "vreplication_across_db_versions", "Tags": [], "Needs": [ + "larger-runner", "limit-resources", "binlog-compression" ] From b86c7016d0076eb106f18e7b8cc02c1e6133e5c0 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 18:03:23 +0000 Subject: [PATCH 068/112] [release-22.0] Address a few VDiff concerns (#19413) (#19447) Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Mohamed Hamza --- .../tabletmanager/vdiff/controller.go | 5 +- .../tabletmanager/vdiff/framework_test.go | 3 ++ .../tabletmanager/vdiff/table_differ.go | 24 ++++++---- .../tabletserver/vstreamer/snapshot_conn.go | 9 ++++ .../vstreamer/snapshot_conn_test.go | 48 +++++++++++++++++++ 5 files changed, 78 insertions(+), 11 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vdiff/controller.go b/go/vt/vttablet/tabletmanager/vdiff/controller.go index 0ce41a64c86..a0acdc98c4c 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/controller.go +++ b/go/vt/vttablet/tabletmanager/vdiff/controller.go @@ -114,8 +114,11 @@ func (ct *controller) Stop() { func (ct *controller) run(ctx context.Context) { defer func() { - log.Infof("Run finished for vdiff %s", ct.uuid) + log.Info("Run finished for vdiff " + ct.uuid) + // Unblock Stop() callers waiting on <-ct.done. close(ct.done) + // Release gRPC connections held by this controller's tablet manager client. + ct.tmc.Close() }() dbClient := ct.vde.dbClientFactoryFiltered() diff --git a/go/vt/vttablet/tabletmanager/vdiff/framework_test.go b/go/vt/vttablet/tabletmanager/vdiff/framework_test.go index e63607b8380..5c8d336929f 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/framework_test.go +++ b/go/vt/vttablet/tabletmanager/vdiff/framework_test.go @@ -456,6 +456,9 @@ func newFakeTMClient() *fakeTMClient { } } +// Close satisfies the TabletManagerClient interface. +func (tmc *fakeTMClient) Close() {} + func (tmc *fakeTMClient) GetSchema(ctx context.Context, tablet *topodatapb.Tablet, request *tabletmanagerdatapb.GetSchemaRequest) (*tabletmanagerdatapb.SchemaDefinition, error) { return tmc.schema, nil } diff --git a/go/vt/vttablet/tabletmanager/vdiff/table_differ.go b/go/vt/vttablet/tabletmanager/vdiff/table_differ.go index f63fced008d..2411288f50c 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/table_differ.go +++ b/go/vt/vttablet/tabletmanager/vdiff/table_differ.go @@ -398,15 +398,14 @@ func (td *tableDiffer) restartTargetVReplicationStreams(ctx context.Context) err func (td *tableDiffer) streamOneShard(ctx context.Context, participant *shardStreamer, query string, lastPK *querypb.QueryResult, gtidch chan string) { log.Infof("streamOneShard Start on %s using query: %s", participant.tablet.Alias.String(), query) td.wgShardStreamers.Add(1) + resultch := participant.result defer func() { - log.Infof("streamOneShard End on %s", participant.tablet.Alias.String()) - select { - case <-ctx.Done(): - default: - close(participant.result) - close(gtidch) - } + log.Info("streamOneShard End on " + participant.tablet.Alias.String()) + + close(resultch) + close(gtidch) + td.wgShardStreamers.Done() }() @@ -455,7 +454,7 @@ func (td *tableDiffer) streamOneShard(ctx context.Context, participant *shardStr result.Fields = nil } select { - case participant.result <- result: + case resultch <- result: case <-ctx.Done(): return vterrors.Wrap(ctx.Err(), "VStreamRows") case <-td.wd.ct.done: @@ -529,8 +528,13 @@ func (td *tableDiffer) diff(ctx context.Context, coreOpts *tabletmanagerdatapb.V } dr.TableName = td.table.Name - sourceExecutor := newPrimitiveExecutor(ctx, td.sourcePrimitive, "source") - targetExecutor := newPrimitiveExecutor(ctx, td.targetPrimitive, "target") + // Scope executor goroutines to this single diff attempt, rather + // than surviving until the controller context is canceled. + execCtx, cancelExec := context.WithCancel(ctx) + defer cancelExec() + + sourceExecutor := newPrimitiveExecutor(execCtx, td.sourcePrimitive, "source") + targetExecutor := newPrimitiveExecutor(execCtx, td.targetPrimitive, "target") var sourceRow, lastProcessedRow, targetRow []sqltypes.Value advanceSource := true advanceTarget := true diff --git a/go/vt/vttablet/tabletserver/vstreamer/snapshot_conn.go b/go/vt/vttablet/tabletserver/vstreamer/snapshot_conn.go index ee141ce9859..45fd2d5af8d 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/snapshot_conn.go +++ b/go/vt/vttablet/tabletserver/vstreamer/snapshot_conn.go @@ -36,6 +36,9 @@ import ( vttablet "vitess.io/vitess/go/vt/vttablet/common" ) +// snapshotLockWaitTimeout is the lock_wait_timeout to use when attempting to start a snapshot. +var snapshotLockWaitTimeout = 30 * time.Second + // snapshotConn is wrapper on mysql.Conn capable of // reading a table along with a GTID snapshot. type snapshotConn struct { @@ -109,6 +112,12 @@ func (conn *snapshotConn) startSnapshot(ctx context.Context, table string) (gtid tableName := sqlparser.String(sqlparser.NewIdentifierCS(table)) + // Avoid waiting indefinitely when table metadata locks are held by another transaction. + lockWaitTimeoutSeconds := int(snapshotLockWaitTimeout.Seconds()) + if _, err := lockConn.ExecuteFetch(fmt.Sprintf("set session lock_wait_timeout = %d", lockWaitTimeoutSeconds), 1, false); err != nil { + return "", vterrors.Wrapf(err, "startSnapshot: failed to set session lock_wait_timeout = %d for table %s", lockWaitTimeoutSeconds, tableName) + } + if _, err := lockConn.ExecuteFetch(fmt.Sprintf("lock tables %s read", tableName), 1, false); err != nil { log.Warningf("Error locking table %s to read: %v", tableName, err) return "", err diff --git a/go/vt/vttablet/tabletserver/vstreamer/snapshot_conn_test.go b/go/vt/vttablet/tabletserver/vstreamer/snapshot_conn_test.go index cc0899bc14b..0b5eaf82500 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/snapshot_conn_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/snapshot_conn_test.go @@ -18,7 +18,9 @@ package vstreamer import ( "context" + "fmt" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -59,3 +61,49 @@ func TestStartSnapshot(t *testing.T) { require.NoError(t, err) assert.Equal(t, wantqr, qr) } + +// TestStartSnapshotLock validates startSnapshot does not hang indefinitely when waiting on a metadata lock. +func TestStartSnapshotLock(t *testing.T) { + if testing.Short() { + t.Skip() + } + + const tableName = "t1_lock_wait_timeout" + const shortLockWaitTimeout = time.Second + + // Seed one row so the table can be locked and queried. + execStatements(t, []string{ + fmt.Sprintf("create table %s(id int, val varbinary(128), primary key(id))", tableName), + fmt.Sprintf("insert into %s values (1, 'aaa')", tableName), + }) + t.Cleanup(func() { execStatements(t, []string{"drop table " + tableName}) }) + + // Shorten the configured snapshot lock wait timeout for this test only. + originalLockWaitTimeout := snapshotLockWaitTimeout + snapshotLockWaitTimeout = shortLockWaitTimeout + t.Cleanup(func() { snapshotLockWaitTimeout = originalLockWaitTimeout }) + + ctx := t.Context() + + // Open a second connection that will hold the metadata lock. + lockHolderConn, err := mysqlConnect(ctx, env.TabletEnv.Config().DB.AppWithDB()) + require.NoError(t, err) + t.Cleanup(func() { lockHolderConn.Close() }) + + _, err = lockHolderConn.ExecuteFetch("begin", 1, false) + require.NoError(t, err) + + _, err = lockHolderConn.ExecuteFetch(fmt.Sprintf("update %s set val = 'blocked' where id = 1", tableName), 1, false) + require.NoError(t, err) + + conn, err := snapshotConnect(ctx, env.TabletEnv.Config().DB.AppWithDB()) + require.NoError(t, err) + t.Cleanup(func() { conn.Close() }) + + // Attempt to start the snapshot while the metadata lock is still held. + _, err = conn.startSnapshot(ctx, tableName) + + // Confirm we fail with the expected lock wait timeout error. + require.Error(t, err) + require.ErrorContains(t, err, "Lock wait timeout exceeded") +} From 02f50cd5b5f06c472559d121bfd7d8b43d4ecd5f Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 20:37:40 +0000 Subject: [PATCH 069/112] [release-22.0] Normalize the --on-ddl param for MoveTables (#19445) (#19451) Signed-off-by: Cheng Yuan Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- .../command/vreplication/common/utils.go | 4 +- .../command/vreplication/common/utils_test.go | 42 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/go/cmd/vtctldclient/command/vreplication/common/utils.go b/go/cmd/vtctldclient/command/vreplication/common/utils.go index ff6d264be66..d6e2a3fae76 100644 --- a/go/cmd/vtctldclient/command/vreplication/common/utils.go +++ b/go/cmd/vtctldclient/command/vreplication/common/utils.go @@ -190,9 +190,11 @@ func ParseTableMaterializeSettings(tableSettings string, parser *sqlparser.Parse } func validateOnDDL(cmd *cobra.Command) error { - if _, ok := binlogdatapb.OnDDLAction_value[strings.ToUpper(CreateOptions.OnDDL)]; !ok { + normalized := strings.ToUpper(CreateOptions.OnDDL) + if _, ok := binlogdatapb.OnDDLAction_value[normalized]; !ok { return fmt.Errorf("invalid on-ddl value: %s", CreateOptions.OnDDL) } + CreateOptions.OnDDL = normalized return nil } diff --git a/go/cmd/vtctldclient/command/vreplication/common/utils_test.go b/go/cmd/vtctldclient/command/vreplication/common/utils_test.go index 39de482da2c..5768a4f00bb 100644 --- a/go/cmd/vtctldclient/command/vreplication/common/utils_test.go +++ b/go/cmd/vtctldclient/command/vreplication/common/utils_test.go @@ -110,6 +110,48 @@ func TestParseAndValidateCreateOptions(t *testing.T) { require.Equal(t, cells, common.CreateOptions.Cells) }, }, + { + name: "invalid on-ddl value", + setFunc: func(cmd *cobra.Command) error { + onDDLFlag := cmd.Flags().Lookup("on-ddl") + if err := onDDLFlag.Value.Set("INVALID"); err != nil { + return err + } + onDDLFlag.Changed = true + return nil + }, + wantErr: true, + }, + { + name: "valid on-ddl normalizes to uppercase", + setFunc: func(cmd *cobra.Command) error { + onDDLFlag := cmd.Flags().Lookup("on-ddl") + if err := onDDLFlag.Value.Set("exec"); err != nil { + return err + } + onDDLFlag.Changed = true + return nil + }, + wantErr: false, + checkFunc: func() { + require.Equal(t, "EXEC", common.CreateOptions.OnDDL) + }, + }, + { + name: "valid on-ddl EXEC_IGNORE", + setFunc: func(cmd *cobra.Command) error { + onDDLFlag := cmd.Flags().Lookup("on-ddl") + if err := onDDLFlag.Value.Set("exec_ignore"); err != nil { + return err + } + onDDLFlag.Changed = true + return nil + }, + wantErr: false, + checkFunc: func() { + require.Equal(t, "EXEC_IGNORE", common.CreateOptions.OnDDL) + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From b91ea326657159e94115b959197f6b5fb7999d07 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 22:47:59 +0000 Subject: [PATCH 070/112] [release-22.0] vtorc: Add a timeout to `DemotePrimary` RPC (#19432) (#19449) Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Mohamed Hamza --- go/test/endtoend/vtorc/general/vtorc_test.go | 92 ++++++++++++++++++++ go/test/endtoend/vtorc/utils/utils.go | 58 +++++------- go/vt/vtorc/logic/topology_recovery.go | 44 ++++++++-- 3 files changed, 151 insertions(+), 43 deletions(-) diff --git a/go/test/endtoend/vtorc/general/vtorc_test.go b/go/test/endtoend/vtorc/general/vtorc_test.go index b713a65dba2..2d50aa2030a 100644 --- a/go/test/endtoend/vtorc/general/vtorc_test.go +++ b/go/test/endtoend/vtorc/general/vtorc_test.go @@ -472,6 +472,98 @@ func TestStalePrimary(t *testing.T) { }, 30*time.Second, time.Second, "expected demotion to REPLICA with read_only=ON") } +// TestDemotePrimaryHang tests that when the `DemotePrimary` RPC hangs, VTOrc is not indefinitely blocked +// on future recoveries. +func TestDemotePrimaryHang(t *testing.T) { + ctx := t.Context() + + utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 4, 0, []string{"--topo-information-refresh-duration", "1s"}, cluster.VTOrcConfiguration{ + PreventCrossCellFailover: true, + }, 1, policy.DurabilitySemiSync) + + keyspace := &clusterInfo.ClusterInstance.Keyspaces[0] + shard0 := &keyspace.Shards[0] + vtorc := clusterInfo.ClusterInstance.VTOrcProcesses[0] + + curPrimary := utils.ShardPrimaryTablet(t, clusterInfo, keyspace, shard0) + require.NotNil(t, curPrimary, "expected VTOrc to elect an initial primary") + + var stalePrimary *cluster.Vttablet + var blockedReplica *cluster.Vttablet + var healthyReplica *cluster.Vttablet + + for _, tablet := range shard0.Vttablets { + if tablet.Alias == curPrimary.Alias { + continue + } + + if stalePrimary == nil { + stalePrimary = tablet + continue + } + + if blockedReplica == nil { + blockedReplica = tablet + continue + } + + healthyReplica = tablet + } + + require.NotNil(t, stalePrimary, "expected a candidate tablet to mark as stale topo primary") + require.NotNil(t, blockedReplica, "expected a second replica to inject a separate failure") + require.NotNil(t, healthyReplica, "expected a healthy replica to keep normal replication coverage") + + utils.CheckReplication(t, clusterInfo, curPrimary, []*cluster.Vttablet{stalePrimary, blockedReplica, healthyReplica}, 15*time.Second) + + // Hold the stale primary candidate's action queue for a long time. This guarantees that VTOrc's + // DemotePrimary RPC will block on the tablet lock. + sleepDuration := 90 * time.Second + go func() { + clusterInfo.ClusterInstance.VtctldClientProcess.ExecuteCommandWithOutput( + "SleepTablet", + stalePrimary.Alias, + sleepDuration.String(), + ) + }() + + // Make the tablet a stale primary by updating its type to PRIMARY and primary term start time + // to an older time than the current primary. This will trigger the StaleTopoPrimary recovery. + err := utils.RunSQLs(t, []string{"SET GLOBAL read_only = OFF"}, stalePrimary, "") + require.NoError(t, err) + + _, err = clusterInfo.Ts.UpdateTabletFields(ctx, stalePrimary.GetAlias(), func(tablet *topodatapb.Tablet) error { + tablet.Type = topodatapb.TabletType_PRIMARY + tablet.PrimaryTermStartTime = protoutil.TimeToProto(time.Now().Add(-1 * time.Minute)) + return nil + }) + require.NoError(t, err) + + // Wait until VTOrc has detected the stale topo primary. + utils.WaitForDetectedProblems(t, vtorc, string(inst.StaleTopoPrimary), stalePrimary.Alias, keyspace.Name, shard0.Name, 1) + + // Inject a second problem on a different replica while the stale-primary recovery is still hanging. + _, err = clusterInfo.ClusterInstance.VtctldClientProcess.ExecuteCommandWithOutput("StopReplication", blockedReplica.Alias) + require.NoError(t, err) + + utils.WaitForDetectedProblems(t, vtorc, string(inst.ReplicationStopped), blockedReplica.Alias, keyspace.Name, shard0.Name, 1) + + // If DemotePrimary is properly bounded by a context timeout, the stale primary recovery should + // fail, close the recovery row, and unblock the shard for further recoveries. + assert.EventuallyWithT(t, func(c *assert.CollectT) { + vars := vtorc.GetVars() + recoveries, ok := vars["RecoveriesCount"].(map[string]any) + require.True(c, ok, "RecoveriesCount metric not yet available") + + mapKey := logic.DemoteStaleTopoPrimaryRecoveryName + count := utils.GetIntFromValue(recoveries[mapKey]) + assert.GreaterOrEqual(c, count, 1) + }, 30*time.Second, time.Second, "expected VTOrc to attempt stale primary recovery") + + // The FixReplica recovery should run once the stale primary recovery unblocks the shard. + utils.WaitForSuccessfulRecoveryCount(t, vtorc, logic.FixReplicaRecoveryName, 1) +} + // TestSemiSync tests that semi-sync is setup correctly by vtorc if it is incorrectly set func TestSemiSync(t *testing.T) { // stop any vtorc instance running due to a previous test. diff --git a/go/test/endtoend/vtorc/utils/utils.go b/go/test/endtoend/vtorc/utils/utils.go index 34ef326535b..8ab20e82ab8 100644 --- a/go/test/endtoend/vtorc/utils/utils.go +++ b/go/test/endtoend/vtorc/utils/utils.go @@ -141,7 +141,7 @@ func createVttablets(clusterInstance *cluster.LocalProcessCluster, cellInfos []* if err != nil { return err } - //Start MySql + // Start MySql var mysqlCtlProcessList []*exec.Cmd for _, tablet := range shard0.Vttablets { log.Infof("Starting MySql for tablet %v", tablet.Alias) @@ -591,7 +591,7 @@ func RunSQL(t *testing.T, sql string, tablet *cluster.Vttablet, db string) (*sql func RunSQLs(t *testing.T, sqls []string, tablet *cluster.Vttablet, db string) error { // Get Connection tabletParams := getMysqlConnParam(tablet, db) - var timeoutDuration = time.Duration(5 * len(sqls)) + timeoutDuration := time.Duration(5 * len(sqls)) ctx, cancel := context.WithTimeout(context.Background(), timeoutDuration*time.Second) defer cancel() conn, err := mysql.Connect(ctx, &tabletParams) @@ -614,7 +614,6 @@ func execute(t *testing.T, conn *mysql.Conn, query string) (*sqltypes.Result, er // StartVttablet is used to start a vttablet from the given cell and type func StartVttablet(t *testing.T, clusterInfo *VTOrcClusterInfo, cell string, isRdonly bool) *cluster.Vttablet { - var tablet *cluster.Vttablet for _, cellInfo := range clusterInfo.CellInfos { if cellInfo.CellName == cell { @@ -818,7 +817,7 @@ func SetupNewClusterSemiSync(t *testing.T) *VTOrcClusterInfo { err = clusterInstance.SetupCluster(keyspace, []cluster.Shard{*shard}) require.NoError(t, err, "Cannot launch cluster: %v", err) - //Start MySql + // Start MySql var mysqlCtlProcessList []*exec.Cmd for _, shard := range clusterInstance.Keyspaces[0].Shards { for _, tablet := range shard.Vttablets { @@ -892,7 +891,7 @@ func AddSemiSyncKeyspace(t *testing.T, clusterInfo *VTOrcClusterInfo) { err := clusterInfo.ClusterInstance.SetupCluster(keyspace, []cluster.Shard{*shard}) require.NoError(t, err, "Cannot launch cluster: %v", err) - //Start MySql + // Start MySql var mysqlCtlProcessList []*exec.Cmd for _, shard := range clusterInfo.ClusterInstance.Keyspaces[1].Shards { for _, tablet := range shard.Vttablets { @@ -994,7 +993,8 @@ func WaitForSuccessfulRecoveryCount(t *testing.T, vtorcInstance *cluster.VTOrcPr startTime := time.Now() for time.Since(startTime) < timeout { vars := vtorcInstance.GetVars() - successfulRecoveriesMap := vars["SuccessfulRecoveries"].(map[string]interface{}) + successfulRecoveriesMap, ok := vars["SuccessfulRecoveries"].(map[string]any) + require.True(t, ok, "SuccessfulRecoveries metric not yet available") successCount := GetIntFromValue(successfulRecoveriesMap[recoveryName]) if successCount == countExpected { return @@ -1002,7 +1002,8 @@ func WaitForSuccessfulRecoveryCount(t *testing.T, vtorcInstance *cluster.VTOrcPr time.Sleep(time.Second) } vars := vtorcInstance.GetVars() - successfulRecoveriesMap := vars["SuccessfulRecoveries"].(map[string]interface{}) + successfulRecoveriesMap, ok := vars["SuccessfulRecoveries"].(map[string]any) + require.True(t, ok, "SuccessfulRecoveries metric not yet available") successCount := GetIntFromValue(successfulRecoveriesMap[recoveryName]) assert.EqualValues(t, countExpected, successCount) } @@ -1083,33 +1084,22 @@ func WaitForDetectedProblems(t *testing.T, vtorcInstance *cluster.VTOrcProcess, t.Helper() key := strings.Join([]string{code, alias, ks, shard}, ".") timeout := 15 * time.Second - startTime := time.Now() - - for time.Since(startTime) < timeout { + require.EventuallyWithT(t, func(c *assert.CollectT) { vars := vtorcInstance.GetVars() - problems := vars["DetectedProblems"].(map[string]interface{}) - actual := GetIntFromValue(problems[key]) - if actual == expect { - return - } - time.Sleep(time.Second) - } - - vars := vtorcInstance.GetVars() - problems := vars["DetectedProblems"].(map[string]interface{}) - actual, ok := problems[key] - actual = GetIntFromValue(actual) - - assert.True(t, ok, - "The metric DetectedProblems[%s] should exist but does not (all problems: %+v)", - key, problems, - ) - - assert.EqualValues(t, expect, actual, - "The metric DetectedProblems[%s] should be %v but is %v (all problems: %+v)", - key, expect, actual, - problems, - ) + problems, ok := vars["DetectedProblems"].(map[string]any) + require.True(c, ok, "DetectedProblems metric not yet available") + actual, ok := problems[key] + actual = GetIntFromValue(actual) + require.True(c, ok, + "The metric DetectedProblems[%s] should exist but does not (all problems: %+v)", + key, problems, + ) + require.EqualValues(c, expect, actual, + "The metric DetectedProblems[%s] should be %v but is %v (all problems: %+v)", + key, expect, actual, + problems, + ) + }, timeout, time.Second, "timed out waiting for detected problem(s)") } // WaitForTabletType waits for the tablet to reach a certain type. @@ -1123,7 +1113,7 @@ func WaitForTabletType(t *testing.T, tablet *cluster.Vttablet, expectedTabletTyp // It expects to find minimum occurrence or exact count of `keyName` provided. func WaitForInstancePollSecondsExceededCount(t *testing.T, vtorcInstance *cluster.VTOrcProcess, keyName string, minCountExpected float64, enforceEquality bool) { t.Helper() - var sinceInSeconds = 30 + sinceInSeconds := 30 duration := time.Duration(sinceInSeconds) time.Sleep(duration * time.Second) diff --git a/go/vt/vtorc/logic/topology_recovery.go b/go/vt/vtorc/logic/topology_recovery.go index 8d9ee006065..60dc40e11e4 100644 --- a/go/vt/vtorc/logic/topology_recovery.go +++ b/go/vt/vtorc/logic/topology_recovery.go @@ -29,7 +29,9 @@ import ( "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/logutil" logutilpb "vitess.io/vitess/go/vt/proto/logutil" + replicationdatapb "vitess.io/vitess/go/vt/proto/replicationdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/vtctl/reparentutil" "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" @@ -244,7 +246,9 @@ func recoverPrimaryHasPrimary(ctx context.Context, analysisEntry *inst.Replicati // This has to be done in the end; whether successful or not, we should mark that the recovery is done. // So that after the active period passes, we are able to run other recoveries. defer func() { - _ = resolveRecovery(topologyRecovery, nil) + if err := resolveRecovery(topologyRecovery, nil); err != nil { + logger.Errorf("failed to resolve recovery for %q: %v", RecoverPrimaryHasPrimaryRecoveryName, err) + } }() // Read the tablet information from the database to find the shard and keyspace of the tablet @@ -281,7 +285,9 @@ func runEmergencyReparentOp(ctx context.Context, analysisEntry *inst.Replication // This has to be done in the end; whether successful or not, we should mark that the recovery is done. // So that after the active period passes, we are able to run other recoveries. defer func() { - _ = resolveRecovery(topologyRecovery, promotedReplica) + if err := resolveRecovery(topologyRecovery, promotedReplica); err != nil { + logger.Errorf("failed to resolve recovery for %q: %v", recoveryName, err) + } }() ev, err := reparentutil.NewEmergencyReparenter(ts, tmc, logutil.NewCallbackLogger(func(event *logutilpb.Event) { @@ -777,7 +783,9 @@ func electNewPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysi // This has to be done in the end; whether successful or not, we should mark that the recovery is done. // So that after the active period passes, we are able to run other recoveries. defer func() { - _ = resolveRecovery(topologyRecovery, promotedReplica) + if err := resolveRecovery(topologyRecovery, promotedReplica); err != nil { + logger.Errorf("failed to resolve recovery for %q: %v", ElectNewPrimaryRecoveryName, err) + } }() analyzedTablet, err := inst.ReadTablet(analysisEntry.AnalyzedInstanceAlias) @@ -827,7 +835,9 @@ func fixPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, lo // This has to be done in the end; whether successful or not, we should mark that the recovery is done. // So that after the active period passes, we are able to run other recoveries. defer func() { - _ = resolveRecovery(topologyRecovery, nil) + if err := resolveRecovery(topologyRecovery, nil); err != nil { + logger.Errorf("failed to resolve recovery for %q: %v", FixPrimaryRecoveryName, err) + } }() analyzedTablet, err := inst.ReadTablet(analysisEntry.AnalyzedInstanceAlias) @@ -861,7 +871,9 @@ func fixReplica(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, lo // This has to be done in the end; whether successful or not, we should mark that the recovery is done. // So that after the active period passes, we are able to run other recoveries. defer func() { - _ = resolveRecovery(topologyRecovery, nil) + if err := resolveRecovery(topologyRecovery, nil); err != nil { + logger.Errorf("failed to resolve recovery for %q: %v", FixReplicaRecoveryName, err) + } }() analyzedTablet, err := inst.ReadTablet(analysisEntry.AnalyzedInstanceAlias) @@ -896,6 +908,8 @@ func fixReplica(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, lo // been elected. It demotes the tablet, updates its type to REPLICA in the topology, and sets its replication source // to the current primary. func demoteStaleTopoPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { + alias := analysisEntry.AnalyzedInstanceAlias + // Register the recovery before touching topology so multiple VTOrc instances do not race the demotion. topologyRecovery, err = AttemptRecoveryRegistration(analysisEntry) if topologyRecovery == nil { @@ -909,10 +923,12 @@ func demoteStaleTopoPrimary(ctx context.Context, analysisEntry *inst.Replication // This has to be done in the end; whether successful or not, we should mark that the recovery is done. // So that after the active period passes, we are able to run other recoveries. defer func() { - _ = resolveRecovery(topologyRecovery, nil) + if err := resolveRecovery(topologyRecovery, nil); err != nil { + logger.Errorf("failed to resolve recovery for %q: %v", DemoteStaleTopoPrimaryRecoveryName, err) + } }() - analyzedTablet, err := inst.ReadTablet(analysisEntry.AnalyzedInstanceAlias) + analyzedTablet, err := inst.ReadTablet(alias) if err != nil { logger.Errorf("Failed to read instance %q, aborting recovery", analysisEntry.AnalyzedInstanceAlias) return false, topologyRecovery, fmt.Errorf("failed to read instance: %w", err) @@ -931,7 +947,7 @@ func demoteStaleTopoPrimary(ctx context.Context, analysisEntry *inst.Replication } // Demote the tablet, forcing it to drop any pending transactions that are waiting for an ack. - _, err = tmc.DemotePrimary(ctx, analyzedTablet, true) + _, err = forceDemotePrimary(ctx, analyzedTablet) if err != nil { return true, topologyRecovery, fmt.Errorf("failed to demote stale primary: %w", err) } @@ -953,6 +969,14 @@ func demoteStaleTopoPrimary(ctx context.Context, analysisEntry *inst.Replication return true, topologyRecovery, err } +// forceDemotePrimary calls the DemotePrimary RPC for the given tablet. +func forceDemotePrimary(ctx context.Context, tablet *topodatapb.Tablet) (*replicationdatapb.PrimaryStatus, error) { + ctx, cancel := context.WithTimeout(ctx, topo.RemoteOperationTimeout) + defer cancel() + + return tmc.DemotePrimary(ctx, tablet, true) +} + // recoverErrantGTIDDetected changes the tablet type of a replica tablet that has errant GTIDs. func recoverErrantGTIDDetected(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { topologyRecovery, err = AttemptRecoveryRegistration(analysisEntry) @@ -966,7 +990,9 @@ func recoverErrantGTIDDetected(ctx context.Context, analysisEntry *inst.Replicat // This has to be done in the end; whether successful or not, we should mark that the recovery is done. // So that after the active period passes, we are able to run other recoveries. defer func() { - _ = resolveRecovery(topologyRecovery, nil) + if err := resolveRecovery(topologyRecovery, nil); err != nil { + logger.Errorf("failed to resolve recovery for %q: %v", RecoverErrantGTIDDetectedName, err) + } }() analyzedTablet, err := inst.ReadTablet(analysisEntry.AnalyzedInstanceAlias) From 27d1f073e0cba24981c678a23cb9d86c4c5d9188 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Tue, 24 Feb 2026 00:52:01 +0000 Subject: [PATCH 071/112] [release-22.0] vreplication: fix infinite retry loop when terminal error message contains binary data (#19423) (#19437) Signed-off-by: Nick Van Wiggeren Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- .../fail-binary-no-default-value/alter | 1 + .../fail-binary-no-default-value/create.sql | 47 ++++++++ .../expect_failure | 1 + .../binlogplayer/message_truncate_test.go | 103 ++++++++++++++++++ .../vreplication/journal_test.go | 10 +- .../vreplication/vplayer_flaky_test.go | 2 +- .../tabletmanager/vreplication/vreplicator.go | 2 +- 7 files changed, 159 insertions(+), 7 deletions(-) create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-binary-no-default-value/alter create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-binary-no-default-value/create.sql create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-binary-no-default-value/expect_failure create mode 100644 go/vt/binlog/binlogplayer/message_truncate_test.go diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-binary-no-default-value/alter b/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-binary-no-default-value/alter new file mode 100644 index 00000000000..bf75cfaf36c --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-binary-no-default-value/alter @@ -0,0 +1 @@ +add column new_col bigint not null \ No newline at end of file diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-binary-no-default-value/create.sql b/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-binary-no-default-value/create.sql new file mode 100644 index 00000000000..aede64f0a63 --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-binary-no-default-value/create.sql @@ -0,0 +1,47 @@ +drop table if exists onlineddl_test; +create table onlineddl_test ( + id int auto_increment, + bin_data varbinary(256) not null, + primary key(id) +) auto_increment=1; + +-- Insert rows with binary data containing bytes 0x80-0xFF. +-- These bytes are invalid standalone UTF-8. When VReplication copies these rows, +-- the bulk INSERT query is built by encodeBytesSQLBytes2 (byte iteration, WriteByte), +-- preserving raw high bytes. If the error message is truncated and then re-encoded +-- by EncodeStringSQL (rune iteration, WriteRune), each invalid byte expands from +-- 1 byte to 3 bytes (U+FFFD), causing the stored message to exceed varbinary(1000). +insert into onlineddl_test (bin_data) values + (UNHEX(REPEAT('FF80FE90FD82FC83', 16))), + (UNHEX(REPEAT('FF80FE90FD82FC83', 16))), + (UNHEX(REPEAT('FF80FE90FD82FC83', 16))), + (UNHEX(REPEAT('FF80FE90FD82FC83', 16))), + (UNHEX(REPEAT('FF80FE90FD82FC83', 16))), + (UNHEX(REPEAT('FF80FE90FD82FC83', 16))), + (UNHEX(REPEAT('FF80FE90FD82FC83', 16))), + (UNHEX(REPEAT('FF80FE90FD82FC83', 16))), + (UNHEX(REPEAT('FF80FE90FD82FC83', 16))), + (UNHEX(REPEAT('FF80FE90FD82FC83', 16))), + (UNHEX(REPEAT('FF80FE90FD82FC83', 16))), + (UNHEX(REPEAT('FF80FE90FD82FC83', 16))), + (UNHEX(REPEAT('FF80FE90FD82FC83', 16))), + (UNHEX(REPEAT('FF80FE90FD82FC83', 16))), + (UNHEX(REPEAT('FF80FE90FD82FC83', 16))), + (UNHEX(REPEAT('FF80FE90FD82FC83', 16))), + (UNHEX(REPEAT('FF80FE90FD82FC83', 16))), + (UNHEX(REPEAT('FF80FE90FD82FC83', 16))), + (UNHEX(REPEAT('FF80FE90FD82FC83', 16))), + (UNHEX(REPEAT('FF80FE90FD82FC83', 16))); + +drop event if exists onlineddl_test; +delimiter ;; +create event onlineddl_test + on schedule every 1 second + starts current_timestamp + ends current_timestamp + interval 60 second + on completion not preserve + enable + do +begin + insert into onlineddl_test values (null, UNHEX(REPEAT('FF80FE90FD82FC83', 16))); +end ;; diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-binary-no-default-value/expect_failure b/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-binary-no-default-value/expect_failure new file mode 100644 index 00000000000..8ca6bb9534c --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-binary-no-default-value/expect_failure @@ -0,0 +1 @@ +doesn't have a default value \ No newline at end of file diff --git a/go/vt/binlog/binlogplayer/message_truncate_test.go b/go/vt/binlog/binlogplayer/message_truncate_test.go new file mode 100644 index 00000000000..ee1b52c1630 --- /dev/null +++ b/go/vt/binlog/binlogplayer/message_truncate_test.go @@ -0,0 +1,103 @@ +/* +Copyright 2026 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package binlogplayer + +import ( + "fmt" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/sqltypes" +) + +// TestMessageTruncateWithBinaryData documents a known encoding asymmetry +// between how binary data is encoded into INSERT queries vs how error messages +// are re-encoded for storage in _vt.vreplication.message (varbinary(1000)). +// +// The INSERT query is built using encodeBytesSQLBytes2 which iterates over +// []byte (byte-by-byte) and uses WriteByte, preserving raw high bytes (128-255) +// as single bytes in the Go string. But when the error message is re-encoded by +// EncodeStringSQL for the UPDATE, it iterates over string (rune-by-rune with +// UTF-8 decoding) and uses WriteRune. Invalid UTF-8 bytes get expanded to +// 3-byte U+FFFD replacement characters, causing the stored value to potentially +// exceed the column limit. +// +// The controller's runBlp() handles this by falling back to a simplified error +// message when setState() fails, preventing an infinite retry loop. +// See: controller.go runBlp() and the fail-binary-no-default-value e2e test. +func TestMessageTruncateWithBinaryData(t *testing.T) { + // Build a realistic error message. The binary data in the INSERT query + // was encoded by encodeBytesSQLBytes2 which preserves raw bytes. So the + // Go string contains raw high bytes (0x80-0xFF) that are NOT valid UTF-8. + var msg strings.Builder + + msg.WriteString("task error: failed inserting rows: Field 'workspace_id' doesn't have a default value (errno 1364) (sqlstate HY000) during query: insert into _vt_vrp_2354fd5f43b850e8a66b2375d6c09642_20260218201401_(chunk,type,`name`,`data`,environment_id) values ") + + // Simulate how encodeBytesSQLBytes2 writes binary values: raw bytes are + // preserved as-is (not re-encoded as UTF-8 runes). Build values that + // contain raw high bytes, similar to bitmap data. + for i := range 30 { + if i > 0 { + msg.WriteString(", ") + } + msg.WriteString(fmt.Sprintf("(0,%d,_binary'", i%4)) + msg.WriteString("id") + msg.WriteString("',_binary'") + // Write raw binary data the way encodeBytesSQLBytes2 does: raw bytes + // including invalid UTF-8 sequences. + msg.WriteByte(0x00) // null byte + msg.WriteByte(0x80) // invalid UTF-8 standalone + msg.WriteByte(0x0d) // carriage return + msg.WriteByte(0xc2) // start of 2-byte UTF-8 sequence... + msg.WriteByte(0xa6) // ...valid pair (U+00A6) + msg.WriteByte(0xff) // invalid UTF-8 + msg.WriteByte(0x80) // invalid UTF-8 standalone + msg.WriteByte(0xfe) // invalid UTF-8 + msg.WriteByte(0x90) // invalid UTF-8 standalone + msg.WriteString("',0)") + } + + fullMessage := msg.String() + require.Greater(t, len(fullMessage), 950, "message should be longer than truncation limit") + + // MessageTruncate correctly limits the raw string to 950 bytes. + truncated := MessageTruncate(fullMessage) + assert.LessOrEqual(t, len(truncated), 950, "MessageTruncate should limit to 950 bytes") + + // Encode for SQL (as setState/setMessage does via encodeString). + encoded := sqltypes.EncodeStringSQL(truncated) + + // Decode (simulating what MySQL stores after processing the UPDATE). + decoded, err := sqltypes.DecodeStringSQL(encoded) + require.NoError(t, err, "DecodeStringSQL should not error") + + // Document the known asymmetry: EncodeStringSQL iterates the string by + // rune (UTF-8 decoding), producing U+FFFD for each invalid byte. WriteRune + // then re-encodes U+FFFD as 3 bytes. The round-trip is NOT symmetric for + // strings containing invalid UTF-8, so the decoded value is larger than + // the input. This can cause the stored value to exceed varbinary(1000). + // + // The controller handles this gracefully by falling back to a simplified + // error message when setState() fails. See controller.go runBlp(). + assert.Greater(t, len(decoded), len(truncated), + "encoding round-trip should expand invalid UTF-8 bytes (known asymmetry)") + assert.Greater(t, len(decoded), 1000, + "decoded value should exceed varbinary(1000) limit (known asymmetry that controller.runBlp handles)") +} diff --git a/go/vt/vttablet/tabletmanager/vreplication/journal_test.go b/go/vt/vttablet/tabletmanager/vreplication/journal_test.go index 862f22ab564..b22b6f18fca 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/journal_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/journal_test.go @@ -74,7 +74,7 @@ func TestJournalOneToOne(t *testing.T) { fmt.Sprintf("delete from _vt.vreplication where id=%d", firstID), "commit", "/update _vt.vreplication set message='Picked source tablet.*", - "/update _vt.vreplication set state='Running', message='' where id.*", + "/update _vt.vreplication set state='Running', message=left\\('', 1000\\) where id.*", )) // Delete all vreplication streams. There should be only one, but we don't know its id. @@ -139,8 +139,8 @@ func TestJournalOneToMany(t *testing.T) { "commit", "/update _vt.vreplication set message='Picked source tablet.*", "/update _vt.vreplication set message='Picked source tablet.*", - "/update _vt.vreplication set state='Running', message='' where id.*", - "/update _vt.vreplication set state='Running', message='' where id.*", + "/update _vt.vreplication set state='Running', message=left\\('', 1000\\) where id.*", + "/update _vt.vreplication set state='Running', message=left\\('', 1000\\) where id.*", )) // Delete all vreplication streams. There should be only one, but we don't know its id. @@ -198,7 +198,7 @@ func TestJournalTablePresent(t *testing.T) { fmt.Sprintf("delete from _vt.vreplication where id=%d", firstID), "commit", "/update _vt.vreplication set message='Picked source tablet.*", - "/update _vt.vreplication set state='Running', message='' where id.*", + "/update _vt.vreplication set state='Running', message=left\\('', 1000\\) where id.*", )) // Delete all vreplication streams. There should be only one, but we don't know its id. @@ -307,7 +307,7 @@ func TestJournalTableMixed(t *testing.T) { defer execStatements(t, []string{"delete from _vt.resharding_journal"}) expectDBClientQueries(t, qh.Expect( - "/update _vt.vreplication set state='Stopped', message='unable to handle journal event: tables were partially matched' where id", + "/update _vt.vreplication set state='Stopped', message=left\\('unable to handle journal event: tables were partially matched', 1000\\) where id", )) // Delete all vreplication streams. There should be only one, but we don't know its id. diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go index 07d5229ef34..57c3db6691c 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go @@ -2086,7 +2086,7 @@ func TestPlayerDDL(t *testing.T) { expectDBClientQueries(t, qh.Expect( "alter table t1 add column val2 varchar(128)", "/update _vt.vreplication set message='error applying event: Duplicate", - "/update _vt.vreplication set state='Error', message='terminal error: error applying event: Duplicate", + "/update _vt.vreplication set state='Error', message=left\\('terminal error: error applying event: Duplicate", )) cancel() diff --git a/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go b/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go index 39e705bd301..83bca9604e3 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go @@ -508,7 +508,7 @@ func (vr *vreplicator) setState(state binlogdatapb.VReplicationWorkflowState, me }) } vr.stats.State.Store(state.String()) - query := fmt.Sprintf("update _vt.vreplication set state=%v, message=%v where id=%v", encodeString(state.String()), encodeString(binlogplayer.MessageTruncate(message)), vr.id) + query := fmt.Sprintf("update _vt.vreplication set state=%v, message=left(%v, 1000) where id=%v", encodeString(state.String()), encodeString(binlogplayer.MessageTruncate(message)), vr.id) // If we're batching a transaction, then include the state update // in the current transaction batch. if vr.dbClient.InTransaction && vr.dbClient.maxBatchSize > 0 { From a1eafd43799a11fd399a52079fc39ada7a1466f5 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Wed, 25 Feb 2026 22:51:47 +0100 Subject: [PATCH 072/112] [release-22.0] Restore: make loading compressor commands from `MANIFEST` opt-in (#19460) (#19473) Signed-off-by: Tim Vaillancourt Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Tim Vaillancourt Co-authored-by: Mohamed Hamza --- go/flags/endtoend/vtbackup.txt | 1 + go/flags/endtoend/vtcombo.txt | 1 + go/flags/endtoend/vttablet.txt | 1 + go/flags/endtoend/vttestserver.txt | 1 + .../backup/vtctlbackup/backup_test.go | 1 + .../backup/vtctlbackup/backup_utils.go | 4 + .../backup/xtrabackup/xtrabackup_test.go | 1 + go/vt/mysqlctl/builtinbackupengine.go | 5 +- go/vt/mysqlctl/compression.go | 18 +++- .../compression_external_decompressor_test.go | 93 +++++++++++++++++++ go/vt/mysqlctl/xtrabackupengine.go | 5 +- 11 files changed, 122 insertions(+), 9 deletions(-) create mode 100644 go/vt/mysqlctl/compression_external_decompressor_test.go diff --git a/go/flags/endtoend/vtbackup.txt b/go/flags/endtoend/vtbackup.txt index a274e881092..9e5184b1521 100644 --- a/go/flags/endtoend/vtbackup.txt +++ b/go/flags/endtoend/vtbackup.txt @@ -131,6 +131,7 @@ Flags: --external-compressor string command with arguments to use when compressing a backup. --external-compressor-extension string extension to use when using an external compressor. --external-decompressor string command with arguments to use when decompressing a backup. + --external-decompressor-use-manifest allows the decompressor command stored in the backup manifest to be used at restore time. Enabling this is a security risk: an attacker with write access to the backup storage could modify the manifest to execute arbitrary commands on the tablet as the Vitess user. NOT RECOMMENDED. --file_backup_storage_root string Root directory for the file backup storage. --gcs_backup_storage_bucket string Google Cloud Storage bucket to use for backups. --gcs_backup_storage_root string Root prefix for all backup-related object names. diff --git a/go/flags/endtoend/vtcombo.txt b/go/flags/endtoend/vtcombo.txt index acd659516c5..a68845cb16f 100644 --- a/go/flags/endtoend/vtcombo.txt +++ b/go/flags/endtoend/vtcombo.txt @@ -131,6 +131,7 @@ Flags: --external-compressor string command with arguments to use when compressing a backup. --external-compressor-extension string extension to use when using an external compressor. --external-decompressor string command with arguments to use when decompressing a backup. + --external-decompressor-use-manifest allows the decompressor command stored in the backup manifest to be used at restore time. Enabling this is a security risk: an attacker with write access to the backup storage could modify the manifest to execute arbitrary commands on the tablet as the Vitess user. NOT RECOMMENDED. --external_topo_server Should vtcombo use an external topology server instead of starting its own in-memory topology server. If true, vtcombo will use the flags defined in topo/server.go to open topo server --foreign_key_mode string This is to provide how to handle foreign key constraint in create/alter table. Valid values are: allow, disallow (default "allow") --gate_query_cache_memory int gate server query cache size in bytes, maximum amount of memory to be cached. vtgate analyzes every incoming query and generate a query plan, these plans are being cached in a lru cache. This config controls the capacity of the lru cache. (default 33554432) diff --git a/go/flags/endtoend/vttablet.txt b/go/flags/endtoend/vttablet.txt index 04eb16edc25..0eeec3f2bec 100644 --- a/go/flags/endtoend/vttablet.txt +++ b/go/flags/endtoend/vttablet.txt @@ -155,6 +155,7 @@ Flags: --external-compressor string command with arguments to use when compressing a backup. --external-compressor-extension string extension to use when using an external compressor. --external-decompressor string command with arguments to use when decompressing a backup. + --external-decompressor-use-manifest allows the decompressor command stored in the backup manifest to be used at restore time. Enabling this is a security risk: an attacker with write access to the backup storage could modify the manifest to execute arbitrary commands on the tablet as the Vitess user. NOT RECOMMENDED. --file_backup_storage_root string Root directory for the file backup storage. --filecustomrules string file based custom rule path --filecustomrules_watch set up a watch on the target file and reload query rules when it changes diff --git a/go/flags/endtoend/vttestserver.txt b/go/flags/endtoend/vttestserver.txt index 385b7194652..eee43552002 100644 --- a/go/flags/endtoend/vttestserver.txt +++ b/go/flags/endtoend/vttestserver.txt @@ -38,6 +38,7 @@ Flags: --external-compressor string command with arguments to use when compressing a backup. --external-compressor-extension string extension to use when using an external compressor. --external-decompressor string command with arguments to use when decompressing a backup. + --external-decompressor-use-manifest allows the decompressor command stored in the backup manifest to be used at restore time. Enabling this is a security risk: an attacker with write access to the backup storage could modify the manifest to execute arbitrary commands on the tablet as the Vitess user. NOT RECOMMENDED. --external_topo_global_root string the path of the global topology data in the global topology server for vtcombo process --external_topo_global_server_address string the address of the global topology server for vtcombo process --external_topo_implementation string the topology implementation to use for vtcombo process diff --git a/go/test/endtoend/backup/vtctlbackup/backup_test.go b/go/test/endtoend/backup/vtctlbackup/backup_test.go index be9e5bbf490..be80d097c9b 100644 --- a/go/test/endtoend/backup/vtctlbackup/backup_test.go +++ b/go/test/endtoend/backup/vtctlbackup/backup_test.go @@ -60,6 +60,7 @@ func TestBuiltinBackupWithExternalZstdCompressionAndManifestedDecompressor(t *te CompressorEngineName: "external", ExternalCompressorCmd: "zstd", ExternalCompressorExt: ".zst", + ExternalDecompressorUseManifest: true, ManifestExternalDecompressorCmd: "zstd -d", } diff --git a/go/test/endtoend/backup/vtctlbackup/backup_utils.go b/go/test/endtoend/backup/vtctlbackup/backup_utils.go index 05deb36bb02..a3ce59e513a 100644 --- a/go/test/endtoend/backup/vtctlbackup/backup_utils.go +++ b/go/test/endtoend/backup/vtctlbackup/backup_utils.go @@ -92,6 +92,7 @@ type CompressionDetails struct { ExternalCompressorCmd string ExternalCompressorExt string ExternalDecompressorCmd string + ExternalDecompressorUseManifest bool ManifestExternalDecompressorCmd string } @@ -305,6 +306,9 @@ func getCompressorArgs(cDetails *CompressionDetails) []string { if cDetails.ExternalDecompressorCmd != "" { args = append(args, fmt.Sprintf("--external-decompressor=%s", cDetails.ExternalDecompressorCmd)) } + if cDetails.ExternalDecompressorUseManifest { + args = append(args, "--external-decompressor-use-manifest") + } if cDetails.ManifestExternalDecompressorCmd != "" { args = append(args, fmt.Sprintf("--manifest-external-decompressor=%s", cDetails.ManifestExternalDecompressorCmd)) } diff --git a/go/test/endtoend/backup/xtrabackup/xtrabackup_test.go b/go/test/endtoend/backup/xtrabackup/xtrabackup_test.go index 3402a170310..e18f229d9cb 100644 --- a/go/test/endtoend/backup/xtrabackup/xtrabackup_test.go +++ b/go/test/endtoend/backup/xtrabackup/xtrabackup_test.go @@ -59,6 +59,7 @@ func TestXtrabackupWithExternalZstdCompressionAndManifestedDecompressor(t *testi CompressorEngineName: "external", ExternalCompressorCmd: "zstd", ExternalCompressorExt: ".zst", + ExternalDecompressorUseManifest: true, ManifestExternalDecompressorCmd: "zstd -d", } diff --git a/go/vt/mysqlctl/builtinbackupengine.go b/go/vt/mysqlctl/builtinbackupengine.go index b88c70c6953..c0a95e41094 100644 --- a/go/vt/mysqlctl/builtinbackupengine.go +++ b/go/vt/mysqlctl/builtinbackupengine.go @@ -1323,10 +1323,7 @@ func (be *BuiltinBackupEngine) restoreFile(ctx context.Context, params RestorePa // for backward compatibility deCompressionEngine = PgzipCompressor } - externalDecompressorCmd := ExternalDecompressorCmd - if externalDecompressorCmd == "" && bm.ExternalDecompressor != "" { - externalDecompressorCmd = bm.ExternalDecompressor - } + externalDecompressorCmd := resolveExternalDecompressor(bm.ExternalDecompressor) if externalDecompressorCmd != "" { if deCompressionEngine == ExternalCompressor { deCompressionEngine = externalDecompressorCmd diff --git a/go/vt/mysqlctl/compression.go b/go/vt/mysqlctl/compression.go index c2d3cbbe18b..5737b70b791 100644 --- a/go/vt/mysqlctl/compression.go +++ b/go/vt/mysqlctl/compression.go @@ -52,9 +52,10 @@ var ( ExternalCompressorCmd string ExternalCompressorExt string ExternalDecompressorCmd string + ExternalDecompressorUseManifest bool ManifestExternalDecompressorCmd string - errUnsupportedDeCompressionEngine = errors.New("unsupported engine in MANIFEST. You need to provide --external-decompressor if using 'external' compression engine") + errUnsupportedDeCompressionEngine = errors.New("unsupported engine in MANIFEST. You need to provide --external-decompressor if using 'external' compression engine. Alternatively, set --external-decompressor-use-manifest to use the decompressor command from the backup manifest, but this is NOT RECOMMENDED as it is a security risk") errUnsupportedCompressionEngine = errors.New("unsupported engine value for --compression-engine-name. supported values are 'external', 'pgzip', 'pargzip', 'zstd', 'lz4'") // this is used by getEngineFromExtension() to figure out which engine to use in case the user didn't specify @@ -77,6 +78,7 @@ func registerBackupCompressionFlags(fs *pflag.FlagSet) { fs.StringVar(&ExternalCompressorCmd, "external-compressor", ExternalCompressorCmd, "command with arguments to use when compressing a backup.") fs.StringVar(&ExternalCompressorExt, "external-compressor-extension", ExternalCompressorExt, "extension to use when using an external compressor.") fs.StringVar(&ExternalDecompressorCmd, "external-decompressor", ExternalDecompressorCmd, "command with arguments to use when decompressing a backup.") + fs.BoolVar(&ExternalDecompressorUseManifest, "external-decompressor-use-manifest", ExternalDecompressorUseManifest, "allows the decompressor command stored in the backup manifest to be used at restore time. Enabling this is a security risk: an attacker with write access to the backup storage could modify the manifest to execute arbitrary commands on the tablet as the Vitess user. NOT RECOMMENDED.") fs.StringVar(&ManifestExternalDecompressorCmd, "manifest-external-decompressor", ManifestExternalDecompressorCmd, "command with arguments to store in the backup manifest when compressing a backup with an external compression engine.") } @@ -91,6 +93,20 @@ func getExtensionFromEngine(engine string) (string, error) { return "", fmt.Errorf("%w %q", errUnsupportedCompressionEngine, engine) } +// resolveExternalDecompressor returns the external decompressor command to use +// at restore time. The CLI flag (--external-decompressor) takes precedence. The +// backup manifest value is only used when --external-decompressor-use-manifest +// is explicitly set to true. +func resolveExternalDecompressor(manifestDecompressor string) string { + if ExternalDecompressorCmd != "" { + return ExternalDecompressorCmd + } + if ExternalDecompressorUseManifest && manifestDecompressor != "" { + return manifestDecompressor + } + return "" +} + // Validates if the external decompressor exists and return its path. func validateExternalCmd(cmd string) (string, error) { if cmd == "" { diff --git a/go/vt/mysqlctl/compression_external_decompressor_test.go b/go/vt/mysqlctl/compression_external_decompressor_test.go new file mode 100644 index 00000000000..fd4732aff24 --- /dev/null +++ b/go/vt/mysqlctl/compression_external_decompressor_test.go @@ -0,0 +1,93 @@ +/* +Copyright 2026 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package mysqlctl + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResolveExternalDecompressor(t *testing.T) { + tests := []struct { + name string + cliDecompressorCmd string + useManifest bool + manifestDecompressor string + expected string + }{ + { + name: "CLI flag takes precedence over manifest", + cliDecompressorCmd: "zstd -d", + useManifest: true, + manifestDecompressor: "gzip -d", + expected: "zstd -d", + }, + { + name: "CLI flag takes precedence even when use-manifest is false", + cliDecompressorCmd: "zstd -d", + useManifest: false, + manifestDecompressor: "gzip -d", + expected: "zstd -d", + }, + { + name: "manifest used when use-manifest is true and no CLI flag", + cliDecompressorCmd: "", + useManifest: true, + manifestDecompressor: "gzip -d", + expected: "gzip -d", + }, + { + name: "manifest ignored when use-manifest is false", + cliDecompressorCmd: "", + useManifest: false, + manifestDecompressor: "gzip -d", + expected: "", + }, + { + name: "empty when nothing is set", + cliDecompressorCmd: "", + useManifest: false, + manifestDecompressor: "", + expected: "", + }, + { + name: "empty when use-manifest is true but manifest is empty", + cliDecompressorCmd: "", + useManifest: true, + manifestDecompressor: "", + expected: "", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + origCmd := ExternalDecompressorCmd + origAllow := ExternalDecompressorUseManifest + t.Cleanup(func() { + ExternalDecompressorCmd = origCmd + ExternalDecompressorUseManifest = origAllow + }) + + ExternalDecompressorCmd = tt.cliDecompressorCmd + ExternalDecompressorUseManifest = tt.useManifest + + result := resolveExternalDecompressor(tt.manifestDecompressor) + assert.Equal(t, tt.expected, result) + }) + } +} diff --git a/go/vt/mysqlctl/xtrabackupengine.go b/go/vt/mysqlctl/xtrabackupengine.go index 639f30d7f4d..2f1044e8a36 100644 --- a/go/vt/mysqlctl/xtrabackupengine.go +++ b/go/vt/mysqlctl/xtrabackupengine.go @@ -638,10 +638,7 @@ func (be *XtrabackupEngine) extractFiles(ctx context.Context, logger logutil.Log // then we assign the default value of compressionEngine. deCompressionEngine = PgzipCompressor } - externalDecompressorCmd := ExternalDecompressorCmd - if externalDecompressorCmd == "" && bm.ExternalDecompressor != "" { - externalDecompressorCmd = bm.ExternalDecompressor - } + externalDecompressorCmd := resolveExternalDecompressor(bm.ExternalDecompressor) if externalDecompressorCmd != "" { if deCompressionEngine == ExternalCompressor { deCompressionEngine = externalDecompressorCmd From 1520b7a14d35919759f002427ee643fd5a5cbcde Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Wed, 25 Feb 2026 23:30:05 +0100 Subject: [PATCH 073/112] [release-22.0] `backupengine`: disallow path traversals via backup `MANIFEST` on restore (#19470) (#19477) Signed-off-by: Tim Vaillancourt Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- go/vt/mysqlctl/builtinbackupengine.go | 7 +- go/vt/mysqlctl/builtinbackupengine_test.go | 89 ++++++++++++++++++++++ 2 files changed, 94 insertions(+), 2 deletions(-) diff --git a/go/vt/mysqlctl/builtinbackupengine.go b/go/vt/mysqlctl/builtinbackupengine.go index c0a95e41094..fa1fee4d186 100644 --- a/go/vt/mysqlctl/builtinbackupengine.go +++ b/go/vt/mysqlctl/builtinbackupengine.go @@ -36,6 +36,7 @@ import ( "github.com/spf13/pflag" "golang.org/x/sync/errgroup" + "vitess.io/vitess/go/fileutil" "vitess.io/vitess/go/ioutil" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/mysql/replication" @@ -178,7 +179,9 @@ func registerBuiltinBackupEngineFlags(fs *pflag.FlagSet) { fs.StringVar(&builtinIncrementalRestorePath, "builtinbackup-incremental-restore-path", builtinIncrementalRestorePath, "the directory where incremental restore files, namely binlog files, are extracted to. In k8s environments, this should be set to a directory that is shared between the vttablet and mysqld pods. The path should exist. When empty, the default OS temp dir is assumed.") } -// fullPath returns the full path of the entry, based on its type +// fullPath returns the full path of the entry, based on its type. +// It validates that the resolved path does not escape the base directory +// via path traversal (e.g. "../../" sequences in fe.Name). func (fe *FileEntry) fullPath(cnf *Mycnf) (string, error) { // find the root to use var root string @@ -195,7 +198,7 @@ func (fe *FileEntry) fullPath(cnf *Mycnf) (string, error) { return "", vterrors.Errorf(vtrpcpb.Code_UNKNOWN, "unknown base: %v", fe.Base) } - return path.Join(fe.ParentPath, root, fe.Name), nil + return fileutil.SafePathJoin(path.Join(fe.ParentPath, root), fe.Name) } // open attempts to open the file diff --git a/go/vt/mysqlctl/builtinbackupengine_test.go b/go/vt/mysqlctl/builtinbackupengine_test.go index 39e4aa7ae1c..61b1abdf3c2 100644 --- a/go/vt/mysqlctl/builtinbackupengine_test.go +++ b/go/vt/mysqlctl/builtinbackupengine_test.go @@ -21,7 +21,9 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "vitess.io/vitess/go/fileutil" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" ) @@ -70,6 +72,93 @@ func TestGetIncrementalFromPosGTIDSet(t *testing.T) { } } +func TestFileEntryFullPath(t *testing.T) { + cnf := &Mycnf{ + DataDir: "/vt/data", + InnodbDataHomeDir: "/vt/innodb-data", + InnodbLogGroupHomeDir: "/vt/innodb-log", + BinLogPath: "/vt/binlogs/mysql-bin", + } + + tests := []struct { + name string + entry FileEntry + wantPath string + wantError error + }{ + { + name: "valid relative path in DataDir", + entry: FileEntry{Base: backupData, Name: "mydb/table1.ibd"}, + wantPath: "/vt/data/mydb/table1.ibd", + }, + { + name: "valid relative path in InnodbDataHomeDir", + entry: FileEntry{Base: backupInnodbDataHomeDir, Name: "ibdata1"}, + wantPath: "/vt/innodb-data/ibdata1", + }, + { + name: "valid relative path in InnodbLogGroupHomeDir", + entry: FileEntry{Base: backupInnodbLogGroupHomeDir, Name: "ib_logfile0"}, + wantPath: "/vt/innodb-log/ib_logfile0", + }, + { + name: "valid relative path in BinlogDir", + entry: FileEntry{Base: backupBinlogDir, Name: "mysql-bin.000001"}, + wantPath: "/vt/binlogs/mysql-bin.000001", + }, + { + name: "valid path with ParentPath", + entry: FileEntry{Base: backupData, Name: "mydb/table1.ibd", ParentPath: "/tmp/restore"}, + wantPath: "/tmp/restore/vt/data/mydb/table1.ibd", + }, + { + name: "path traversal escapes base directory", + entry: FileEntry{Base: backupData, Name: "../../etc/passwd"}, + wantError: fileutil.ErrInvalidJoinedPath, + }, + { + name: "path traversal with deeper nesting", + entry: FileEntry{Base: backupData, Name: "mydb/../../../etc/shadow"}, + wantError: fileutil.ErrInvalidJoinedPath, + }, + { + name: "path traversal to root", + entry: FileEntry{Base: backupData, Name: "../../../../../etc/crontab"}, + wantError: fileutil.ErrInvalidJoinedPath, + }, + { + name: "path traversal escapes ParentPath", + entry: FileEntry{Base: backupData, Name: "../../../../etc/passwd", ParentPath: "/tmp/restore"}, + wantError: fileutil.ErrInvalidJoinedPath, + }, + { + name: "relative path with dot-dot that stays within base", + entry: FileEntry{Base: backupData, Name: "mydb/../mydb/table1.ibd"}, + wantPath: "/vt/data/mydb/table1.ibd", + }, + } + + // Test unknown base separately since it returns a different error type. + t.Run("unknown base", func(t *testing.T) { + entry := FileEntry{Base: "unknown", Name: "file"} + _, err := entry.fullPath(cnf) + require.Error(t, err) + assert.Contains(t, err.Error(), "unknown base") + }) + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := tt.entry.fullPath(cnf) + if tt.wantError != nil { + require.ErrorIs(t, err, tt.wantError) + } else { + require.NoError(t, err) + assert.Equal(t, tt.wantPath, got) + } + }) + } +} + func TestShouldDrainForBackupBuiltIn(t *testing.T) { be := &BuiltinBackupEngine{} From 9894049de2c420a755945f20f5c428f00e03f4b5 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Wed, 25 Feb 2026 22:43:11 +0000 Subject: [PATCH 074/112] [release-22.0] `filebackupstorage`: use `fileutil.SafePathJoin` for all path building (#19479) (#19480) Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- go/vt/mysqlctl/filebackupstorage/file.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/go/vt/mysqlctl/filebackupstorage/file.go b/go/vt/mysqlctl/filebackupstorage/file.go index bff054692dc..c841e4ce479 100644 --- a/go/vt/mysqlctl/filebackupstorage/file.go +++ b/go/vt/mysqlctl/filebackupstorage/file.go @@ -23,7 +23,6 @@ import ( "fmt" "io" "os" - "path" "github.com/spf13/pflag" @@ -96,7 +95,10 @@ func (fbh *FileBackupHandle) AddFile(ctx context.Context, filename string, files if fbh.readOnly { return nil, fmt.Errorf("AddFile cannot be called on read-only backup") } - p := path.Join(FileBackupStorageRoot, fbh.dir, fbh.name, filename) + p, err := fileutil.SafePathJoin(FileBackupStorageRoot, fbh.dir, fbh.name, filename) + if err != nil { + return nil, err + } f, err := os2.Create(p) if err != nil { return nil, err @@ -188,7 +190,10 @@ func (fbs *FileBackupStorage) StartBackup(ctx context.Context, dir, name string) } // Create the subdirectory for this named backup. - p = path.Join(p, name) + p, err = fileutil.SafePathJoin(p, name) + if err != nil { + return nil, err + } if err = os2.Mkdir(p); err != nil { return nil, err } From 45b59f7ce95f5685a4d5b604b58dfd3c47c8dae1 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Thu, 26 Feb 2026 11:02:04 +0000 Subject: [PATCH 075/112] [release-22.0] vtgate: Add bounds check in `visitUnion` for mismatched column counts (#19476) (#19482) Signed-off-by: Arthur Schreiber Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 --- go/vt/vtgate/semantics/analyzer_test.go | 3 +++ go/vt/vtgate/semantics/table_collector.go | 3 +++ 2 files changed, 6 insertions(+) diff --git a/go/vt/vtgate/semantics/analyzer_test.go b/go/vt/vtgate/semantics/analyzer_test.go index 72b9ad83eb4..3f1ff88c9df 100644 --- a/go/vt/vtgate/semantics/analyzer_test.go +++ b/go/vt/vtgate/semantics/analyzer_test.go @@ -940,6 +940,9 @@ func TestInvalidQueries(t *testing.T) { sql: "select sql_calc_found_rows id from a union select 1 limit 109", err: &UnionWithSQLCalcFoundRowsError{}, serr: "VT12001: unsupported: SQL_CALC_FOUND_ROWS not supported with union", + }, { + sql: "select 1 union select *, m from t1", + err: &UnionColumnsDoNotMatchError{FirstProj: 1, SecondProj: 2}, }, { sql: "select * from (select sql_calc_found_rows id from a) as t", serr: "Incorrect usage/placement of 'SQL_CALC_FOUND_ROWS'", diff --git a/go/vt/vtgate/semantics/table_collector.go b/go/vt/vtgate/semantics/table_collector.go index 4eed6f4eb93..a91a29bd342 100644 --- a/go/vt/vtgate/semantics/table_collector.go +++ b/go/vt/vtgate/semantics/table_collector.go @@ -175,6 +175,9 @@ func (tc *tableCollector) visitUnion(union *sqlparser.Union) error { err = sqlparser.VisitAllSelects(union, func(s *sqlparser.Select, idx int) error { for i, expr := range s.GetColumns() { + if i >= size { + return &UnionColumnsDoNotMatchError{FirstProj: size, SecondProj: len(s.GetColumns())} + } ae, ok := expr.(*sqlparser.AliasedExpr) if !ok { continue From 0438639e4da74fdfb08e64eb3186b3928836a2ae Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Thu, 26 Feb 2026 17:17:43 +0000 Subject: [PATCH 076/112] [release-22.0] `mysqlshellbackupengine`: use `fileutil.SafePathJoin(...)` to build path (#19484) (#19490) Signed-off-by: Tim Vaillancourt Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- go/vt/mysqlctl/mysqlshellbackupengine.go | 65 +++++++++++++++++++----- 1 file changed, 52 insertions(+), 13 deletions(-) diff --git a/go/vt/mysqlctl/mysqlshellbackupengine.go b/go/vt/mysqlctl/mysqlshellbackupengine.go index ac40d9adc17..c258c8a9121 100644 --- a/go/vt/mysqlctl/mysqlshellbackupengine.go +++ b/go/vt/mysqlctl/mysqlshellbackupengine.go @@ -26,6 +26,7 @@ import ( "os" "os/exec" "path" + "path/filepath" "slices" "strings" "sync" @@ -33,6 +34,7 @@ import ( "github.com/spf13/pflag" + "vitess.io/vitess/go/fileutil" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/mysql/capabilities" "vitess.io/vitess/go/vt/log" @@ -117,9 +119,12 @@ const ( func (be *MySQLShellBackupEngine) ExecuteBackup(ctx context.Context, params BackupParams, bh backupstorage.BackupHandle) (result BackupResult, finalErr error) { params.Logger.Infof("Starting ExecuteBackup in %s", params.TabletAlias) - location := path.Join(mysqlShellBackupLocation, bh.Directory(), bh.Name()) + location, err := be.backupLocation(bh.Directory(), bh.Name()) + if err != nil { + return BackupUnusable, vterrors.Wrap(err, "cannot safely determine backup location") + } - err := be.backupPreCheck(location) + err = be.backupPreCheck(location) if err != nil { return BackupUnusable, vterrors.Wrap(err, "failed backup precheck") } @@ -254,6 +259,24 @@ func (be *MySQLShellBackupEngine) ExecuteRestore(ctx context.Context, params Res return nil, err } + // Validate bm.BackupLocation from the MANIFEST. For local filesystem + // mode, use SafePathJoin to prevent path traversal. For object storage, + // trust the manifest location directly since SafePathJoin relies on + // OS-native path operations that don't understand cloud URIs. + var location string + if isObjectStoreFlags(mysqlShellLoadFlags) { + location = bm.BackupLocation + } else { + relLocation, err := filepath.Rel(mysqlShellBackupLocation, bm.BackupLocation) + if err != nil { + return nil, vterrors.Wrapf(err, "cannot determine relative backup location from manifest") + } + location, err = fileutil.SafePathJoin(mysqlShellBackupLocation, relLocation) + if err != nil { + return nil, vterrors.Wrapf(err, "backup location %q in manifest is outside the backup root %q", bm.BackupLocation, mysqlShellBackupLocation) + } + } + // mark restore as in progress if err := createStateFile(params.Cnf); err != nil { return nil, err @@ -338,7 +361,7 @@ func (be *MySQLShellBackupEngine) ExecuteRestore(ctx context.Context, params Res } args = append(args, "-e", fmt.Sprintf("util.loadDump(%q, %s)", - bm.BackupLocation, + location, mysqlShellLoadFlags, )) @@ -396,6 +419,30 @@ func (be *MySQLShellBackupEngine) ShouldStartMySQLAfterRestore() bool { func (be *MySQLShellBackupEngine) Name() string { return mysqlShellBackupEngineName } +// isObjectStoreFlags returns true if the given flags JSON string contains +// any known object store parameters, indicating cloud storage is in use. +func isObjectStoreFlags(flags string) bool { + for _, objStore := range knownObjectStoreParams { + if strings.Contains(flags, objStore) { + return true + } + } + return false +} + +// backupLocation returns a backup location path by joining the configured +// mysqlShellBackupLocation with the provided directory and name components. +// For local filesystem mode, it uses fileutil.SafePathJoin to prevent path +// traversal outside the configured backup location. For object storage, +// path.Join is used since SafePathJoin relies on OS-native path operations +// that don't understand cloud URIs. +func (be *MySQLShellBackupEngine) backupLocation(dir, name string) (string, error) { + if isObjectStoreFlags(mysqlShellDumpFlags) { + return path.Join(mysqlShellBackupLocation, dir, name), nil + } + return fileutil.SafePathJoin(mysqlShellBackupLocation, dir, name) +} + func (be *MySQLShellBackupEngine) backupPreCheck(location string) error { if mysqlShellBackupLocation == "" { return fmt.Errorf("%w: no backup location set via --mysql-shell-backup-location", ErrMySQLShellPreCheck) @@ -405,17 +452,9 @@ func (be *MySQLShellBackupEngine) backupPreCheck(location string) error { return fmt.Errorf("%w: at least the --js flag is required in the value of the flag --mysql-shell-flags", ErrMySQLShellPreCheck) } - // make sure the targe directory exists if the target location for the backup is not an object store + // make sure the target directory exists if the target location for the backup is not an object store // (e.g. is the local filesystem) as MySQL Shell doesn't create the entire path beforehand: - isObjectStorage := false - for _, objStore := range knownObjectStoreParams { - if strings.Contains(mysqlShellDumpFlags, objStore) { - isObjectStorage = true - break - } - } - - if !isObjectStorage { + if !isObjectStoreFlags(mysqlShellDumpFlags) { err := os.MkdirAll(location, 0o750) if err != nil { return fmt.Errorf("failure creating directory %s: %w", location, err) From 5f1e8e0751f55a43827018adce05d252b3278e78 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Thu, 26 Feb 2026 21:55:42 +0000 Subject: [PATCH 077/112] [release-22.0] `vttablet`: harden `ExecuteHook` RPC and backup engine flag inputs (#19486) (#19500) Signed-off-by: Tim Vaillancourt Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Tim Vaillancourt --- go/vt/hook/hook.go | 13 +++++----- go/vt/mysqlctl/mysqlshellbackupengine.go | 30 +++++++++++++++++------- go/vt/mysqlctl/xtrabackupengine.go | 19 ++++++++++++--- go/vt/vttablet/grpctmserver/server.go | 5 ++++ go/vt/vttablet/tmrpctest/test_tm_rpc.go | 9 +++++++ 5 files changed, 58 insertions(+), 18 deletions(-) diff --git a/go/vt/hook/hook.go b/go/vt/hook/hook.go index 4f402cdcb44..88f42b8efdf 100644 --- a/go/vt/hook/hook.go +++ b/go/vt/hook/hook.go @@ -23,11 +23,12 @@ import ( "io" "os" "os/exec" - "path" + "path/filepath" "strings" "syscall" "time" + "vitess.io/vitess/go/fileutil" vtenv "vitess.io/vitess/go/vt/env" "vitess.io/vitess/go/vt/log" ) @@ -98,11 +99,6 @@ func NewHookWithEnv(name string, params []string, env map[string]string) *Hook { // findHook tries to locate the hook, and returns the exec.Cmd for it. func (hook *Hook) findHook(ctx context.Context) (*exec.Cmd, int, error) { - // Check the hook path. - if strings.Contains(hook.Name, "/") { - return nil, HOOK_INVALID_NAME, fmt.Errorf("hook cannot contain '/'") - } - // Find our root. root, err := vtenv.VtRoot() if err != nil { @@ -110,7 +106,10 @@ func (hook *Hook) findHook(ctx context.Context) (*exec.Cmd, int, error) { } // See if the hook exists. - vthook := path.Join(root, "vthook", hook.Name) + vthook, err := fileutil.SafePathJoin(filepath.Join(root, "vthook"), hook.Name) + if err != nil { + return nil, HOOK_INVALID_NAME, fmt.Errorf("invalid hook name %q: %v", hook.Name, err) + } _, err = os.Stat(vthook) if err != nil { if os.IsNotExist(err) { diff --git a/go/vt/mysqlctl/mysqlshellbackupengine.go b/go/vt/mysqlctl/mysqlshellbackupengine.go index c258c8a9121..74bc312dee6 100644 --- a/go/vt/mysqlctl/mysqlshellbackupengine.go +++ b/go/vt/mysqlctl/mysqlshellbackupengine.go @@ -18,6 +18,7 @@ package mysqlctl import ( "bufio" + "bytes" "context" "encoding/json" "errors" @@ -32,6 +33,7 @@ import ( "sync" "time" + "github.com/google/shlex" "github.com/spf13/pflag" "vitess.io/vitess/go/fileutil" @@ -40,6 +42,7 @@ import ( "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/mysqlctl/backupstorage" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/servenv" "vitess.io/vitess/go/vt/vterrors" ) @@ -139,14 +142,20 @@ func (be *MySQLShellBackupEngine) ExecuteBackup(ctx context.Context, params Back return BackupUnusable, vterrors.Wrap(err, "can't get MySQL version") } - args := []string{} - if mysqlShellFlags != "" { - args = append(args, strings.Fields(mysqlShellFlags)...) + args, err := shlex.Split(mysqlShellFlags) + if err != nil { + return BackupUnusable, vterrors.Wrap(err, "failed to parse --mysql-shell-flags") + } + + // compact and validate the json input from mysqlShellDumpFlags. + var compactDumpFlags bytes.Buffer + if err := json.Compact(&compactDumpFlags, []byte(mysqlShellDumpFlags)); err != nil { + return BackupUnusable, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "failed to parse --mysql-shell-dump-flags as JSON: %v", err) } args = append(args, "-e", fmt.Sprintf("util.dumpInstance(%q, %s)", location, - mysqlShellDumpFlags, + compactDumpFlags.String(), )) // to be able to get the consistent GTID sets, we will acquire a global read lock before starting mysql shell. @@ -354,15 +363,20 @@ func (be *MySQLShellBackupEngine) ExecuteRestore(ctx context.Context, params Res } defer resetFunc() - args := []string{} + args, err := shlex.Split(mysqlShellFlags) + if err != nil { + return nil, vterrors.Wrap(err, "failed to parse --mysql-shell-flags") + } - if mysqlShellFlags != "" { - args = append(args, strings.Fields(mysqlShellFlags)...) + // compact and validate the json input from mysqlShellLoadFlags. + var compactLoadFlags bytes.Buffer + if err := json.Compact(&compactLoadFlags, []byte(mysqlShellLoadFlags)); err != nil { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "failed to parse --mysql-shell-load-flags as JSON: %v", err) } args = append(args, "-e", fmt.Sprintf("util.loadDump(%q, %s)", location, - mysqlShellLoadFlags, + compactLoadFlags.String(), )) cmd := exec.CommandContext(ctx, "mysqlsh", args...) diff --git a/go/vt/mysqlctl/xtrabackupengine.go b/go/vt/mysqlctl/xtrabackupengine.go index 2f1044e8a36..cdd5ebadba9 100644 --- a/go/vt/mysqlctl/xtrabackupengine.go +++ b/go/vt/mysqlctl/xtrabackupengine.go @@ -30,6 +30,7 @@ import ( "sync" "time" + "github.com/google/shlex" "github.com/spf13/pflag" "vitess.io/vitess/go/ioutil" @@ -306,7 +307,11 @@ func (be *XtrabackupEngine) backupFiles( flagsToExec = append(flagsToExec, "--stream="+xtrabackupStreamMode) } if xtrabackupBackupFlags != "" { - flagsToExec = append(flagsToExec, strings.Fields(xtrabackupBackupFlags)...) + backupFlags, err := shlex.Split(xtrabackupBackupFlags) + if err != nil { + return replicationPosition, vterrors.Wrap(err, "failed to parse --xtrabackup-backup-flags") + } + flagsToExec = append(flagsToExec, backupFlags...) } // Create a cancellable Context for calls to bh.AddFile(). @@ -535,7 +540,11 @@ func (be *XtrabackupEngine) restoreFromBackup(ctx context.Context, cnf *Mycnf, b "--target-dir=" + tempDir, } if xtrabackupPrepareFlags != "" { - flagsToExec = append(flagsToExec, strings.Fields(xtrabackupPrepareFlags)...) + prepareFlags, err := shlex.Split(xtrabackupPrepareFlags) + if err != nil { + return vterrors.Wrap(err, "failed to parse --xtrabackup-prepare-flags") + } + flagsToExec = append(flagsToExec, prepareFlags...) } prepareCmd := exec.CommandContext(ctx, restoreProgram, flagsToExec...) prepareOut, err := prepareCmd.StdoutPipe() @@ -708,7 +717,11 @@ func (be *XtrabackupEngine) extractFiles(ctx context.Context, logger logutil.Log xbstreamProgram := path.Join(xtrabackupEnginePath, xbstream) flagsToExec := []string{"-C", tempDir, "-xv"} if xbstreamRestoreFlags != "" { - flagsToExec = append(flagsToExec, strings.Fields(xbstreamRestoreFlags)...) + restoreFlags, err := shlex.Split(xbstreamRestoreFlags) + if err != nil { + return vterrors.Wrap(err, "failed to parse --xbstream-restore-flags") + } + flagsToExec = append(flagsToExec, restoreFlags...) } xbstreamCmd := exec.CommandContext(ctx, xbstreamProgram, flagsToExec...) logger.Infof("Executing xbstream cmd: %v %v", xbstreamProgram, flagsToExec) diff --git a/go/vt/vttablet/grpctmserver/server.go b/go/vt/vttablet/grpctmserver/server.go index 24bba022692..4d2db680276 100644 --- a/go/vt/vttablet/grpctmserver/server.go +++ b/go/vt/vttablet/grpctmserver/server.go @@ -18,6 +18,7 @@ package grpctmserver import ( "context" + "path/filepath" "time" "google.golang.org/grpc" @@ -35,6 +36,7 @@ import ( querypb "vitess.io/vitess/go/vt/proto/query" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" tabletmanagerservicepb "vitess.io/vitess/go/vt/proto/tabletmanagerservice" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) // server is the gRPC implementation of the RPC server @@ -64,6 +66,9 @@ func (s *server) Sleep(ctx context.Context, request *tabletmanagerdatapb.SleepRe func (s *server) ExecuteHook(ctx context.Context, request *tabletmanagerdatapb.ExecuteHookRequest) (response *tabletmanagerdatapb.ExecuteHookResponse, err error) { defer s.tm.HandleRPCPanic(ctx, "ExecuteHook", request, response, true /*verbose*/, &err) ctx = callinfo.GRPCCallInfo(ctx) + if request.Name == "" || filepath.Base(request.Name) != request.Name { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "hook name must be a basename, got %q", request.Name) + } response = &tabletmanagerdatapb.ExecuteHookResponse{} hr := s.tm.ExecuteHook(ctx, &hook.Hook{ Name: request.Name, diff --git a/go/vt/vttablet/tmrpctest/test_tm_rpc.go b/go/vt/vttablet/tmrpctest/test_tm_rpc.go index 45f7786debd..a6f6133431c 100644 --- a/go/vt/vttablet/tmrpctest/test_tm_rpc.go +++ b/go/vt/vttablet/tmrpctest/test_tm_rpc.go @@ -26,6 +26,7 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/protobuf/proto" @@ -580,6 +581,13 @@ func tmRPCTestExecuteHook(ctx context.Context, t *testing.T, client tmclient.Tab compareError(t, "ExecuteHook", err, hr, testExecuteHookHookResult) } +func tmRPCTestExecuteHookInvalidName(ctx context.Context, t *testing.T, client tmclient.TabletManagerClient, tablet *topodatapb.Tablet) { + for _, name := range []string{"", "../etc/passwd", "/bin/ls"} { + _, err := client.ExecuteHook(ctx, tablet, &hook.Hook{Name: name}) + assert.ErrorContains(t, err, "hook name must be a basename") + } +} + func tmRPCTestExecuteHookPanic(ctx context.Context, t *testing.T, client tmclient.TabletManagerClient, tablet *topodatapb.Tablet) { _, err := client.ExecuteHook(ctx, tablet, testExecuteHookHook) expectHandleRPCPanic(t, "ExecuteHook", true /*verbose*/, err) @@ -1554,6 +1562,7 @@ func Run(t *testing.T, client tmclient.TabletManagerClient, tablet *topodatapb.T tmRPCTestChangeType(ctx, t, client, tablet) tmRPCTestSleep(ctx, t, client, tablet) tmRPCTestExecuteHook(ctx, t, client, tablet) + tmRPCTestExecuteHookInvalidName(ctx, t, client, tablet) tmRPCTestRefreshState(ctx, t, client, tablet) tmRPCTestRunHealthCheck(ctx, t, client, tablet) tmRPCTestReloadSchema(ctx, t, client, tablet) From a2bfb2c8bc19244ad3e87f266a9bf8a3a2dcfcb6 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Thu, 26 Feb 2026 23:14:02 +0100 Subject: [PATCH 078/112] [release-22.0] docker: install mysql-shell from Oracle repo and fix shellcheck warnings (#19456) (#19463) Signed-off-by: Arthur Schreiber Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Arthur Schreiber Co-authored-by: Claude Opus 4.6 --- docker/utils/install_dependencies.sh | 80 ++++++++++++++-------------- 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/docker/utils/install_dependencies.sh b/docker/utils/install_dependencies.sh index 59e16b6303a..08ece1df515 100755 --- a/docker/utils/install_dependencies.sh +++ b/docker/utils/install_dependencies.sh @@ -39,7 +39,7 @@ do_fetch() { --retry-connrefused\ --waitretry=1\ --no-dns-cache \ - $1 -O $2 + "$1" -O "$2" } # Install base packages that are common to all flavors. @@ -75,26 +75,27 @@ mysql80) if [ -z "$VERSION" ]; then VERSION=8.0.40 fi - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-common_${VERSION}-1debian12_amd64.deb /tmp/mysql-common_${VERSION}-1debian12_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/libmysqlclient21_${VERSION}-1debian12_amd64.deb /tmp/libmysqlclient21_${VERSION}-1debian12_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-community-client-core_${VERSION}-1debian12_amd64.deb /tmp/mysql-community-client-core_${VERSION}-1debian12_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-community-client-plugins_${VERSION}-1debian12_amd64.deb /tmp/mysql-community-client-plugins_${VERSION}-1debian12_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-community-client_${VERSION}-1debian12_amd64.deb /tmp/mysql-community-client_${VERSION}-1debian12_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-client_${VERSION}-1debian12_amd64.deb /tmp/mysql-client_${VERSION}-1debian12_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-community-server-core_${VERSION}-1debian12_amd64.deb /tmp/mysql-community-server-core_${VERSION}-1debian12_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-community-server_${VERSION}-1debian12_amd64.deb /tmp/mysql-community-server_${VERSION}-1debian12_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-server_${VERSION}-1debian12_amd64.deb /tmp/mysql-server_${VERSION}-1debian12_amd64.deb + do_fetch "https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-common_${VERSION}-1debian12_amd64.deb" "/tmp/mysql-common_${VERSION}-1debian12_amd64.deb" + do_fetch "https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/libmysqlclient21_${VERSION}-1debian12_amd64.deb" "/tmp/libmysqlclient21_${VERSION}-1debian12_amd64.deb" + do_fetch "https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-community-client-core_${VERSION}-1debian12_amd64.deb" "/tmp/mysql-community-client-core_${VERSION}-1debian12_amd64.deb" + do_fetch "https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-community-client-plugins_${VERSION}-1debian12_amd64.deb" "/tmp/mysql-community-client-plugins_${VERSION}-1debian12_amd64.deb" + do_fetch "https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-community-client_${VERSION}-1debian12_amd64.deb" "/tmp/mysql-community-client_${VERSION}-1debian12_amd64.deb" + do_fetch "https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-client_${VERSION}-1debian12_amd64.deb" "/tmp/mysql-client_${VERSION}-1debian12_amd64.deb" + do_fetch "https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-community-server-core_${VERSION}-1debian12_amd64.deb" "/tmp/mysql-community-server-core_${VERSION}-1debian12_amd64.deb" + do_fetch "https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-community-server_${VERSION}-1debian12_amd64.deb" "/tmp/mysql-community-server_${VERSION}-1debian12_amd64.deb" + do_fetch "https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-server_${VERSION}-1debian12_amd64.deb" "/tmp/mysql-server_${VERSION}-1debian12_amd64.deb" + do_fetch "https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-shell/mysql-shell_${VERSION}-1debian12_amd64.deb" "/tmp/mysql-shell_${VERSION}-1debian12_amd64.deb" PACKAGES=( - /tmp/mysql-common_${VERSION}-1debian12_amd64.deb - /tmp/libmysqlclient21_${VERSION}-1debian12_amd64.deb - /tmp/mysql-community-client-core_${VERSION}-1debian12_amd64.deb - /tmp/mysql-community-client-plugins_${VERSION}-1debian12_amd64.deb - /tmp/mysql-community-client_${VERSION}-1debian12_amd64.deb - /tmp/mysql-client_${VERSION}-1debian12_amd64.deb - /tmp/mysql-community-server-core_${VERSION}-1debian12_amd64.deb - /tmp/mysql-community-server_${VERSION}-1debian12_amd64.deb - /tmp/mysql-server_${VERSION}-1debian12_amd64.deb - mysql-shell + "/tmp/mysql-common_${VERSION}-1debian12_amd64.deb" + "/tmp/libmysqlclient21_${VERSION}-1debian12_amd64.deb" + "/tmp/mysql-community-client-core_${VERSION}-1debian12_amd64.deb" + "/tmp/mysql-community-client-plugins_${VERSION}-1debian12_amd64.deb" + "/tmp/mysql-community-client_${VERSION}-1debian12_amd64.deb" + "/tmp/mysql-client_${VERSION}-1debian12_amd64.deb" + "/tmp/mysql-community-server-core_${VERSION}-1debian12_amd64.deb" + "/tmp/mysql-community-server_${VERSION}-1debian12_amd64.deb" + "/tmp/mysql-server_${VERSION}-1debian12_amd64.deb" + "/tmp/mysql-shell_${VERSION}-1debian12_amd64.deb" percona-xtrabackup-80 ) ;; @@ -102,26 +103,27 @@ mysql84) if [ -z "$VERSION" ]; then VERSION=8.4.3 fi - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/mysql-common_${VERSION}-1debian12_amd64.deb /tmp/mysql-common_${VERSION}-1debian12_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/libmysqlclient24_${VERSION}-1debian12_amd64.deb /tmp/libmysqlclient24_${VERSION}-1debian12_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/mysql-community-client-core_${VERSION}-1debian12_amd64.deb /tmp/mysql-community-client-core_${VERSION}-1debian12_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/mysql-community-client-plugins_${VERSION}-1debian12_amd64.deb /tmp/mysql-community-client-plugins_${VERSION}-1debian12_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/mysql-community-client_${VERSION}-1debian12_amd64.deb /tmp/mysql-community-client_${VERSION}-1debian12_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/mysql-client_${VERSION}-1debian12_amd64.deb /tmp/mysql-client_${VERSION}-1debian12_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/mysql-community-server-core_${VERSION}-1debian12_amd64.deb /tmp/mysql-community-server-core_${VERSION}-1debian12_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/mysql-community-server_${VERSION}-1debian12_amd64.deb /tmp/mysql-community-server_${VERSION}-1debian12_amd64.deb - do_fetch https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/mysql-server_${VERSION}-1debian12_amd64.deb /tmp/mysql-server_${VERSION}-1debian12_amd64.deb + do_fetch "https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/mysql-common_${VERSION}-1debian12_amd64.deb" "/tmp/mysql-common_${VERSION}-1debian12_amd64.deb" + do_fetch "https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/libmysqlclient24_${VERSION}-1debian12_amd64.deb" "/tmp/libmysqlclient24_${VERSION}-1debian12_amd64.deb" + do_fetch "https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/mysql-community-client-core_${VERSION}-1debian12_amd64.deb" "/tmp/mysql-community-client-core_${VERSION}-1debian12_amd64.deb" + do_fetch "https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/mysql-community-client-plugins_${VERSION}-1debian12_amd64.deb" "/tmp/mysql-community-client-plugins_${VERSION}-1debian12_amd64.deb" + do_fetch "https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/mysql-community-client_${VERSION}-1debian12_amd64.deb" "/tmp/mysql-community-client_${VERSION}-1debian12_amd64.deb" + do_fetch "https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/mysql-client_${VERSION}-1debian12_amd64.deb" "/tmp/mysql-client_${VERSION}-1debian12_amd64.deb" + do_fetch "https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/mysql-community-server-core_${VERSION}-1debian12_amd64.deb" "/tmp/mysql-community-server-core_${VERSION}-1debian12_amd64.deb" + do_fetch "https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/mysql-community-server_${VERSION}-1debian12_amd64.deb" "/tmp/mysql-community-server_${VERSION}-1debian12_amd64.deb" + do_fetch "https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-community/mysql-server_${VERSION}-1debian12_amd64.deb" "/tmp/mysql-server_${VERSION}-1debian12_amd64.deb" + do_fetch "https://repo.mysql.com/apt/debian/pool/mysql-8.4-lts/m/mysql-shell/mysql-shell_${VERSION}-1debian12_amd64.deb" "/tmp/mysql-shell_${VERSION}-1debian12_amd64.deb" PACKAGES=( - /tmp/mysql-common_${VERSION}-1debian12_amd64.deb - /tmp/libmysqlclient24_${VERSION}-1debian12_amd64.deb - /tmp/mysql-community-client-core_${VERSION}-1debian12_amd64.deb - /tmp/mysql-community-client-plugins_${VERSION}-1debian12_amd64.deb - /tmp/mysql-community-client_${VERSION}-1debian12_amd64.deb - /tmp/mysql-client_${VERSION}-1debian12_amd64.deb - /tmp/mysql-community-server-core_${VERSION}-1debian12_amd64.deb - /tmp/mysql-community-server_${VERSION}-1debian12_amd64.deb - /tmp/mysql-server_${VERSION}-1debian12_amd64.deb - mysql-shell + "/tmp/mysql-common_${VERSION}-1debian12_amd64.deb" + "/tmp/libmysqlclient24_${VERSION}-1debian12_amd64.deb" + "/tmp/mysql-community-client-core_${VERSION}-1debian12_amd64.deb" + "/tmp/mysql-community-client-plugins_${VERSION}-1debian12_amd64.deb" + "/tmp/mysql-community-client_${VERSION}-1debian12_amd64.deb" + "/tmp/mysql-client_${VERSION}-1debian12_amd64.deb" + "/tmp/mysql-community-server-core_${VERSION}-1debian12_amd64.deb" + "/tmp/mysql-community-server_${VERSION}-1debian12_amd64.deb" + "/tmp/mysql-server_${VERSION}-1debian12_amd64.deb" + "/tmp/mysql-shell_${VERSION}-1debian12_amd64.deb" percona-xtrabackup-84 ) ;; From 7ae0d1a5d6ab2c1f56e36b35ffbf324eb1821d30 Mon Sep 17 00:00:00 2001 From: Matt Lord Date: Thu, 26 Feb 2026 21:29:47 -0500 Subject: [PATCH 079/112] Add release summary for v22.0.4 (#19508) Signed-off-by: Matt Lord --- changelog/22.0/22.0.4/summary.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 changelog/22.0/22.0.4/summary.md diff --git a/changelog/22.0/22.0.4/summary.md b/changelog/22.0/22.0.4/summary.md new file mode 100644 index 00000000000..3927041651f --- /dev/null +++ b/changelog/22.0/22.0.4/summary.md @@ -0,0 +1,29 @@ +# Release of Vitess v22.0.4 + +## Summary + +This is a security focused release. It contains fixes for two recently reported CVEs along with a number of other security related fixes. + +### External Decompressor No Longer Read from Backup MANIFEST by Default + +This is a fix for the following security advisory and associated CVE + +- Advisory: +- CVE: + +The external decompressor command stored in a backup's `MANIFEST` file is no longer used at restore time by default. Previously, when no `--external-decompressor` flag was provided, VTTablet would fall back to the command specified in the `MANIFEST`. This posed a security risk: an attacker with write access to backup storage could modify the `MANIFEST` to execute arbitrary commands on the tablet. + +*Please note that this is a breaking change.* Starting in v22.0.4, the `MANIFEST`-based decompressor is ignored unless you explicitly opt in with the new `--external-decompressor-use-manifest` flag. If you rely on this behavior, add the flag to your VTTablet configuration, but be aware of the security implications. + +See [#19460](https://github.com/vitessio/vitess/pull/19460) for details. + +### Prevent Path Traversals Via Backup MANIFEST Files On restore + +This is a fix for the following security advisory and associated CVE + +- Advisory: +- CVE: + +We now prevent a common [Path Traversal attack](https://owasp.org/www-community/attacks/Path_Traversal) that someone with write access to backup storage could use to escape the target restore directory and write files to arbitrary filesystem paths via modifications to the `MANIFEST`. + +See [#19470](https://github.com/vitessio/vitess/pull/19470) for details. From fa17b71b2e09d828f5dc404e9499a387e57e4802 Mon Sep 17 00:00:00 2001 From: Matt Lord Date: Thu, 26 Feb 2026 21:32:22 -0500 Subject: [PATCH 080/112] [release-22.0] Code Freeze for `v22.0.4` (#19509) Signed-off-by: Matt Lord --- .github/workflows/code_freeze.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/code_freeze.yml b/.github/workflows/code_freeze.yml index a66fb6e8b2b..5f0ae51e0f1 100644 --- a/.github/workflows/code_freeze.yml +++ b/.github/workflows/code_freeze.yml @@ -11,4 +11,4 @@ jobs: steps: - name: Fail if Code Freeze is enabled run: | - exit 0 + exit 1 From 5b0d3ad22b7553e7a31dc1e02b8005f192cbe039 Mon Sep 17 00:00:00 2001 From: Matt Lord Date: Thu, 26 Feb 2026 21:52:41 -0500 Subject: [PATCH 081/112] [release-22.0] Release of `v22.0.4` (#19510) Signed-off-by: Matt Lord --- .github/workflows/code_freeze.yml | 2 +- changelog/22.0/22.0.4/changelog.md | 69 +++++++++++++++++++ changelog/22.0/22.0.4/release_notes.md | 37 ++++++++++ changelog/22.0/README.md | 4 ++ examples/compose/docker-compose.beginners.yml | 20 +++--- examples/compose/docker-compose.yml | 26 +++---- .../compose/vtcompose/docker-compose.test.yml | 26 +++---- examples/compose/vtcompose/vtcompose.go | 16 ++--- examples/operator/101_initial_cluster.yaml | 14 ++-- examples/operator/201_customer_tablets.yaml | 14 ++-- examples/operator/302_new_shards.yaml | 14 ++-- examples/operator/306_down_shard_0.yaml | 14 ++-- examples/operator/401_scheduled_backups.yaml | 14 ++-- go/vt/servenv/version.go | 2 +- java/client/pom.xml | 2 +- java/example/pom.xml | 2 +- java/grpc-client/pom.xml | 2 +- java/jdbc/pom.xml | 2 +- java/pom.xml | 2 +- 19 files changed, 196 insertions(+), 86 deletions(-) create mode 100644 changelog/22.0/22.0.4/changelog.md create mode 100644 changelog/22.0/22.0.4/release_notes.md diff --git a/.github/workflows/code_freeze.yml b/.github/workflows/code_freeze.yml index 5f0ae51e0f1..a66fb6e8b2b 100644 --- a/.github/workflows/code_freeze.yml +++ b/.github/workflows/code_freeze.yml @@ -11,4 +11,4 @@ jobs: steps: - name: Fail if Code Freeze is enabled run: | - exit 1 + exit 0 diff --git a/changelog/22.0/22.0.4/changelog.md b/changelog/22.0/22.0.4/changelog.md new file mode 100644 index 00000000000..2521697b052 --- /dev/null +++ b/changelog/22.0/22.0.4/changelog.md @@ -0,0 +1,69 @@ +# Changelog of Vitess v22.0.4 + +### Bug fixes +#### Backup and Restore + * [release-22.0] fix(backup): propagate file hashes to manifest after retry (#19336) [#19343](https://github.com/vitessio/vitess/pull/19343) +#### Docker + * [release-22.0] docker: install mysql-shell from Oracle repo and fix shellcheck warnings (#19456) [#19463](https://github.com/vitessio/vitess/pull/19463) +#### Online DDL + * [release-22.0] vreplication: fix infinite retry loop when terminal error message contains binary data (#19423) [#19437](https://github.com/vitessio/vitess/pull/19437) +#### Query Serving + * [release-22.0] vtgate: defer implicit transaction start until after query planning (#19277) [#19341](https://github.com/vitessio/vitess/pull/19341) +#### VDiff + * [release-22.0] Address a few VDiff concerns (#19413) [#19447](https://github.com/vitessio/vitess/pull/19447) +#### VReplication + * [release-22.0] Bug fix: Add missing db_name filters to vreplication and vdiff queries #19378 [#19430](https://github.com/vitessio/vitess/pull/19430) + * [release-22.0] Normalize the --on-ddl param for MoveTables (#19445) [#19451](https://github.com/vitessio/vitess/pull/19451) +#### VTGate + * [release-22.0] vtgate: Add bounds check in `visitUnion` for mismatched column counts (#19476) [#19482](https://github.com/vitessio/vitess/pull/19482) +#### VTOrc + * [release-22.0] vtorc: Add a timeout to `DemotePrimary` RPC (#19432) [#19449](https://github.com/vitessio/vitess/pull/19449) +#### schema management + * [release-22.0] sidecardb: make ALTER TABLE algorithm version-aware (#19358) [#19403](https://github.com/vitessio/vitess/pull/19403) +### CI/Build +#### Build/CI + * [release-22.0] Consolidate CI test workflows (#19259) [#19272](https://github.com/vitessio/vitess/pull/19272) + * [release-22.0] Run tests with gotestsum (#19076) [#19292](https://github.com/vitessio/vitess/pull/19292) + * [release-22.0] Fix go upgrade tool (#19290) [#19298](https://github.com/vitessio/vitess/pull/19298) + * [release-22.0] Switch gotestsum output format (#19215) [#19302](https://github.com/vitessio/vitess/pull/19302) + * [release-22.0] Build boostrap image for local/region example CI (#19310) [#19316](https://github.com/vitessio/vitess/pull/19316) + * [release-22.0] Don't add "Skip CI" label for Go upgrade PRs (#19307) [#19322](https://github.com/vitessio/vitess/pull/19322) + * [release-22.0] Explicitly pass local image tags in example CI (#19320) [#19325](https://github.com/vitessio/vitess/pull/19325) + * [release-22.0] Add lite image build CI job (#19321) [#19329](https://github.com/vitessio/vitess/pull/19329) + * [release-22.0] try to fix setup mysql (#19371) [#19375](https://github.com/vitessio/vitess/pull/19375) + * [release-22.0] CI: Fix workflows that install xtrabackup (#19383) [#19384](https://github.com/vitessio/vitess/pull/19384) +#### Docker + * [release-22.0] Build bootstrap image locally in ci (#19255) [#19265](https://github.com/vitessio/vitess/pull/19265) +### Compatibility Bug +#### Query Serving + * [release-22.0] fix streaming binary row corruption in prepared statements (#19381) [#19414](https://github.com/vitessio/vitess/pull/19414) +#### VTGate + * [release-22.0] vtgate: fix handling of session variables on targeted connections (#19318) [#19334](https://github.com/vitessio/vitess/pull/19334) +### Dependencies +#### Docker + * [release-22.0] Upgrade the Golang version to `go1.24.13` [#19305](https://github.com/vitessio/vitess/pull/19305) +### Enhancement +#### VTGate + * [release-22.0] Performance: use `IsSingleShard()` check in `pushDerived` instead of just `engine.EqualUnique` opcode (#18974) [#19345](https://github.com/vitessio/vitess/pull/19345) +### Release +#### Build/CI + * [release-22.0] Code Freeze for `v22.0.4` [#19509](https://github.com/vitessio/vitess/pull/19509) +#### Documentation + * Add release summary for v22.0.4 [#19508](https://github.com/vitessio/vitess/pull/19508) +#### General + * [release-22.0] Bump to `v22.0.4-SNAPSHOT` after the `v22.0.3` release [#19284](https://github.com/vitessio/vitess/pull/19284) +### Security +#### Backup and Restore + * [release-22.0] Restore: make loading compressor commands from `MANIFEST` opt-in (#19460) [#19473](https://github.com/vitessio/vitess/pull/19473) + * [release-22.0] `backupengine`: disallow path traversals via backup `MANIFEST` on restore (#19470) [#19477](https://github.com/vitessio/vitess/pull/19477) + * [release-22.0] `mysqlshellbackupengine`: use `fileutil.SafePathJoin(...)` to build path (#19484) [#19490](https://github.com/vitessio/vitess/pull/19490) +#### VTTablet + * [release-22.0] `filebackupstorage`: use `fileutil.SafePathJoin` for all path building (#19479) [#19480](https://github.com/vitessio/vitess/pull/19480) + * [release-22.0] `vttablet`: harden `ExecuteHook` RPC and backup engine flag inputs (#19486) [#19500](https://github.com/vitessio/vitess/pull/19500) +### Testing +#### Build/CI + * [release-22.0] Generate race unit tests (#19078) [#19295](https://github.com/vitessio/vitess/pull/19295) + * [release-22.0] CI: Deflake Code Coverage workflow (#19388) [#19393](https://github.com/vitessio/vitess/pull/19393) + * [release-22.0] CI: Deflake two flaky tests (#19364) [#19411](https://github.com/vitessio/vitess/pull/19411) + * [release-22.0] CI: Use larger runners for vreplication workflows (#19433) [#19434](https://github.com/vitessio/vitess/pull/19434) + diff --git a/changelog/22.0/22.0.4/release_notes.md b/changelog/22.0/22.0.4/release_notes.md new file mode 100644 index 00000000000..31c8ec20d50 --- /dev/null +++ b/changelog/22.0/22.0.4/release_notes.md @@ -0,0 +1,37 @@ +# Release of Vitess v22.0.4 + +## Summary + +This is a security focused release. It contains fixes for two recently reported CVEs along with a number of other security related fixes. + +### External Decompressor No Longer Read from Backup MANIFEST by Default + +This is a fix for the following security advisory and associated CVE + +- Advisory: +- CVE: + +The external decompressor command stored in a backup's `MANIFEST` file is no longer used at restore time by default. Previously, when no `--external-decompressor` flag was provided, VTTablet would fall back to the command specified in the `MANIFEST`. This posed a security risk: an attacker with write access to backup storage could modify the `MANIFEST` to execute arbitrary commands on the tablet. + +*Please note that this is a breaking change.* Starting in v22.0.4, the `MANIFEST`-based decompressor is ignored unless you explicitly opt in with the new `--external-decompressor-use-manifest` flag. If you rely on this behavior, add the flag to your VTTablet configuration, but be aware of the security implications. + +See [#19460](https://github.com/vitessio/vitess/pull/19460) for details. + +### Prevent Path Traversals Via Backup MANIFEST Files On restore + +This is a fix for the following security advisory and associated CVE + +- Advisory: +- CVE: + +We now prevent a common [Path Traversal attack](https://owasp.org/www-community/attacks/Path_Traversal) that someone with write access to backup storage could use to escape the target restore directory and write files to arbitrary filesystem paths via modifications to the `MANIFEST`. + +See [#19470](https://github.com/vitessio/vitess/pull/19470) for details. + +------------ +The entire changelog for this release can be found [here](https://github.com/vitessio/vitess/blob/main/changelog/22.0/22.0.4/changelog.md). + +The release includes 37 merged Pull Requests. + +Thanks to all our contributors: @app/vitess-bot, @mattlord, @vitess-bot + diff --git a/changelog/22.0/README.md b/changelog/22.0/README.md index 272a2f335d6..11745abb642 100644 --- a/changelog/22.0/README.md +++ b/changelog/22.0/README.md @@ -1,4 +1,8 @@ ## v22.0 +* **[22.0.4](22.0.4)** + * [Changelog](22.0.4/changelog.md) + * [Release Notes](22.0.4/release_notes.md) + * **[22.0.3](22.0.3)** * [Changelog](22.0.3/changelog.md) * [Release Notes](22.0.3/release_notes.md) diff --git a/examples/compose/docker-compose.beginners.yml b/examples/compose/docker-compose.beginners.yml index 213ae433fd9..a87c0b1a83b 100644 --- a/examples/compose/docker-compose.beginners.yml +++ b/examples/compose/docker-compose.beginners.yml @@ -58,7 +58,7 @@ services: - "3306" vtctld: - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - "15000:$WEB_PORT" - "$GRPC_PORT" @@ -83,7 +83,7 @@ services: condition: service_healthy vtgate: - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - "15099:$WEB_PORT" - "$GRPC_PORT" @@ -113,7 +113,7 @@ services: condition: service_healthy schemaload: - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 command: - sh - -c @@ -146,12 +146,12 @@ services: environment: - KEYSPACES=$KEYSPACE - GRPC_PORT=15999 - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 volumes: - .:/script vttablet100: - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - "15100:$WEB_PORT" - "$GRPC_PORT" @@ -183,7 +183,7 @@ services: retries: 15 vttablet101: - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - "15101:$WEB_PORT" - "$GRPC_PORT" @@ -215,7 +215,7 @@ services: retries: 15 vttablet102: - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - "15102:$WEB_PORT" - "$GRPC_PORT" @@ -247,7 +247,7 @@ services: retries: 15 vttablet103: - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - "15103:$WEB_PORT" - "$GRPC_PORT" @@ -279,7 +279,7 @@ services: retries: 15 vtorc: - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 command: ["sh", "-c", "/script/vtorc-up.sh"] depends_on: - vtctld @@ -309,7 +309,7 @@ services: retries: 15 vreplication: - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 volumes: - ".:/script" environment: diff --git a/examples/compose/docker-compose.yml b/examples/compose/docker-compose.yml index 548f3b52ac3..9643f8502e8 100644 --- a/examples/compose/docker-compose.yml +++ b/examples/compose/docker-compose.yml @@ -75,7 +75,7 @@ services: - SCHEMA_FILES=lookup_keyspace_schema_file.sql - POST_LOAD_FILE= - EXTERNAL_DB=0 - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 volumes: - .:/script schemaload_test_keyspace: @@ -101,7 +101,7 @@ services: - SCHEMA_FILES=test_keyspace_schema_file.sql - POST_LOAD_FILE= - EXTERNAL_DB=0 - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 volumes: - .:/script set_keyspace_durability_policy: @@ -115,7 +115,7 @@ services: environment: - KEYSPACES=test_keyspace lookup_keyspace - GRPC_PORT=15999 - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 volumes: - .:/script vreplication: @@ -129,7 +129,7 @@ services: - TOPOLOGY_FLAGS=--topo_implementation consul --topo_global_server_address consul1:8500 --topo_global_root vitess/global - EXTERNAL_DB=0 - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 volumes: - .:/script vtctld: @@ -143,7 +143,7 @@ services: depends_on: external_db_host: condition: service_healthy - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - 15000:8080 - "15999" @@ -160,7 +160,7 @@ services: --normalize_queries=true ' depends_on: - vtctld - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - 15099:8080 - "15999" @@ -182,7 +182,7 @@ services: - EXTERNAL_DB=0 - DB_USER= - DB_PASS= - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - 13000:8080 volumes: @@ -217,7 +217,7 @@ services: - CMD-SHELL - curl -s --fail --show-error localhost:8080/debug/health timeout: 10s - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - 15101:8080 - "15999" @@ -254,7 +254,7 @@ services: - CMD-SHELL - curl -s --fail --show-error localhost:8080/debug/health timeout: 10s - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - 15102:8080 - "15999" @@ -291,7 +291,7 @@ services: - CMD-SHELL - curl -s --fail --show-error localhost:8080/debug/health timeout: 10s - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - 15201:8080 - "15999" @@ -328,7 +328,7 @@ services: - CMD-SHELL - curl -s --fail --show-error localhost:8080/debug/health timeout: 10s - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - 15202:8080 - "15999" @@ -365,7 +365,7 @@ services: - CMD-SHELL - curl -s --fail --show-error localhost:8080/debug/health timeout: 10s - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - 15301:8080 - "15999" @@ -402,7 +402,7 @@ services: - CMD-SHELL - curl -s --fail --show-error localhost:8080/debug/health timeout: 10s - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - 15302:8080 - "15999" diff --git a/examples/compose/vtcompose/docker-compose.test.yml b/examples/compose/vtcompose/docker-compose.test.yml index 0bad4b1ded3..65ddc1feba0 100644 --- a/examples/compose/vtcompose/docker-compose.test.yml +++ b/examples/compose/vtcompose/docker-compose.test.yml @@ -79,7 +79,7 @@ services: - SCHEMA_FILES=test_keyspace_schema_file.sql - POST_LOAD_FILE= - EXTERNAL_DB=0 - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 volumes: - .:/script schemaload_unsharded_keyspace: @@ -103,7 +103,7 @@ services: - SCHEMA_FILES=unsharded_keyspace_schema_file.sql - POST_LOAD_FILE= - EXTERNAL_DB=0 - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 volumes: - .:/script set_keyspace_durability_policy_test_keyspace: @@ -117,7 +117,7 @@ services: environment: - GRPC_PORT=15999 - KEYSPACES=test_keyspace - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 volumes: - .:/script set_keyspace_durability_policy_unsharded_keyspace: @@ -130,7 +130,7 @@ services: environment: - GRPC_PORT=15999 - KEYSPACES=unsharded_keyspace - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 volumes: - .:/script vreplication: @@ -144,7 +144,7 @@ services: - TOPOLOGY_FLAGS=--topo_implementation consul --topo_global_server_address consul1:8500 --topo_global_root vitess/global - EXTERNAL_DB=0 - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 volumes: - .:/script vtctld: @@ -159,7 +159,7 @@ services: depends_on: external_db_host: condition: service_healthy - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - 15000:8080 - "15999" @@ -176,7 +176,7 @@ services: ''grpc-vtgateservice'' --normalize_queries=true ' depends_on: - vtctld - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - 15099:8080 - "15999" @@ -199,7 +199,7 @@ services: - EXTERNAL_DB=0 - DB_USER= - DB_PASS= - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - 13000:8080 volumes: @@ -234,7 +234,7 @@ services: - CMD-SHELL - curl -s --fail --show-error localhost:8080/debug/health timeout: 10s - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - 15101:8080 - "15999" @@ -271,7 +271,7 @@ services: - CMD-SHELL - curl -s --fail --show-error localhost:8080/debug/health timeout: 10s - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - 15102:8080 - "15999" @@ -308,7 +308,7 @@ services: - CMD-SHELL - curl -s --fail --show-error localhost:8080/debug/health timeout: 10s - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - 15201:8080 - "15999" @@ -345,7 +345,7 @@ services: - CMD-SHELL - curl -s --fail --show-error localhost:8080/debug/health timeout: 10s - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - 15202:8080 - "15999" @@ -382,7 +382,7 @@ services: - CMD-SHELL - curl -s --fail --show-error localhost:8080/debug/health timeout: 10s - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - 15301:8080 - "15999" diff --git a/examples/compose/vtcompose/vtcompose.go b/examples/compose/vtcompose/vtcompose.go index ec3137ae4c8..a0b7fbc092a 100644 --- a/examples/compose/vtcompose/vtcompose.go +++ b/examples/compose/vtcompose/vtcompose.go @@ -525,7 +525,7 @@ func generateExternalPrimary( - op: add path: /services/vttablet%[1]d value: - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - "15%[1]d:%[3]d" - "%[4]d" @@ -587,7 +587,7 @@ func generateDefaultTablet(tabAlias int, shard, role, keyspace string, dbInfo ex - op: add path: /services/vttablet%[1]d value: - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - "15%[1]d:%[4]d" - "%[5]d" @@ -625,7 +625,7 @@ func generateVtctld(opts vtOptions) string { - op: add path: /services/vtctld value: - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - "15000:%[1]d" - "%[2]d" @@ -656,7 +656,7 @@ func generateVtgate(opts vtOptions) string { - op: add path: /services/vtgate value: - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 ports: - "15099:%[1]d" - "%[2]d" @@ -698,7 +698,7 @@ func generateVTOrc(dbInfo externalDbInfo, keyspaceInfoMap map[string]keyspaceInf - op: add path: /services/vtorc value: - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 volumes: - ".:/script" environment: @@ -723,7 +723,7 @@ func generateVreplication(dbInfo externalDbInfo, opts vtOptions) string { - op: add path: /services/vreplication value: - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 volumes: - ".:/script" environment: @@ -751,7 +751,7 @@ func generateSetKeyspaceDurabilityPolicy( - op: add path: /services/set_keyspace_durability_policy_%[3]s value: - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 volumes: - ".:/script" environment: @@ -788,7 +788,7 @@ func generateSchemaload( - op: add path: /services/schemaload_%[7]s value: - image: vitess/lite:v22.0.3 + image: vitess/lite:v22.0.4 volumes: - ".:/script" environment: diff --git a/examples/operator/101_initial_cluster.yaml b/examples/operator/101_initial_cluster.yaml index e50a36cc9a8..bc546b193db 100644 --- a/examples/operator/101_initial_cluster.yaml +++ b/examples/operator/101_initial_cluster.yaml @@ -16,14 +16,14 @@ spec: path: /tmp type: Directory images: - vtctld: vitess/lite:v22.0.3 - vtadmin: vitess/vtadmin:v22.0.3 - vtgate: vitess/lite:v22.0.3 - vttablet: vitess/lite:v22.0.3 - vtbackup: vitess/lite:v22.0.3 - vtorc: vitess/lite:v22.0.3 + vtctld: vitess/lite:v22.0.4 + vtadmin: vitess/vtadmin:v22.0.4 + vtgate: vitess/lite:v22.0.4 + vttablet: vitess/lite:v22.0.4 + vtbackup: vitess/lite:v22.0.4 + vtorc: vitess/lite:v22.0.4 mysqld: - mysql80Compatible: vitess/lite:v22.0.3 + mysql80Compatible: vitess/lite:v22.0.4 mysqldExporter: prom/mysqld-exporter:v0.14.0 cells: - name: zone1 diff --git a/examples/operator/201_customer_tablets.yaml b/examples/operator/201_customer_tablets.yaml index ed70a2cfd81..6ecbe613718 100644 --- a/examples/operator/201_customer_tablets.yaml +++ b/examples/operator/201_customer_tablets.yaml @@ -12,14 +12,14 @@ spec: path: /tmp type: Directory images: - vtctld: vitess/lite:v22.0.3 - vtadmin: vitess/vtadmin:v22.0.3 - vtgate: vitess/lite:v22.0.3 - vttablet: vitess/lite:v22.0.3 - vtbackup: vitess/lite:v22.0.3 - vtorc: vitess/lite:v22.0.3 + vtctld: vitess/lite:v22.0.4 + vtadmin: vitess/vtadmin:v22.0.4 + vtgate: vitess/lite:v22.0.4 + vttablet: vitess/lite:v22.0.4 + vtbackup: vitess/lite:v22.0.4 + vtorc: vitess/lite:v22.0.4 mysqld: - mysql80Compatible: vitess/lite:v22.0.3 + mysql80Compatible: vitess/lite:v22.0.4 mysqldExporter: prom/mysqld-exporter:v0.14.0 cells: - name: zone1 diff --git a/examples/operator/302_new_shards.yaml b/examples/operator/302_new_shards.yaml index bc8c43a40e5..04f93836693 100644 --- a/examples/operator/302_new_shards.yaml +++ b/examples/operator/302_new_shards.yaml @@ -12,14 +12,14 @@ spec: path: /tmp type: Directory images: - vtctld: vitess/lite:v22.0.3 - vtadmin: vitess/vtadmin:v22.0.3 - vtgate: vitess/lite:v22.0.3 - vttablet: vitess/lite:v22.0.3 - vtbackup: vitess/lite:v22.0.3 - vtorc: vitess/lite:v22.0.3 + vtctld: vitess/lite:v22.0.4 + vtadmin: vitess/vtadmin:v22.0.4 + vtgate: vitess/lite:v22.0.4 + vttablet: vitess/lite:v22.0.4 + vtbackup: vitess/lite:v22.0.4 + vtorc: vitess/lite:v22.0.4 mysqld: - mysql80Compatible: vitess/lite:v22.0.3 + mysql80Compatible: vitess/lite:v22.0.4 mysqldExporter: prom/mysqld-exporter:v0.14.0 cells: - name: zone1 diff --git a/examples/operator/306_down_shard_0.yaml b/examples/operator/306_down_shard_0.yaml index 5426c6bd72e..fc926303719 100644 --- a/examples/operator/306_down_shard_0.yaml +++ b/examples/operator/306_down_shard_0.yaml @@ -12,14 +12,14 @@ spec: path: /tmp type: Directory images: - vtctld: vitess/lite:v22.0.3 - vtadmin: vitess/vtadmin:v22.0.3 - vtgate: vitess/lite:v22.0.3 - vttablet: vitess/lite:v22.0.3 - vtbackup: vitess/lite:v22.0.3 - vtorc: vitess/lite:v22.0.3 + vtctld: vitess/lite:v22.0.4 + vtadmin: vitess/vtadmin:v22.0.4 + vtgate: vitess/lite:v22.0.4 + vttablet: vitess/lite:v22.0.4 + vtbackup: vitess/lite:v22.0.4 + vtorc: vitess/lite:v22.0.4 mysqld: - mysql80Compatible: vitess/lite:v22.0.3 + mysql80Compatible: vitess/lite:v22.0.4 mysqldExporter: prom/mysqld-exporter:v0.14.0 cells: - name: zone1 diff --git a/examples/operator/401_scheduled_backups.yaml b/examples/operator/401_scheduled_backups.yaml index 84c255ac859..a081fcc0cd5 100644 --- a/examples/operator/401_scheduled_backups.yaml +++ b/examples/operator/401_scheduled_backups.yaml @@ -46,14 +46,14 @@ spec: keyspace: "customer" shard: "-80" images: - vtctld: vitess/lite:v22.0.3 - vtadmin: vitess/vtadmin:v22.0.3 - vtgate: vitess/lite:v22.0.3 - vttablet: vitess/lite:v22.0.3 - vtbackup: vitess/lite:v22.0.3 - vtorc: vitess/lite:v22.0.3 + vtctld: vitess/lite:v22.0.4 + vtadmin: vitess/vtadmin:v22.0.4 + vtgate: vitess/lite:v22.0.4 + vttablet: vitess/lite:v22.0.4 + vtbackup: vitess/lite:v22.0.4 + vtorc: vitess/lite:v22.0.4 mysqld: - mysql80Compatible: vitess/lite:v22.0.3 + mysql80Compatible: vitess/lite:v22.0.4 mysqldExporter: prom/mysqld-exporter:v0.14.0 cells: - name: zone1 diff --git a/go/vt/servenv/version.go b/go/vt/servenv/version.go index ff1acc10527..f3a8a4a8ca2 100644 --- a/go/vt/servenv/version.go +++ b/go/vt/servenv/version.go @@ -19,4 +19,4 @@ package servenv // DO NOT EDIT // THIS FILE IS AUTO-GENERATED DURING NEW RELEASES BY THE VITESS-RELEASER -const versionName = "22.0.4-SNAPSHOT" +const versionName = "22.0.4" diff --git a/java/client/pom.xml b/java/client/pom.xml index f0c44682b15..fc2d732722a 100644 --- a/java/client/pom.xml +++ b/java/client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 22.0.4-SNAPSHOT + 22.0.4 vitess-client Vitess Java Client diff --git a/java/example/pom.xml b/java/example/pom.xml index 41eec3e319e..1b12493a609 100644 --- a/java/example/pom.xml +++ b/java/example/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 22.0.4-SNAPSHOT + 22.0.4 vitess-example Vitess Java Client Example diff --git a/java/grpc-client/pom.xml b/java/grpc-client/pom.xml index 69e9e71bf47..4aeb77da39d 100644 --- a/java/grpc-client/pom.xml +++ b/java/grpc-client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 22.0.4-SNAPSHOT + 22.0.4 vitess-grpc-client Vitess gRPC Client diff --git a/java/jdbc/pom.xml b/java/jdbc/pom.xml index 006d8bcaeb9..1e687d5edb4 100644 --- a/java/jdbc/pom.xml +++ b/java/jdbc/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 22.0.4-SNAPSHOT + 22.0.4 vitess-jdbc Vitess JDBC Driver diff --git a/java/pom.xml b/java/pom.xml index ed6990a508b..1ac3543848d 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -11,7 +11,7 @@ io.vitess vitess-parent - 22.0.4-SNAPSHOT + 22.0.4 pom Vitess Java Client libraries [Parent] From 1634bad7f20d302122ae6af6ea81f7a40cf105da Mon Sep 17 00:00:00 2001 From: Matt Lord Date: Thu, 26 Feb 2026 22:15:31 -0500 Subject: [PATCH 082/112] [release-22.0] Bump to `v22.0.5-SNAPSHOT` after the `v22.0.4` release (#19512) Signed-off-by: Matt Lord --- go/vt/servenv/version.go | 2 +- java/client/pom.xml | 2 +- java/example/pom.xml | 2 +- java/grpc-client/pom.xml | 2 +- java/jdbc/pom.xml | 2 +- java/pom.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go/vt/servenv/version.go b/go/vt/servenv/version.go index f3a8a4a8ca2..861a7f29285 100644 --- a/go/vt/servenv/version.go +++ b/go/vt/servenv/version.go @@ -19,4 +19,4 @@ package servenv // DO NOT EDIT // THIS FILE IS AUTO-GENERATED DURING NEW RELEASES BY THE VITESS-RELEASER -const versionName = "22.0.4" +const versionName = "22.0.5-SNAPSHOT" diff --git a/java/client/pom.xml b/java/client/pom.xml index fc2d732722a..ef8a897dc8d 100644 --- a/java/client/pom.xml +++ b/java/client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 22.0.4 + 22.0.5-SNAPSHOT vitess-client Vitess Java Client diff --git a/java/example/pom.xml b/java/example/pom.xml index 1b12493a609..7815f342ba8 100644 --- a/java/example/pom.xml +++ b/java/example/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 22.0.4 + 22.0.5-SNAPSHOT vitess-example Vitess Java Client Example diff --git a/java/grpc-client/pom.xml b/java/grpc-client/pom.xml index 4aeb77da39d..9ce2b4bb6a9 100644 --- a/java/grpc-client/pom.xml +++ b/java/grpc-client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 22.0.4 + 22.0.5-SNAPSHOT vitess-grpc-client Vitess gRPC Client diff --git a/java/jdbc/pom.xml b/java/jdbc/pom.xml index 1e687d5edb4..01970830792 100644 --- a/java/jdbc/pom.xml +++ b/java/jdbc/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 22.0.4 + 22.0.5-SNAPSHOT vitess-jdbc Vitess JDBC Driver diff --git a/java/pom.xml b/java/pom.xml index 1ac3543848d..2ed1dcc3d28 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -11,7 +11,7 @@ io.vitess vitess-parent - 22.0.4 + 22.0.5-SNAPSHOT pom Vitess Java Client libraries [Parent] From 992254bc1e9f15fbcc0ad01da9105a7f19f0bd92 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Fri, 27 Feb 2026 18:42:09 +0000 Subject: [PATCH 083/112] [release-22.0] `vtorc`: improve logging in `DiscoverInstance`, remove old metric (#19010) (#19516) Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Mohamed Hamza --- go/vt/vtorc/logic/vtorc.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/go/vt/vtorc/logic/vtorc.go b/go/vt/vtorc/logic/vtorc.go index 45568cd745c..e76d04ccab4 100644 --- a/go/vt/vtorc/logic/vtorc.go +++ b/go/vt/vtorc/logic/vtorc.go @@ -201,8 +201,10 @@ func DiscoverInstance(tabletAlias string, forceDiscovery bool) { discoverInstanceTimings.Add("Instance", instanceLatency) discoverInstanceTimings.Add("Other", otherLatency) - if forceDiscovery { - log.Infof("Force discovered - %+v, err - %v", instance, err) + if err != nil { + log.Errorf("Failed to discover %s (force: %t), err: %v", tabletAlias, forceDiscovery, err) + } else { + log.Infof("Discovered %s (force: %t): %+v", tabletAlias, forceDiscovery, instance) } if instance == nil { @@ -217,7 +219,7 @@ func DiscoverInstance(tabletAlias string, forceDiscovery bool) { } _ = discoveryMetrics.Append(metric) if util.ClearToLog("discoverInstance", tabletAlias) { - log.Warningf(" DiscoverInstance(%+v) instance is nil in %.3fs (Backend: %.3fs, Instance: %.3fs), error=%+v", + log.Warningf("DiscoverInstance(%+v) instance is nil in %.3fs (Backend: %.3fs, Instance: %.3fs), error=%+v", tabletAlias, totalLatency.Seconds(), backendLatency.Seconds(), From dc6de33160ffbb4f57272e43ef6e42e21876671c Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Wed, 4 Mar 2026 17:18:28 +0000 Subject: [PATCH 084/112] [release-22.0] vtorc: add timeout helpers for remaining recovery topo/tmc calls (#19520) (#19558) Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Mohamed Hamza --- go/vt/vtorc/logic/tablet_discovery.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/go/vt/vtorc/logic/tablet_discovery.go b/go/vt/vtorc/logic/tablet_discovery.go index eee788bd9aa..694a03b675c 100644 --- a/go/vt/vtorc/logic/tablet_discovery.go +++ b/go/vt/vtorc/logic/tablet_discovery.go @@ -286,7 +286,7 @@ func refreshTabletInfoOfShard(ctx context.Context, keyspace, shard string) { } func refreshTabletsInKeyspaceShard(ctx context.Context, keyspace, shard string, loader func(tabletAlias string), forceRefresh bool, tabletsToIgnore []string) { - tablets, err := ts.GetTabletsByShard(ctx, keyspace, shard) + tablets, err := getShardTablets(ctx, keyspace, shard) if err != nil { log.Errorf("Error fetching tablets for keyspace/shard %v/%v: %v", keyspace, shard, err) return @@ -296,6 +296,14 @@ func refreshTabletsInKeyspaceShard(ctx context.Context, keyspace, shard string, refreshTablets(tablets, query, args, loader, forceRefresh, tabletsToIgnore) } +// getShardTablets gets tablets for the given keyspace and shard with a timeout. +func getShardTablets(ctx context.Context, keyspace, shard string) ([]*topo.TabletInfo, error) { + ctx, cancel := context.WithTimeout(ctx, topo.RemoteOperationTimeout) + defer cancel() + + return ts.GetTabletsByShard(ctx, keyspace, shard) +} + func refreshTablets(tablets []*topo.TabletInfo, query string, args []any, loader func(tabletAlias string), forceRefresh bool, tabletsToIgnore []string) { // Discover new tablets. latestInstances := make(map[string]bool) From e578cf4242fff11bfb8fac1ae8a02be93648abaa Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Thu, 5 Mar 2026 21:45:29 +0000 Subject: [PATCH 085/112] [release-22.0] vtgate: Reject unqualified `*` after comma in `SELECT` list (#19475) (#19583) Signed-off-by: Arthur Schreiber Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Arthur Schreiber --- go/vt/sqlparser/parse_test.go | 6 + go/vt/sqlparser/sql.go | 1468 +++++++++-------- go/vt/sqlparser/sql.y | 4 + .../planbuilder/testdata/dml_cases.json | 2 +- .../testdata/unknown_schema_cases.json | 2 +- go/vt/vtgate/semantics/early_rewriter_test.go | 4 - .../vreplication/replicator_plan_test.go | 2 +- .../vstreamer/planbuilder_test.go | 2 +- 8 files changed, 750 insertions(+), 740 deletions(-) diff --git a/go/vt/sqlparser/parse_test.go b/go/vt/sqlparser/parse_test.go index 4099e9f91fe..0ad5202a34a 100644 --- a/go/vt/sqlparser/parse_test.go +++ b/go/vt/sqlparser/parse_test.go @@ -6337,6 +6337,12 @@ var ( }, { input: "insert into t1 (a1) values row('a'), ('b')", output: "syntax error at position 39", + }, { + input: "select a, * from t", + output: "syntax error: unexpected '*' at position 12", + }, { + input: "select *, * from t", + output: "syntax error: unexpected '*' at position 12", }} ) diff --git a/go/vt/sqlparser/sql.go b/go/vt/sqlparser/sql.go index 5df698e434d..af1b78a4cef 100644 --- a/go/vt/sqlparser/sql.go +++ b/go/vt/sqlparser/sql.go @@ -8542,7 +8542,7 @@ var yyPgo = [...]int{ 139, 2815, 227, } -//line sql.y:9280 +//line sql.y:9284 type yySymType struct { union any empty struct{} @@ -18476,6 +18476,10 @@ yydefault: var yyLOCAL *SelectExprs //line sql.y:5296 { + if starExpr, ok := yyDollar[3].selectExprUnion().(*StarExpr); ok && starExpr.TableName.IsEmpty() { + yylex.Error("syntax error: unexpected '*'") + return 1 + } res := yyDollar[1].selectExprsUnion() res.Exprs = append(res.Exprs, yyDollar[3].selectExprUnion()) yyLOCAL = res @@ -18484,7 +18488,7 @@ yydefault: case 997: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:5304 +//line sql.y:5308 { yyLOCAL = &StarExpr{} } @@ -18492,7 +18496,7 @@ yydefault: case 998: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:5308 +//line sql.y:5312 { yyLOCAL = &AliasedExpr{Expr: yyDollar[1].exprUnion(), As: yyDollar[2].identifierCI} } @@ -18500,7 +18504,7 @@ yydefault: case 999: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:5312 +//line sql.y:5316 { yyLOCAL = &StarExpr{TableName: TableName{Name: yyDollar[1].identifierCS}} } @@ -18508,39 +18512,39 @@ yydefault: case 1000: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:5316 +//line sql.y:5320 { yyLOCAL = &StarExpr{TableName: TableName{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCS}} } yyVAL.union = yyLOCAL case 1001: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5321 +//line sql.y:5325 { yyVAL.identifierCI = IdentifierCI{} } case 1002: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5325 +//line sql.y:5329 { yyVAL.identifierCI = yyDollar[1].identifierCI } case 1003: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5329 +//line sql.y:5333 { yyVAL.identifierCI = yyDollar[2].identifierCI } case 1005: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5336 +//line sql.y:5340 { yyVAL.identifierCI = NewIdentifierCI(string(yyDollar[1].str)) } case 1006: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL TableExprs -//line sql.y:5341 +//line sql.y:5345 { yyLOCAL = TableExprs{&AliasedTableExpr{Expr: TableName{Name: NewIdentifierCS("dual")}}} } @@ -18548,7 +18552,7 @@ yydefault: case 1007: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExprs -//line sql.y:5345 +//line sql.y:5349 { yyLOCAL = yyDollar[1].tableExprsUnion() } @@ -18556,7 +18560,7 @@ yydefault: case 1008: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL TableExprs -//line sql.y:5351 +//line sql.y:5355 { yyLOCAL = yyDollar[2].tableExprsUnion() } @@ -18564,14 +18568,14 @@ yydefault: case 1009: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExprs -//line sql.y:5357 +//line sql.y:5361 { yyLOCAL = TableExprs{yyDollar[1].tableExprUnion()} } yyVAL.union = yyLOCAL case 1010: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5361 +//line sql.y:5365 { yySLICE := (*TableExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableExprUnion()) @@ -18579,7 +18583,7 @@ yydefault: case 1013: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5371 +//line sql.y:5375 { yyLOCAL = yyDollar[1].aliasedTableNameUnion() } @@ -18587,7 +18591,7 @@ yydefault: case 1014: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5375 +//line sql.y:5379 { yyLOCAL = &AliasedTableExpr{Expr: yyDollar[1].derivedTableUnion(), As: yyDollar[3].identifierCS, Columns: yyDollar[4].columnsUnion()} } @@ -18595,7 +18599,7 @@ yydefault: case 1015: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5379 +//line sql.y:5383 { yyLOCAL = &ParenTableExpr{Exprs: yyDollar[2].tableExprsUnion()} } @@ -18603,7 +18607,7 @@ yydefault: case 1016: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5383 +//line sql.y:5387 { yyLOCAL = yyDollar[1].tableExprUnion() } @@ -18611,7 +18615,7 @@ yydefault: case 1017: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *DerivedTable -//line sql.y:5389 +//line sql.y:5393 { yyLOCAL = &DerivedTable{Lateral: false, Select: yyDollar[1].tableStmtUnion()} } @@ -18619,7 +18623,7 @@ yydefault: case 1018: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *DerivedTable -//line sql.y:5393 +//line sql.y:5397 { yyLOCAL = &DerivedTable{Lateral: true, Select: yyDollar[2].tableStmtUnion()} } @@ -18627,7 +18631,7 @@ yydefault: case 1019: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *AliasedTableExpr -//line sql.y:5399 +//line sql.y:5403 { yyLOCAL = &AliasedTableExpr{Expr: yyDollar[1].tableName, As: yyDollar[2].identifierCS, Hints: yyDollar[3].indexHintsUnion()} } @@ -18635,7 +18639,7 @@ yydefault: case 1020: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *AliasedTableExpr -//line sql.y:5403 +//line sql.y:5407 { yyLOCAL = &AliasedTableExpr{Expr: yyDollar[1].tableName, Partitions: yyDollar[4].partitionsUnion(), As: yyDollar[6].identifierCS, Hints: yyDollar[7].indexHintsUnion()} } @@ -18643,7 +18647,7 @@ yydefault: case 1021: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Columns -//line sql.y:5408 +//line sql.y:5412 { yyLOCAL = nil } @@ -18651,7 +18655,7 @@ yydefault: case 1022: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Columns -//line sql.y:5412 +//line sql.y:5416 { yyLOCAL = yyDollar[2].columnsUnion() } @@ -18659,7 +18663,7 @@ yydefault: case 1023: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Columns -//line sql.y:5417 +//line sql.y:5421 { yyLOCAL = nil } @@ -18667,7 +18671,7 @@ yydefault: case 1024: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:5421 +//line sql.y:5425 { yyLOCAL = yyDollar[1].columnsUnion() } @@ -18675,14 +18679,14 @@ yydefault: case 1025: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:5427 +//line sql.y:5431 { yyLOCAL = Columns{yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL case 1026: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5431 +//line sql.y:5435 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) @@ -18690,14 +18694,14 @@ yydefault: case 1027: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*Variable -//line sql.y:5437 +//line sql.y:5441 { yyLOCAL = []*Variable{yyDollar[1].variableUnion()} } yyVAL.union = yyLOCAL case 1028: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5441 +//line sql.y:5445 { yySLICE := (*[]*Variable)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].variableUnion()) @@ -18705,7 +18709,7 @@ yydefault: case 1029: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:5447 +//line sql.y:5451 { yyLOCAL = Columns{yyDollar[1].identifierCI} } @@ -18713,21 +18717,21 @@ yydefault: case 1030: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:5451 +//line sql.y:5455 { yyLOCAL = Columns{NewIdentifierCI(string(yyDollar[1].str))} } yyVAL.union = yyLOCAL case 1031: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5455 +//line sql.y:5459 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) } case 1032: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5459 +//line sql.y:5463 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, NewIdentifierCI(string(yyDollar[3].str))) @@ -18735,14 +18739,14 @@ yydefault: case 1033: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Partitions -//line sql.y:5465 +//line sql.y:5469 { yyLOCAL = Partitions{yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL case 1034: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5469 +//line sql.y:5473 { yySLICE := (*Partitions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) @@ -18750,7 +18754,7 @@ yydefault: case 1035: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5482 +//line sql.y:5486 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion(), Condition: yyDollar[4].joinCondition} } @@ -18758,7 +18762,7 @@ yydefault: case 1036: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5486 +//line sql.y:5490 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion(), Condition: yyDollar[4].joinCondition} } @@ -18766,7 +18770,7 @@ yydefault: case 1037: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5490 +//line sql.y:5494 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion(), Condition: yyDollar[4].joinCondition} } @@ -18774,87 +18778,87 @@ yydefault: case 1038: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5494 +//line sql.y:5498 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion()} } yyVAL.union = yyLOCAL case 1039: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5500 +//line sql.y:5504 { yyVAL.joinCondition = &JoinCondition{On: yyDollar[2].exprUnion()} } case 1040: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:5502 +//line sql.y:5506 { yyVAL.joinCondition = &JoinCondition{Using: yyDollar[3].columnsUnion()} } case 1041: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5506 +//line sql.y:5510 { yyVAL.joinCondition = &JoinCondition{} } case 1042: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5508 +//line sql.y:5512 { yyVAL.joinCondition = yyDollar[1].joinCondition } case 1043: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5512 +//line sql.y:5516 { yyVAL.joinCondition = &JoinCondition{} } case 1044: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5514 +//line sql.y:5518 { yyVAL.joinCondition = &JoinCondition{On: yyDollar[2].exprUnion()} } case 1045: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5517 +//line sql.y:5521 { yyVAL.empty = struct{}{} } case 1046: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5519 +//line sql.y:5523 { yyVAL.empty = struct{}{} } case 1047: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5522 +//line sql.y:5526 { yyVAL.identifierCS = NewIdentifierCS("") } case 1048: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5526 +//line sql.y:5530 { yyVAL.identifierCS = yyDollar[1].identifierCS } case 1049: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5530 +//line sql.y:5534 { yyVAL.identifierCS = yyDollar[2].identifierCS } case 1051: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5537 +//line sql.y:5541 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } case 1052: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL JoinType -//line sql.y:5543 +//line sql.y:5547 { yyLOCAL = NormalJoinType } @@ -18862,7 +18866,7 @@ yydefault: case 1053: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5547 +//line sql.y:5551 { yyLOCAL = NormalJoinType } @@ -18870,7 +18874,7 @@ yydefault: case 1054: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5551 +//line sql.y:5555 { yyLOCAL = NormalJoinType } @@ -18878,7 +18882,7 @@ yydefault: case 1055: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL JoinType -//line sql.y:5557 +//line sql.y:5561 { yyLOCAL = StraightJoinType } @@ -18886,7 +18890,7 @@ yydefault: case 1056: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5563 +//line sql.y:5567 { yyLOCAL = LeftJoinType } @@ -18894,7 +18898,7 @@ yydefault: case 1057: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL JoinType -//line sql.y:5567 +//line sql.y:5571 { yyLOCAL = LeftJoinType } @@ -18902,7 +18906,7 @@ yydefault: case 1058: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5571 +//line sql.y:5575 { yyLOCAL = RightJoinType } @@ -18910,7 +18914,7 @@ yydefault: case 1059: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL JoinType -//line sql.y:5575 +//line sql.y:5579 { yyLOCAL = RightJoinType } @@ -18918,7 +18922,7 @@ yydefault: case 1060: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5581 +//line sql.y:5585 { yyLOCAL = NaturalJoinType } @@ -18926,7 +18930,7 @@ yydefault: case 1061: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5585 +//line sql.y:5589 { if yyDollar[2].joinTypeUnion() == LeftJoinType { yyLOCAL = NaturalLeftJoinType @@ -18937,38 +18941,38 @@ yydefault: yyVAL.union = yyLOCAL case 1062: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5595 +//line sql.y:5599 { yyVAL.tableName = yyDollar[2].tableName } case 1063: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5599 +//line sql.y:5603 { yyVAL.tableName = yyDollar[1].tableName } case 1064: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5605 +//line sql.y:5609 { yyVAL.tableName = TableName{Name: yyDollar[1].identifierCS} } case 1065: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5609 +//line sql.y:5613 { yyVAL.tableName = TableName{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCS} } case 1066: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5615 +//line sql.y:5619 { yyVAL.tableName = TableName{Name: yyDollar[1].identifierCS} } case 1067: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL IndexHints -//line sql.y:5620 +//line sql.y:5624 { yyLOCAL = nil } @@ -18976,7 +18980,7 @@ yydefault: case 1068: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IndexHints -//line sql.y:5624 +//line sql.y:5628 { yyLOCAL = yyDollar[1].indexHintsUnion() } @@ -18984,14 +18988,14 @@ yydefault: case 1069: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IndexHints -//line sql.y:5630 +//line sql.y:5634 { yyLOCAL = IndexHints{yyDollar[1].indexHintUnion()} } yyVAL.union = yyLOCAL case 1070: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5634 +//line sql.y:5638 { yySLICE := (*IndexHints)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].indexHintUnion()) @@ -18999,7 +19003,7 @@ yydefault: case 1071: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5640 +//line sql.y:5644 { yyLOCAL = &IndexHint{Type: UseOp, ForType: yyDollar[3].indexHintForTypeUnion(), Indexes: yyDollar[5].columnsUnion()} } @@ -19007,7 +19011,7 @@ yydefault: case 1072: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5644 +//line sql.y:5648 { yyLOCAL = &IndexHint{Type: UseOp, ForType: yyDollar[3].indexHintForTypeUnion()} } @@ -19015,7 +19019,7 @@ yydefault: case 1073: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5648 +//line sql.y:5652 { yyLOCAL = &IndexHint{Type: IgnoreOp, ForType: yyDollar[3].indexHintForTypeUnion(), Indexes: yyDollar[5].columnsUnion()} } @@ -19023,7 +19027,7 @@ yydefault: case 1074: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5652 +//line sql.y:5656 { yyLOCAL = &IndexHint{Type: ForceOp, ForType: yyDollar[3].indexHintForTypeUnion(), Indexes: yyDollar[5].columnsUnion()} } @@ -19031,7 +19035,7 @@ yydefault: case 1075: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5656 +//line sql.y:5660 { yyLOCAL = &IndexHint{Type: UseVindexOp, Indexes: yyDollar[4].columnsUnion()} } @@ -19039,7 +19043,7 @@ yydefault: case 1076: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5660 +//line sql.y:5664 { yyLOCAL = &IndexHint{Type: IgnoreVindexOp, Indexes: yyDollar[4].columnsUnion()} } @@ -19047,7 +19051,7 @@ yydefault: case 1077: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL IndexHintForType -//line sql.y:5665 +//line sql.y:5669 { yyLOCAL = NoForType } @@ -19055,7 +19059,7 @@ yydefault: case 1078: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL IndexHintForType -//line sql.y:5669 +//line sql.y:5673 { yyLOCAL = JoinForType } @@ -19063,7 +19067,7 @@ yydefault: case 1079: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL IndexHintForType -//line sql.y:5673 +//line sql.y:5677 { yyLOCAL = OrderByForType } @@ -19071,7 +19075,7 @@ yydefault: case 1080: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL IndexHintForType -//line sql.y:5677 +//line sql.y:5681 { yyLOCAL = GroupByForType } @@ -19079,7 +19083,7 @@ yydefault: case 1081: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:5683 +//line sql.y:5687 { yyLOCAL = nil } @@ -19087,7 +19091,7 @@ yydefault: case 1082: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5687 +//line sql.y:5691 { yyLOCAL = yyDollar[2].exprUnion() } @@ -19095,7 +19099,7 @@ yydefault: case 1083: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5694 +//line sql.y:5698 { yyLOCAL = &OrExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} } @@ -19103,7 +19107,7 @@ yydefault: case 1084: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5698 +//line sql.y:5702 { yyLOCAL = &XorExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} } @@ -19111,7 +19115,7 @@ yydefault: case 1085: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5702 +//line sql.y:5706 { yyLOCAL = &AndExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} } @@ -19119,7 +19123,7 @@ yydefault: case 1086: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5706 +//line sql.y:5710 { yyLOCAL = &NotExpr{Expr: yyDollar[2].exprUnion()} } @@ -19127,7 +19131,7 @@ yydefault: case 1087: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5710 +//line sql.y:5714 { yyLOCAL = &IsExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].isExprOperatorUnion()} } @@ -19135,7 +19139,7 @@ yydefault: case 1088: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5714 +//line sql.y:5718 { yyLOCAL = yyDollar[1].exprUnion() } @@ -19143,7 +19147,7 @@ yydefault: case 1089: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5718 +//line sql.y:5722 { yyLOCAL = &AssignmentExpr{Left: yyDollar[1].variableUnion(), Right: yyDollar[3].exprUnion()} } @@ -19151,25 +19155,25 @@ yydefault: case 1090: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5722 +//line sql.y:5726 { yyLOCAL = &MemberOfExpr{Value: yyDollar[1].exprUnion(), JSONArr: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL case 1091: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5728 +//line sql.y:5732 { } case 1092: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5731 +//line sql.y:5735 { } case 1093: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5736 +//line sql.y:5740 { yyLOCAL = &IsExpr{Left: yyDollar[1].exprUnion(), Right: IsNullOp} } @@ -19177,7 +19181,7 @@ yydefault: case 1094: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5740 +//line sql.y:5744 { yyLOCAL = &IsExpr{Left: yyDollar[1].exprUnion(), Right: IsNotNullOp} } @@ -19185,7 +19189,7 @@ yydefault: case 1095: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5744 +//line sql.y:5748 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: yyDollar[2].comparisonExprOperatorUnion(), Right: yyDollar[3].exprUnion()} } @@ -19193,7 +19197,7 @@ yydefault: case 1096: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5748 +//line sql.y:5752 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: yyDollar[2].comparisonExprOperatorUnion(), Modifier: Any, Right: yyDollar[4].subqueryUnion()} } @@ -19201,7 +19205,7 @@ yydefault: case 1097: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5752 +//line sql.y:5756 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: yyDollar[2].comparisonExprOperatorUnion(), Modifier: Any, Right: yyDollar[4].subqueryUnion()} } @@ -19209,7 +19213,7 @@ yydefault: case 1098: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5756 +//line sql.y:5760 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: yyDollar[2].comparisonExprOperatorUnion(), Modifier: All, Right: yyDollar[4].subqueryUnion()} } @@ -19217,7 +19221,7 @@ yydefault: case 1099: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5760 +//line sql.y:5764 { yyLOCAL = yyDollar[1].exprUnion() } @@ -19225,7 +19229,7 @@ yydefault: case 1100: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5766 +//line sql.y:5770 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: InOp, Right: yyDollar[3].colTupleUnion()} } @@ -19233,7 +19237,7 @@ yydefault: case 1101: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5770 +//line sql.y:5774 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotInOp, Right: yyDollar[4].colTupleUnion()} } @@ -19241,7 +19245,7 @@ yydefault: case 1102: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5774 +//line sql.y:5778 { yyLOCAL = &BetweenExpr{Left: yyDollar[1].exprUnion(), IsBetween: true, From: yyDollar[3].exprUnion(), To: yyDollar[5].exprUnion()} } @@ -19249,7 +19253,7 @@ yydefault: case 1103: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5778 +//line sql.y:5782 { yyLOCAL = &BetweenExpr{Left: yyDollar[1].exprUnion(), IsBetween: false, From: yyDollar[4].exprUnion(), To: yyDollar[6].exprUnion()} } @@ -19257,7 +19261,7 @@ yydefault: case 1104: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5782 +//line sql.y:5786 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: LikeOp, Right: yyDollar[3].exprUnion()} } @@ -19265,7 +19269,7 @@ yydefault: case 1105: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5786 +//line sql.y:5790 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotLikeOp, Right: yyDollar[4].exprUnion()} } @@ -19273,7 +19277,7 @@ yydefault: case 1106: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5790 +//line sql.y:5794 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: LikeOp, Right: yyDollar[3].exprUnion(), Escape: yyDollar[5].exprUnion()} } @@ -19281,7 +19285,7 @@ yydefault: case 1107: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5794 +//line sql.y:5798 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotLikeOp, Right: yyDollar[4].exprUnion(), Escape: yyDollar[6].exprUnion()} } @@ -19289,7 +19293,7 @@ yydefault: case 1108: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5798 +//line sql.y:5802 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: RegexpOp, Right: yyDollar[3].exprUnion()} } @@ -19297,7 +19301,7 @@ yydefault: case 1109: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5802 +//line sql.y:5806 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotRegexpOp, Right: yyDollar[4].exprUnion()} } @@ -19305,25 +19309,25 @@ yydefault: case 1110: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5806 +//line sql.y:5810 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL case 1111: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5812 +//line sql.y:5816 { } case 1112: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5815 +//line sql.y:5819 { } case 1113: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5821 +//line sql.y:5825 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitOrOp, Right: yyDollar[3].exprUnion()} } @@ -19331,7 +19335,7 @@ yydefault: case 1114: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5825 +//line sql.y:5829 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitAndOp, Right: yyDollar[3].exprUnion()} } @@ -19339,7 +19343,7 @@ yydefault: case 1115: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5829 +//line sql.y:5833 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ShiftLeftOp, Right: yyDollar[3].exprUnion()} } @@ -19347,7 +19351,7 @@ yydefault: case 1116: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5833 +//line sql.y:5837 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ShiftRightOp, Right: yyDollar[3].exprUnion()} } @@ -19355,7 +19359,7 @@ yydefault: case 1117: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5837 +//line sql.y:5841 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: PlusOp, Right: yyDollar[3].exprUnion()} } @@ -19363,7 +19367,7 @@ yydefault: case 1118: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5841 +//line sql.y:5845 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: MinusOp, Right: yyDollar[3].exprUnion()} } @@ -19371,7 +19375,7 @@ yydefault: case 1119: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5845 +//line sql.y:5849 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprBinaryAdd, Date: yyDollar[1].exprUnion(), Unit: yyDollar[5].intervalTypeUnion(), Interval: yyDollar[4].exprUnion()} } @@ -19379,7 +19383,7 @@ yydefault: case 1120: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5849 +//line sql.y:5853 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprBinarySub, Date: yyDollar[1].exprUnion(), Unit: yyDollar[5].intervalTypeUnion(), Interval: yyDollar[4].exprUnion()} } @@ -19387,7 +19391,7 @@ yydefault: case 1121: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5853 +//line sql.y:5857 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: MultOp, Right: yyDollar[3].exprUnion()} } @@ -19395,7 +19399,7 @@ yydefault: case 1122: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5857 +//line sql.y:5861 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: DivOp, Right: yyDollar[3].exprUnion()} } @@ -19403,7 +19407,7 @@ yydefault: case 1123: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5861 +//line sql.y:5865 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ModOp, Right: yyDollar[3].exprUnion()} } @@ -19411,7 +19415,7 @@ yydefault: case 1124: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5865 +//line sql.y:5869 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: IntDivOp, Right: yyDollar[3].exprUnion()} } @@ -19419,7 +19423,7 @@ yydefault: case 1125: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5869 +//line sql.y:5873 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ModOp, Right: yyDollar[3].exprUnion()} } @@ -19427,7 +19431,7 @@ yydefault: case 1126: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5873 +//line sql.y:5877 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitXorOp, Right: yyDollar[3].exprUnion()} } @@ -19435,7 +19439,7 @@ yydefault: case 1127: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5877 +//line sql.y:5881 { yyLOCAL = yyDollar[1].exprUnion() } @@ -19443,7 +19447,7 @@ yydefault: case 1128: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5883 +//line sql.y:5887 { yyLOCAL = yyDollar[1].exprUnion() } @@ -19451,7 +19455,7 @@ yydefault: case 1129: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5887 +//line sql.y:5891 { yyLOCAL = yyDollar[1].exprUnion() } @@ -19459,7 +19463,7 @@ yydefault: case 1130: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5891 +//line sql.y:5895 { yyLOCAL = yyDollar[1].exprUnion() } @@ -19467,7 +19471,7 @@ yydefault: case 1131: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5895 +//line sql.y:5899 { yyLOCAL = yyDollar[1].exprUnion() } @@ -19475,7 +19479,7 @@ yydefault: case 1132: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5899 +//line sql.y:5903 { yyLOCAL = &CollateExpr{Expr: yyDollar[1].exprUnion(), Collation: yyDollar[3].str} } @@ -19483,7 +19487,7 @@ yydefault: case 1133: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5903 +//line sql.y:5907 { yyLOCAL = yyDollar[1].exprUnion() } @@ -19491,7 +19495,7 @@ yydefault: case 1134: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5907 +//line sql.y:5911 { yyLOCAL = yyDollar[1].exprUnion() } @@ -19499,7 +19503,7 @@ yydefault: case 1135: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5911 +//line sql.y:5915 { yyLOCAL = yyDollar[1].variableUnion() } @@ -19507,7 +19511,7 @@ yydefault: case 1136: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5915 +//line sql.y:5919 { yyLOCAL = yyDollar[2].exprUnion() // TODO: do we really want to ignore unary '+' before any kind of literals? } @@ -19515,7 +19519,7 @@ yydefault: case 1137: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5919 +//line sql.y:5923 { yyLOCAL = &UnaryExpr{Operator: UMinusOp, Expr: yyDollar[2].exprUnion()} } @@ -19523,7 +19527,7 @@ yydefault: case 1138: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5923 +//line sql.y:5927 { yyLOCAL = &UnaryExpr{Operator: TildaOp, Expr: yyDollar[2].exprUnion()} } @@ -19531,7 +19535,7 @@ yydefault: case 1139: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5927 +//line sql.y:5931 { yyLOCAL = &UnaryExpr{Operator: BangOp, Expr: yyDollar[2].exprUnion()} } @@ -19539,7 +19543,7 @@ yydefault: case 1140: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5931 +//line sql.y:5935 { yyLOCAL = yyDollar[1].subqueryUnion() } @@ -19547,7 +19551,7 @@ yydefault: case 1141: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5935 +//line sql.y:5939 { yyLOCAL = yyDollar[1].exprUnion() } @@ -19555,7 +19559,7 @@ yydefault: case 1142: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5939 +//line sql.y:5943 { yyLOCAL = &ExistsExpr{Subquery: yyDollar[2].subqueryUnion()} } @@ -19563,7 +19567,7 @@ yydefault: case 1143: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr -//line sql.y:5943 +//line sql.y:5947 { yyLOCAL = &MatchExpr{Columns: yyDollar[2].colNamesUnion(), Expr: yyDollar[5].exprUnion(), Option: yyDollar[6].matchExprOptionUnion()} } @@ -19571,7 +19575,7 @@ yydefault: case 1144: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr -//line sql.y:5947 +//line sql.y:5951 { yyLOCAL = &CastExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].convertTypeUnion(), Array: yyDollar[6].booleanUnion()} } @@ -19579,7 +19583,7 @@ yydefault: case 1145: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5951 +//line sql.y:5955 { yyLOCAL = &ConvertExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].convertTypeUnion()} } @@ -19587,7 +19591,7 @@ yydefault: case 1146: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5955 +//line sql.y:5959 { yyLOCAL = &ConvertUsingExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].str} } @@ -19595,7 +19599,7 @@ yydefault: case 1147: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5959 +//line sql.y:5963 { // From: https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#operator_binary // To convert a string expression to a binary string, these constructs are equivalent: @@ -19607,7 +19611,7 @@ yydefault: case 1148: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5967 +//line sql.y:5971 { yyLOCAL = &Default{ColName: yyDollar[2].str} } @@ -19615,7 +19619,7 @@ yydefault: case 1149: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5971 +//line sql.y:5975 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprBinaryAddLeft, Date: yyDollar[5].exprUnion(), Unit: yyDollar[3].intervalTypeUnion(), Interval: yyDollar[2].exprUnion()} } @@ -19623,7 +19627,7 @@ yydefault: case 1150: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5975 +//line sql.y:5979 { yyLOCAL = &IntervalFuncExpr{Expr: yyDollar[3].exprUnion(), Exprs: yyDollar[5].exprsUnion()} } @@ -19631,7 +19635,7 @@ yydefault: case 1151: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5979 +//line sql.y:5983 { yyLOCAL = &JSONExtractExpr{JSONDoc: yyDollar[1].exprUnion(), PathList: []Expr{yyDollar[3].exprUnion()}} } @@ -19639,7 +19643,7 @@ yydefault: case 1152: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5983 +//line sql.y:5987 { yyLOCAL = &JSONUnquoteExpr{JSONValue: &JSONExtractExpr{JSONDoc: yyDollar[1].exprUnion(), PathList: []Expr{yyDollar[3].exprUnion()}}} } @@ -19647,7 +19651,7 @@ yydefault: case 1153: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*ColName -//line sql.y:5989 +//line sql.y:5993 { yyLOCAL = yyDollar[1].colNamesUnion() } @@ -19655,7 +19659,7 @@ yydefault: case 1154: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*ColName -//line sql.y:5993 +//line sql.y:5997 { yyLOCAL = yyDollar[2].colNamesUnion() } @@ -19663,14 +19667,14 @@ yydefault: case 1155: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*ColName -//line sql.y:5999 +//line sql.y:6003 { yyLOCAL = []*ColName{yyDollar[1].colNameUnion()} } yyVAL.union = yyLOCAL case 1156: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:6003 +//line sql.y:6007 { yySLICE := (*[]*ColName)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].colNameUnion()) @@ -19678,7 +19682,7 @@ yydefault: case 1157: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TrimType -//line sql.y:6009 +//line sql.y:6013 { yyLOCAL = BothTrimType } @@ -19686,7 +19690,7 @@ yydefault: case 1158: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TrimType -//line sql.y:6013 +//line sql.y:6017 { yyLOCAL = LeadingTrimType } @@ -19694,7 +19698,7 @@ yydefault: case 1159: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TrimType -//line sql.y:6017 +//line sql.y:6021 { yyLOCAL = TrailingTrimType } @@ -19702,7 +19706,7 @@ yydefault: case 1160: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL FrameUnitType -//line sql.y:6023 +//line sql.y:6027 { yyLOCAL = FrameRowsType } @@ -19710,7 +19714,7 @@ yydefault: case 1161: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL FrameUnitType -//line sql.y:6027 +//line sql.y:6031 { yyLOCAL = FrameRangeType } @@ -19718,7 +19722,7 @@ yydefault: case 1162: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:6034 +//line sql.y:6038 { yyLOCAL = CumeDistExprType } @@ -19726,7 +19730,7 @@ yydefault: case 1163: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:6038 +//line sql.y:6042 { yyLOCAL = DenseRankExprType } @@ -19734,7 +19738,7 @@ yydefault: case 1164: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:6042 +//line sql.y:6046 { yyLOCAL = PercentRankExprType } @@ -19742,7 +19746,7 @@ yydefault: case 1165: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:6046 +//line sql.y:6050 { yyLOCAL = RankExprType } @@ -19750,7 +19754,7 @@ yydefault: case 1166: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:6050 +//line sql.y:6054 { yyLOCAL = RowNumberExprType } @@ -19758,7 +19762,7 @@ yydefault: case 1167: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:6056 +//line sql.y:6060 { yyLOCAL = &FramePoint{Type: CurrentRowType} } @@ -19766,7 +19770,7 @@ yydefault: case 1168: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:6060 +//line sql.y:6064 { yyLOCAL = &FramePoint{Type: UnboundedPrecedingType} } @@ -19774,7 +19778,7 @@ yydefault: case 1169: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:6064 +//line sql.y:6068 { yyLOCAL = &FramePoint{Type: UnboundedFollowingType} } @@ -19782,7 +19786,7 @@ yydefault: case 1170: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:6068 +//line sql.y:6072 { yyLOCAL = &FramePoint{Type: ExprPrecedingType, Expr: yyDollar[1].exprUnion()} } @@ -19790,7 +19794,7 @@ yydefault: case 1171: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:6072 +//line sql.y:6076 { yyLOCAL = &FramePoint{Type: ExprPrecedingType, Expr: yyDollar[2].exprUnion(), Unit: yyDollar[3].intervalTypeUnion()} } @@ -19798,7 +19802,7 @@ yydefault: case 1172: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:6076 +//line sql.y:6080 { yyLOCAL = &FramePoint{Type: ExprFollowingType, Expr: yyDollar[1].exprUnion()} } @@ -19806,7 +19810,7 @@ yydefault: case 1173: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:6080 +//line sql.y:6084 { yyLOCAL = &FramePoint{Type: ExprFollowingType, Expr: yyDollar[2].exprUnion(), Unit: yyDollar[3].intervalTypeUnion()} } @@ -19814,7 +19818,7 @@ yydefault: case 1174: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *FrameClause -//line sql.y:6085 +//line sql.y:6089 { yyLOCAL = nil } @@ -19822,7 +19826,7 @@ yydefault: case 1175: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *FrameClause -//line sql.y:6089 +//line sql.y:6093 { yyLOCAL = yyDollar[1].frameClauseUnion() } @@ -19830,7 +19834,7 @@ yydefault: case 1176: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FrameClause -//line sql.y:6095 +//line sql.y:6099 { yyLOCAL = &FrameClause{Unit: yyDollar[1].frameUnitTypeUnion(), Start: yyDollar[2].framePointUnion()} } @@ -19838,7 +19842,7 @@ yydefault: case 1177: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *FrameClause -//line sql.y:6099 +//line sql.y:6103 { yyLOCAL = &FrameClause{Unit: yyDollar[1].frameUnitTypeUnion(), Start: yyDollar[3].framePointUnion(), End: yyDollar[5].framePointUnion()} } @@ -19846,7 +19850,7 @@ yydefault: case 1178: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []Expr -//line sql.y:6104 +//line sql.y:6108 { yyLOCAL = nil } @@ -19854,27 +19858,27 @@ yydefault: case 1179: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []Expr -//line sql.y:6108 +//line sql.y:6112 { yyLOCAL = yyDollar[3].exprsUnion() } yyVAL.union = yyLOCAL case 1180: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:6113 +//line sql.y:6117 { yyVAL.identifierCI = IdentifierCI{} } case 1181: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:6117 +//line sql.y:6121 { yyVAL.identifierCI = yyDollar[1].identifierCI } case 1182: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *WindowSpecification -//line sql.y:6123 +//line sql.y:6127 { yyLOCAL = &WindowSpecification{Name: yyDollar[1].identifierCI, PartitionClause: yyDollar[2].exprsUnion(), OrderClause: yyDollar[3].orderByUnion(), FrameClause: yyDollar[4].frameClauseUnion()} } @@ -19882,7 +19886,7 @@ yydefault: case 1183: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *OverClause -//line sql.y:6129 +//line sql.y:6133 { yyLOCAL = &OverClause{WindowSpec: yyDollar[3].windowSpecificationUnion()} } @@ -19890,7 +19894,7 @@ yydefault: case 1184: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *OverClause -//line sql.y:6133 +//line sql.y:6137 { yyLOCAL = &OverClause{WindowName: yyDollar[2].identifierCI} } @@ -19898,7 +19902,7 @@ yydefault: case 1185: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *OverClause -//line sql.y:6139 +//line sql.y:6143 { yyLOCAL = yyDollar[1].overClauseUnion() } @@ -19906,7 +19910,7 @@ yydefault: case 1186: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *OverClause -//line sql.y:6143 +//line sql.y:6147 { yyLOCAL = nil } @@ -19914,7 +19918,7 @@ yydefault: case 1187: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *NullTreatmentClause -//line sql.y:6148 +//line sql.y:6152 { yyLOCAL = nil } @@ -19922,7 +19926,7 @@ yydefault: case 1189: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *NullTreatmentClause -//line sql.y:6155 +//line sql.y:6159 { yyLOCAL = &NullTreatmentClause{yyDollar[1].nullTreatmentTypeUnion()} } @@ -19930,7 +19934,7 @@ yydefault: case 1190: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL NullTreatmentType -//line sql.y:6161 +//line sql.y:6165 { yyLOCAL = RespectNullsType } @@ -19938,7 +19942,7 @@ yydefault: case 1191: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL NullTreatmentType -//line sql.y:6165 +//line sql.y:6169 { yyLOCAL = IgnoreNullsType } @@ -19946,7 +19950,7 @@ yydefault: case 1192: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL FirstOrLastValueExprType -//line sql.y:6171 +//line sql.y:6175 { yyLOCAL = FirstValueExprType } @@ -19954,7 +19958,7 @@ yydefault: case 1193: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL FirstOrLastValueExprType -//line sql.y:6175 +//line sql.y:6179 { yyLOCAL = LastValueExprType } @@ -19962,7 +19966,7 @@ yydefault: case 1194: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL FromFirstLastType -//line sql.y:6181 +//line sql.y:6185 { yyLOCAL = FromFirstType } @@ -19970,7 +19974,7 @@ yydefault: case 1195: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL FromFirstLastType -//line sql.y:6185 +//line sql.y:6189 { yyLOCAL = FromLastType } @@ -19978,7 +19982,7 @@ yydefault: case 1196: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *FromFirstLastClause -//line sql.y:6190 +//line sql.y:6194 { yyLOCAL = nil } @@ -19986,7 +19990,7 @@ yydefault: case 1198: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *FromFirstLastClause -//line sql.y:6197 +//line sql.y:6201 { yyLOCAL = &FromFirstLastClause{yyDollar[1].fromFirstLastTypeUnion()} } @@ -19994,7 +19998,7 @@ yydefault: case 1199: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL LagLeadExprType -//line sql.y:6203 +//line sql.y:6207 { yyLOCAL = LagExprType } @@ -20002,7 +20006,7 @@ yydefault: case 1200: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL LagLeadExprType -//line sql.y:6207 +//line sql.y:6211 { yyLOCAL = LeadExprType } @@ -20010,7 +20014,7 @@ yydefault: case 1201: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *WindowDefinition -//line sql.y:6213 +//line sql.y:6217 { yyLOCAL = &WindowDefinition{Name: yyDollar[1].identifierCI, WindowSpec: yyDollar[4].windowSpecificationUnion()} } @@ -20018,34 +20022,34 @@ yydefault: case 1202: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL WindowDefinitions -//line sql.y:6219 +//line sql.y:6223 { yyLOCAL = WindowDefinitions{yyDollar[1].windowDefinitionUnion()} } yyVAL.union = yyLOCAL case 1203: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:6223 +//line sql.y:6227 { yySLICE := (*WindowDefinitions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].windowDefinitionUnion()) } case 1204: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:6229 +//line sql.y:6233 { yyVAL.str = "" } case 1205: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:6233 +//line sql.y:6237 { yyVAL.str = string(yyDollar[2].identifierCI.String()) } case 1206: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL BoolVal -//line sql.y:6239 +//line sql.y:6243 { yyLOCAL = BoolVal(true) } @@ -20053,7 +20057,7 @@ yydefault: case 1207: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL BoolVal -//line sql.y:6243 +//line sql.y:6247 { yyLOCAL = BoolVal(false) } @@ -20061,7 +20065,7 @@ yydefault: case 1208: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:6250 +//line sql.y:6254 { yyLOCAL = IsTrueOp } @@ -20069,7 +20073,7 @@ yydefault: case 1209: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:6254 +//line sql.y:6258 { yyLOCAL = IsNotTrueOp } @@ -20077,7 +20081,7 @@ yydefault: case 1210: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:6258 +//line sql.y:6262 { yyLOCAL = IsFalseOp } @@ -20085,7 +20089,7 @@ yydefault: case 1211: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:6262 +//line sql.y:6266 { yyLOCAL = IsNotFalseOp } @@ -20093,7 +20097,7 @@ yydefault: case 1212: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:6268 +//line sql.y:6272 { yyLOCAL = yyDollar[1].comparisonExprOperatorUnion() } @@ -20101,7 +20105,7 @@ yydefault: case 1213: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:6272 +//line sql.y:6276 { yyLOCAL = NullSafeEqualOp } @@ -20109,7 +20113,7 @@ yydefault: case 1214: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:6278 +//line sql.y:6282 { yyLOCAL = EqualOp } @@ -20117,7 +20121,7 @@ yydefault: case 1215: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:6282 +//line sql.y:6286 { yyLOCAL = LessThanOp } @@ -20125,7 +20129,7 @@ yydefault: case 1216: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:6286 +//line sql.y:6290 { yyLOCAL = GreaterThanOp } @@ -20133,7 +20137,7 @@ yydefault: case 1217: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:6290 +//line sql.y:6294 { yyLOCAL = LessEqualOp } @@ -20141,7 +20145,7 @@ yydefault: case 1218: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:6294 +//line sql.y:6298 { yyLOCAL = GreaterEqualOp } @@ -20149,7 +20153,7 @@ yydefault: case 1219: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:6298 +//line sql.y:6302 { yyLOCAL = NotEqualOp } @@ -20157,7 +20161,7 @@ yydefault: case 1220: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColTuple -//line sql.y:6304 +//line sql.y:6308 { yyLOCAL = yyDollar[1].valTupleUnion() } @@ -20165,7 +20169,7 @@ yydefault: case 1221: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColTuple -//line sql.y:6308 +//line sql.y:6312 { yyLOCAL = yyDollar[1].subqueryUnion() } @@ -20173,7 +20177,7 @@ yydefault: case 1222: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColTuple -//line sql.y:6312 +//line sql.y:6316 { yyLOCAL = ListArg(yyDollar[1].str[2:]) markBindVariable(yylex, yyDollar[1].str[2:]) @@ -20182,7 +20186,7 @@ yydefault: case 1223: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Subquery -//line sql.y:6319 +//line sql.y:6323 { yyLOCAL = &Subquery{yyDollar[1].tableStmtUnion()} } @@ -20190,14 +20194,14 @@ yydefault: case 1224: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []Expr -//line sql.y:6325 +//line sql.y:6329 { yyLOCAL = []Expr{yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL case 1225: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:6329 +//line sql.y:6333 { yySLICE := (*[]Expr)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].exprUnion()) @@ -20205,7 +20209,7 @@ yydefault: case 1226: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6339 +//line sql.y:6343 { yyLOCAL = &FuncExpr{Name: yyDollar[1].identifierCI, Exprs: yyDollar[3].exprsUnion()} } @@ -20213,7 +20217,7 @@ yydefault: case 1227: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6343 +//line sql.y:6347 { yyLOCAL = &FuncExpr{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCI, Exprs: yyDollar[5].exprsUnion()} } @@ -20221,7 +20225,7 @@ yydefault: case 1228: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6353 +//line sql.y:6357 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("left"), Exprs: yyDollar[3].exprsUnion()} } @@ -20229,7 +20233,7 @@ yydefault: case 1229: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6357 +//line sql.y:6361 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("right"), Exprs: yyDollar[3].exprsUnion()} } @@ -20237,7 +20241,7 @@ yydefault: case 1230: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6361 +//line sql.y:6365 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} } @@ -20245,7 +20249,7 @@ yydefault: case 1231: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6365 +//line sql.y:6369 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} } @@ -20253,7 +20257,7 @@ yydefault: case 1232: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6369 +//line sql.y:6373 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion()} } @@ -20261,7 +20265,7 @@ yydefault: case 1233: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6373 +//line sql.y:6377 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} } @@ -20269,7 +20273,7 @@ yydefault: case 1234: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6377 +//line sql.y:6381 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion()} } @@ -20277,7 +20281,7 @@ yydefault: case 1235: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6381 +//line sql.y:6385 { yyLOCAL = &CaseExpr{Expr: yyDollar[2].exprUnion(), Whens: yyDollar[3].whensUnion(), Else: yyDollar[4].exprUnion()} } @@ -20285,7 +20289,7 @@ yydefault: case 1236: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6385 +//line sql.y:6389 { yyLOCAL = &ValuesFuncExpr{Name: yyDollar[3].colNameUnion()} } @@ -20293,7 +20297,7 @@ yydefault: case 1237: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:6389 +//line sql.y:6393 { yyLOCAL = &InsertExpr{Str: yyDollar[3].exprUnion(), Pos: yyDollar[5].exprUnion(), Len: yyDollar[7].exprUnion(), NewStr: yyDollar[9].exprUnion()} } @@ -20301,7 +20305,7 @@ yydefault: case 1238: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6393 +//line sql.y:6397 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI(yyDollar[1].str)} } @@ -20309,7 +20313,7 @@ yydefault: case 1239: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6404 +//line sql.y:6408 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("utc_date")} } @@ -20317,7 +20321,7 @@ yydefault: case 1240: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:6408 +//line sql.y:6412 { yyLOCAL = yyDollar[1].exprUnion() } @@ -20325,7 +20329,7 @@ yydefault: case 1241: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6414 +//line sql.y:6418 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("current_date")} } @@ -20333,7 +20337,7 @@ yydefault: case 1242: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6418 +//line sql.y:6422 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("curdate")} } @@ -20341,7 +20345,7 @@ yydefault: case 1243: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6422 +//line sql.y:6426 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("utc_time"), Fsp: yyDollar[2].integerUnion()} } @@ -20349,7 +20353,7 @@ yydefault: case 1244: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6427 +//line sql.y:6431 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("curtime"), Fsp: yyDollar[2].integerUnion()} } @@ -20357,7 +20361,7 @@ yydefault: case 1245: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6432 +//line sql.y:6436 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("current_time"), Fsp: yyDollar[2].integerUnion()} } @@ -20365,7 +20369,7 @@ yydefault: case 1246: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6436 +//line sql.y:6440 { yyLOCAL = &CountStar{OverClause: yyDollar[5].overClauseUnion()} } @@ -20373,7 +20377,7 @@ yydefault: case 1247: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6440 +//line sql.y:6444 { yyLOCAL = &Count{Distinct: yyDollar[3].booleanUnion(), Args: yyDollar[4].exprsUnion(), OverClause: yyDollar[6].overClauseUnion()} } @@ -20381,7 +20385,7 @@ yydefault: case 1248: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6444 +//line sql.y:6448 { yyLOCAL = &Max{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion(), OverClause: yyDollar[6].overClauseUnion()} } @@ -20389,7 +20393,7 @@ yydefault: case 1249: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6448 +//line sql.y:6452 { yyLOCAL = &Min{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion(), OverClause: yyDollar[6].overClauseUnion()} } @@ -20397,7 +20401,7 @@ yydefault: case 1250: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6452 +//line sql.y:6456 { yyLOCAL = &Sum{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion(), OverClause: yyDollar[6].overClauseUnion()} } @@ -20405,7 +20409,7 @@ yydefault: case 1251: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6456 +//line sql.y:6460 { yyLOCAL = &Avg{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion(), OverClause: yyDollar[6].overClauseUnion()} } @@ -20413,7 +20417,7 @@ yydefault: case 1252: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6460 +//line sql.y:6464 { yyLOCAL = &BitAnd{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } @@ -20421,7 +20425,7 @@ yydefault: case 1253: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6464 +//line sql.y:6468 { yyLOCAL = &BitOr{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } @@ -20429,7 +20433,7 @@ yydefault: case 1254: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6468 +//line sql.y:6472 { yyLOCAL = &BitXor{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } @@ -20437,7 +20441,7 @@ yydefault: case 1255: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6472 +//line sql.y:6476 { yyLOCAL = &Std{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } @@ -20445,7 +20449,7 @@ yydefault: case 1256: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6476 +//line sql.y:6480 { yyLOCAL = &StdDev{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } @@ -20453,7 +20457,7 @@ yydefault: case 1257: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6480 +//line sql.y:6484 { yyLOCAL = &StdPop{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } @@ -20461,7 +20465,7 @@ yydefault: case 1258: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6484 +//line sql.y:6488 { yyLOCAL = &StdSamp{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } @@ -20469,7 +20473,7 @@ yydefault: case 1259: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6488 +//line sql.y:6492 { yyLOCAL = &VarPop{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } @@ -20477,7 +20481,7 @@ yydefault: case 1260: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6492 +//line sql.y:6496 { yyLOCAL = &VarSamp{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } @@ -20485,7 +20489,7 @@ yydefault: case 1261: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6496 +//line sql.y:6500 { yyLOCAL = &Variance{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } @@ -20493,7 +20497,7 @@ yydefault: case 1262: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6500 +//line sql.y:6504 { yyLOCAL = &GroupConcatExpr{Distinct: yyDollar[3].booleanUnion(), Exprs: yyDollar[4].exprsUnion(), OrderBy: yyDollar[5].orderByUnion(), Separator: yyDollar[6].str, Limit: yyDollar[7].limitUnion()} } @@ -20501,7 +20505,7 @@ yydefault: case 1263: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6504 +//line sql.y:6508 { yyLOCAL = &AnyValue{Arg: yyDollar[3].exprUnion()} } @@ -20509,7 +20513,7 @@ yydefault: case 1264: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6508 +//line sql.y:6512 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprTimestampadd, Date: yyDollar[7].exprUnion(), Interval: yyDollar[5].exprUnion(), Unit: yyDollar[3].intervalTypeUnion()} } @@ -20517,7 +20521,7 @@ yydefault: case 1265: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6512 +//line sql.y:6516 { yyLOCAL = &TimestampDiffExpr{Unit: yyDollar[3].intervalTypeUnion(), Expr1: yyDollar[5].exprUnion(), Expr2: yyDollar[7].exprUnion()} } @@ -20525,7 +20529,7 @@ yydefault: case 1266: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6516 +//line sql.y:6520 { yyLOCAL = &ExtractFuncExpr{IntervalType: yyDollar[3].intervalTypeUnion(), Expr: yyDollar[5].exprUnion()} } @@ -20533,7 +20537,7 @@ yydefault: case 1267: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6520 +//line sql.y:6524 { yyLOCAL = &WeightStringFuncExpr{Expr: yyDollar[3].exprUnion(), As: yyDollar[4].convertTypeUnion()} } @@ -20541,7 +20545,7 @@ yydefault: case 1268: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6524 +//line sql.y:6528 { yyLOCAL = &JSONPrettyExpr{JSONVal: yyDollar[3].exprUnion()} } @@ -20549,7 +20553,7 @@ yydefault: case 1269: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6528 +//line sql.y:6532 { yyLOCAL = &JSONStorageFreeExpr{JSONVal: yyDollar[3].exprUnion()} } @@ -20557,7 +20561,7 @@ yydefault: case 1270: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6532 +//line sql.y:6536 { yyLOCAL = &JSONStorageSizeExpr{JSONVal: yyDollar[3].exprUnion()} } @@ -20565,7 +20569,7 @@ yydefault: case 1271: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6536 +//line sql.y:6540 { yyLOCAL = &JSONArrayAgg{Expr: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } @@ -20573,7 +20577,7 @@ yydefault: case 1272: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr -//line sql.y:6540 +//line sql.y:6544 { yyLOCAL = &JSONObjectAgg{Key: yyDollar[3].exprUnion(), Value: yyDollar[5].exprUnion(), OverClause: yyDollar[7].overClauseUnion()} } @@ -20581,7 +20585,7 @@ yydefault: case 1273: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6544 +//line sql.y:6548 { yyLOCAL = &TrimFuncExpr{TrimFuncType: LTrimType, Type: LeadingTrimType, StringArg: yyDollar[3].exprUnion()} } @@ -20589,7 +20593,7 @@ yydefault: case 1274: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6548 +//line sql.y:6552 { yyLOCAL = &TrimFuncExpr{TrimFuncType: RTrimType, Type: TrailingTrimType, StringArg: yyDollar[3].exprUnion()} } @@ -20597,7 +20601,7 @@ yydefault: case 1275: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr -//line sql.y:6552 +//line sql.y:6556 { yyLOCAL = &TrimFuncExpr{Type: yyDollar[3].trimTypeUnion(), TrimArg: yyDollar[4].exprUnion(), StringArg: yyDollar[6].exprUnion()} } @@ -20605,7 +20609,7 @@ yydefault: case 1276: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6556 +//line sql.y:6560 { yyLOCAL = &TrimFuncExpr{StringArg: yyDollar[3].exprUnion()} } @@ -20613,7 +20617,7 @@ yydefault: case 1277: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6560 +//line sql.y:6564 { yyLOCAL = &CharExpr{Exprs: yyDollar[3].exprsUnion()} } @@ -20621,7 +20625,7 @@ yydefault: case 1278: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6564 +//line sql.y:6568 { yyLOCAL = &CharExpr{Exprs: yyDollar[3].exprsUnion(), Charset: yyDollar[5].str} } @@ -20629,7 +20633,7 @@ yydefault: case 1279: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6568 +//line sql.y:6572 { yyLOCAL = &TrimFuncExpr{TrimArg: yyDollar[3].exprUnion(), StringArg: yyDollar[5].exprUnion()} } @@ -20637,7 +20641,7 @@ yydefault: case 1280: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6572 +//line sql.y:6576 { yyLOCAL = &LocateExpr{SubStr: yyDollar[3].exprUnion(), Str: yyDollar[5].exprUnion()} } @@ -20645,7 +20649,7 @@ yydefault: case 1281: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6576 +//line sql.y:6580 { yyLOCAL = &LocateExpr{SubStr: yyDollar[3].exprUnion(), Str: yyDollar[5].exprUnion(), Pos: yyDollar[7].exprUnion()} } @@ -20653,7 +20657,7 @@ yydefault: case 1282: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6580 +//line sql.y:6584 { yyLOCAL = &LocateExpr{SubStr: yyDollar[3].exprUnion(), Str: yyDollar[5].exprUnion()} } @@ -20661,7 +20665,7 @@ yydefault: case 1283: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6584 +//line sql.y:6588 { yyLOCAL = &LockingFunc{Type: GetLock, Name: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion()} } @@ -20669,7 +20673,7 @@ yydefault: case 1284: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6588 +//line sql.y:6592 { yyLOCAL = &LockingFunc{Type: IsFreeLock, Name: yyDollar[3].exprUnion()} } @@ -20677,7 +20681,7 @@ yydefault: case 1285: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6592 +//line sql.y:6596 { yyLOCAL = &LockingFunc{Type: IsUsedLock, Name: yyDollar[3].exprUnion()} } @@ -20685,7 +20689,7 @@ yydefault: case 1286: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:6596 +//line sql.y:6600 { yyLOCAL = &LockingFunc{Type: ReleaseAllLocks} } @@ -20693,7 +20697,7 @@ yydefault: case 1287: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6600 +//line sql.y:6604 { yyLOCAL = &LockingFunc{Type: ReleaseLock, Name: yyDollar[3].exprUnion()} } @@ -20701,7 +20705,7 @@ yydefault: case 1288: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6604 +//line sql.y:6608 { yyLOCAL = &JSONSchemaValidFuncExpr{Schema: yyDollar[3].exprUnion(), Document: yyDollar[5].exprUnion()} } @@ -20709,7 +20713,7 @@ yydefault: case 1289: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6608 +//line sql.y:6612 { yyLOCAL = &JSONSchemaValidationReportFuncExpr{Schema: yyDollar[3].exprUnion(), Document: yyDollar[5].exprUnion()} } @@ -20717,7 +20721,7 @@ yydefault: case 1290: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6612 +//line sql.y:6616 { yyLOCAL = &JSONArrayExpr{Params: yyDollar[3].exprsUnion()} } @@ -20725,7 +20729,7 @@ yydefault: case 1291: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6616 +//line sql.y:6620 { yyLOCAL = &GeomFormatExpr{FormatType: BinaryFormat, Geom: yyDollar[3].exprUnion()} } @@ -20733,7 +20737,7 @@ yydefault: case 1292: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6620 +//line sql.y:6624 { yyLOCAL = &GeomFormatExpr{FormatType: BinaryFormat, Geom: yyDollar[3].exprUnion(), AxisOrderOpt: yyDollar[5].exprUnion()} } @@ -20741,7 +20745,7 @@ yydefault: case 1293: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6624 +//line sql.y:6628 { yyLOCAL = &GeomFormatExpr{FormatType: TextFormat, Geom: yyDollar[3].exprUnion()} } @@ -20749,7 +20753,7 @@ yydefault: case 1294: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6628 +//line sql.y:6632 { yyLOCAL = &GeomFormatExpr{FormatType: TextFormat, Geom: yyDollar[3].exprUnion(), AxisOrderOpt: yyDollar[5].exprUnion()} } @@ -20757,7 +20761,7 @@ yydefault: case 1295: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6632 +//line sql.y:6636 { yyLOCAL = &GeomPropertyFuncExpr{Property: IsEmpty, Geom: yyDollar[3].exprUnion()} } @@ -20765,7 +20769,7 @@ yydefault: case 1296: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6636 +//line sql.y:6640 { yyLOCAL = &GeomPropertyFuncExpr{Property: IsSimple, Geom: yyDollar[3].exprUnion()} } @@ -20773,7 +20777,7 @@ yydefault: case 1297: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6640 +//line sql.y:6644 { yyLOCAL = &GeomPropertyFuncExpr{Property: Dimension, Geom: yyDollar[3].exprUnion()} } @@ -20781,7 +20785,7 @@ yydefault: case 1298: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6644 +//line sql.y:6648 { yyLOCAL = &GeomPropertyFuncExpr{Property: Envelope, Geom: yyDollar[3].exprUnion()} } @@ -20789,7 +20793,7 @@ yydefault: case 1299: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6648 +//line sql.y:6652 { yyLOCAL = &GeomPropertyFuncExpr{Property: GeometryType, Geom: yyDollar[3].exprUnion()} } @@ -20797,7 +20801,7 @@ yydefault: case 1300: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6652 +//line sql.y:6656 { yyLOCAL = &PointPropertyFuncExpr{Property: Latitude, Point: yyDollar[3].exprUnion()} } @@ -20805,7 +20809,7 @@ yydefault: case 1301: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6656 +//line sql.y:6660 { yyLOCAL = &PointPropertyFuncExpr{Property: Latitude, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} } @@ -20813,7 +20817,7 @@ yydefault: case 1302: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6660 +//line sql.y:6664 { yyLOCAL = &PointPropertyFuncExpr{Property: Longitude, Point: yyDollar[3].exprUnion()} } @@ -20821,7 +20825,7 @@ yydefault: case 1303: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6664 +//line sql.y:6668 { yyLOCAL = &PointPropertyFuncExpr{Property: Longitude, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} } @@ -20829,7 +20833,7 @@ yydefault: case 1304: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6668 +//line sql.y:6672 { yyLOCAL = &LinestrPropertyFuncExpr{Property: EndPoint, Linestring: yyDollar[3].exprUnion()} } @@ -20837,7 +20841,7 @@ yydefault: case 1305: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6672 +//line sql.y:6676 { yyLOCAL = &LinestrPropertyFuncExpr{Property: IsClosed, Linestring: yyDollar[3].exprUnion()} } @@ -20845,7 +20849,7 @@ yydefault: case 1306: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6676 +//line sql.y:6680 { yyLOCAL = &LinestrPropertyFuncExpr{Property: Length, Linestring: yyDollar[3].exprUnion()} } @@ -20853,7 +20857,7 @@ yydefault: case 1307: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6680 +//line sql.y:6684 { yyLOCAL = &LinestrPropertyFuncExpr{Property: Length, Linestring: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} } @@ -20861,7 +20865,7 @@ yydefault: case 1308: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6684 +//line sql.y:6688 { yyLOCAL = &LinestrPropertyFuncExpr{Property: NumPoints, Linestring: yyDollar[3].exprUnion()} } @@ -20869,7 +20873,7 @@ yydefault: case 1309: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6688 +//line sql.y:6692 { yyLOCAL = &LinestrPropertyFuncExpr{Property: PointN, Linestring: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} } @@ -20877,7 +20881,7 @@ yydefault: case 1310: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6692 +//line sql.y:6696 { yyLOCAL = &LinestrPropertyFuncExpr{Property: StartPoint, Linestring: yyDollar[3].exprUnion()} } @@ -20885,7 +20889,7 @@ yydefault: case 1311: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6696 +//line sql.y:6700 { yyLOCAL = &PointPropertyFuncExpr{Property: XCordinate, Point: yyDollar[3].exprUnion()} } @@ -20893,7 +20897,7 @@ yydefault: case 1312: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6700 +//line sql.y:6704 { yyLOCAL = &PointPropertyFuncExpr{Property: XCordinate, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} } @@ -20901,7 +20905,7 @@ yydefault: case 1313: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6704 +//line sql.y:6708 { yyLOCAL = &PointPropertyFuncExpr{Property: YCordinate, Point: yyDollar[3].exprUnion()} } @@ -20909,7 +20913,7 @@ yydefault: case 1314: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6708 +//line sql.y:6712 { yyLOCAL = &PointPropertyFuncExpr{Property: YCordinate, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} } @@ -20917,7 +20921,7 @@ yydefault: case 1315: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6712 +//line sql.y:6716 { yyLOCAL = &GeomFromTextExpr{Type: GeometryFromText, WktText: yyDollar[3].exprUnion()} } @@ -20925,7 +20929,7 @@ yydefault: case 1316: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6716 +//line sql.y:6720 { yyLOCAL = &GeomFromTextExpr{Type: GeometryFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } @@ -20933,7 +20937,7 @@ yydefault: case 1317: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6720 +//line sql.y:6724 { yyLOCAL = &GeomFromTextExpr{Type: GeometryFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } @@ -20941,7 +20945,7 @@ yydefault: case 1318: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6724 +//line sql.y:6728 { yyLOCAL = &GeomFromTextExpr{Type: GeometryCollectionFromText, WktText: yyDollar[3].exprUnion()} } @@ -20949,7 +20953,7 @@ yydefault: case 1319: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6728 +//line sql.y:6732 { yyLOCAL = &GeomFromTextExpr{Type: GeometryCollectionFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } @@ -20957,7 +20961,7 @@ yydefault: case 1320: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6732 +//line sql.y:6736 { yyLOCAL = &GeomFromTextExpr{Type: GeometryCollectionFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } @@ -20965,7 +20969,7 @@ yydefault: case 1321: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6736 +//line sql.y:6740 { yyLOCAL = &GeomFromTextExpr{Type: LineStringFromText, WktText: yyDollar[3].exprUnion()} } @@ -20973,7 +20977,7 @@ yydefault: case 1322: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6740 +//line sql.y:6744 { yyLOCAL = &GeomFromTextExpr{Type: LineStringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } @@ -20981,7 +20985,7 @@ yydefault: case 1323: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6744 +//line sql.y:6748 { yyLOCAL = &GeomFromTextExpr{Type: LineStringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } @@ -20989,7 +20993,7 @@ yydefault: case 1324: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6748 +//line sql.y:6752 { yyLOCAL = &GeomFromTextExpr{Type: MultiLinestringFromText, WktText: yyDollar[3].exprUnion()} } @@ -20997,7 +21001,7 @@ yydefault: case 1325: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6752 +//line sql.y:6756 { yyLOCAL = &GeomFromTextExpr{Type: MultiLinestringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } @@ -21005,7 +21009,7 @@ yydefault: case 1326: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6756 +//line sql.y:6760 { yyLOCAL = &GeomFromTextExpr{Type: MultiLinestringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } @@ -21013,7 +21017,7 @@ yydefault: case 1327: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6760 +//line sql.y:6764 { yyLOCAL = &GeomFromTextExpr{Type: MultiPointFromText, WktText: yyDollar[3].exprUnion()} } @@ -21021,7 +21025,7 @@ yydefault: case 1328: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6764 +//line sql.y:6768 { yyLOCAL = &GeomFromTextExpr{Type: MultiPointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } @@ -21029,7 +21033,7 @@ yydefault: case 1329: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6768 +//line sql.y:6772 { yyLOCAL = &GeomFromTextExpr{Type: MultiPointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } @@ -21037,7 +21041,7 @@ yydefault: case 1330: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6772 +//line sql.y:6776 { yyLOCAL = &GeomFromTextExpr{Type: MultiPolygonFromText, WktText: yyDollar[3].exprUnion()} } @@ -21045,7 +21049,7 @@ yydefault: case 1331: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6776 +//line sql.y:6780 { yyLOCAL = &GeomFromTextExpr{Type: MultiPolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } @@ -21053,7 +21057,7 @@ yydefault: case 1332: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6780 +//line sql.y:6784 { yyLOCAL = &GeomFromTextExpr{Type: MultiPolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } @@ -21061,7 +21065,7 @@ yydefault: case 1333: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6784 +//line sql.y:6788 { yyLOCAL = &GeomFromTextExpr{Type: PointFromText, WktText: yyDollar[3].exprUnion()} } @@ -21069,7 +21073,7 @@ yydefault: case 1334: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6788 +//line sql.y:6792 { yyLOCAL = &GeomFromTextExpr{Type: PointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } @@ -21077,7 +21081,7 @@ yydefault: case 1335: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6792 +//line sql.y:6796 { yyLOCAL = &GeomFromTextExpr{Type: PointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } @@ -21085,7 +21089,7 @@ yydefault: case 1336: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6796 +//line sql.y:6800 { yyLOCAL = &GeomFromTextExpr{Type: PolygonFromText, WktText: yyDollar[3].exprUnion()} } @@ -21093,7 +21097,7 @@ yydefault: case 1337: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6800 +//line sql.y:6804 { yyLOCAL = &GeomFromTextExpr{Type: PolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } @@ -21101,7 +21105,7 @@ yydefault: case 1338: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6804 +//line sql.y:6808 { yyLOCAL = &GeomFromTextExpr{Type: PolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } @@ -21109,7 +21113,7 @@ yydefault: case 1339: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6808 +//line sql.y:6812 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryFromWKB, WkbBlob: yyDollar[3].exprUnion()} } @@ -21117,7 +21121,7 @@ yydefault: case 1340: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6812 +//line sql.y:6816 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } @@ -21125,7 +21129,7 @@ yydefault: case 1341: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6816 +//line sql.y:6820 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } @@ -21133,7 +21137,7 @@ yydefault: case 1342: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6820 +//line sql.y:6824 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryCollectionFromWKB, WkbBlob: yyDollar[3].exprUnion()} } @@ -21141,7 +21145,7 @@ yydefault: case 1343: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6824 +//line sql.y:6828 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryCollectionFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } @@ -21149,7 +21153,7 @@ yydefault: case 1344: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6828 +//line sql.y:6832 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryCollectionFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } @@ -21157,7 +21161,7 @@ yydefault: case 1345: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6832 +//line sql.y:6836 { yyLOCAL = &GeomFromWKBExpr{Type: LineStringFromWKB, WkbBlob: yyDollar[3].exprUnion()} } @@ -21165,7 +21169,7 @@ yydefault: case 1346: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6836 +//line sql.y:6840 { yyLOCAL = &GeomFromWKBExpr{Type: LineStringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } @@ -21173,7 +21177,7 @@ yydefault: case 1347: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6840 +//line sql.y:6844 { yyLOCAL = &GeomFromWKBExpr{Type: LineStringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } @@ -21181,7 +21185,7 @@ yydefault: case 1348: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6844 +//line sql.y:6848 { yyLOCAL = &GeomFromWKBExpr{Type: MultiLinestringFromWKB, WkbBlob: yyDollar[3].exprUnion()} } @@ -21189,7 +21193,7 @@ yydefault: case 1349: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6848 +//line sql.y:6852 { yyLOCAL = &GeomFromWKBExpr{Type: MultiLinestringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } @@ -21197,7 +21201,7 @@ yydefault: case 1350: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6852 +//line sql.y:6856 { yyLOCAL = &GeomFromWKBExpr{Type: MultiLinestringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } @@ -21205,7 +21209,7 @@ yydefault: case 1351: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6856 +//line sql.y:6860 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPointFromWKB, WkbBlob: yyDollar[3].exprUnion()} } @@ -21213,7 +21217,7 @@ yydefault: case 1352: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6860 +//line sql.y:6864 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } @@ -21221,7 +21225,7 @@ yydefault: case 1353: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6864 +//line sql.y:6868 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } @@ -21229,7 +21233,7 @@ yydefault: case 1354: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6868 +//line sql.y:6872 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPolygonFromWKB, WkbBlob: yyDollar[3].exprUnion()} } @@ -21237,7 +21241,7 @@ yydefault: case 1355: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6872 +//line sql.y:6876 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } @@ -21245,7 +21249,7 @@ yydefault: case 1356: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6876 +//line sql.y:6880 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } @@ -21253,7 +21257,7 @@ yydefault: case 1357: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6880 +//line sql.y:6884 { yyLOCAL = &GeomFromWKBExpr{Type: PointFromWKB, WkbBlob: yyDollar[3].exprUnion()} } @@ -21261,7 +21265,7 @@ yydefault: case 1358: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6884 +//line sql.y:6888 { yyLOCAL = &GeomFromWKBExpr{Type: PointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } @@ -21269,7 +21273,7 @@ yydefault: case 1359: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6888 +//line sql.y:6892 { yyLOCAL = &GeomFromWKBExpr{Type: PointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } @@ -21277,7 +21281,7 @@ yydefault: case 1360: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6892 +//line sql.y:6896 { yyLOCAL = &GeomFromWKBExpr{Type: PolygonFromWKB, WkbBlob: yyDollar[3].exprUnion()} } @@ -21285,7 +21289,7 @@ yydefault: case 1361: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6896 +//line sql.y:6900 { yyLOCAL = &GeomFromWKBExpr{Type: PolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } @@ -21293,7 +21297,7 @@ yydefault: case 1362: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6900 +//line sql.y:6904 { yyLOCAL = &GeomFromWKBExpr{Type: PolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } @@ -21301,7 +21305,7 @@ yydefault: case 1363: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6904 +//line sql.y:6908 { yyLOCAL = &PolygonPropertyFuncExpr{Property: Area, Polygon: yyDollar[3].exprUnion()} } @@ -21309,7 +21313,7 @@ yydefault: case 1364: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6908 +//line sql.y:6912 { yyLOCAL = &PolygonPropertyFuncExpr{Property: Centroid, Polygon: yyDollar[3].exprUnion()} } @@ -21317,7 +21321,7 @@ yydefault: case 1365: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6912 +//line sql.y:6916 { yyLOCAL = &PolygonPropertyFuncExpr{Property: ExteriorRing, Polygon: yyDollar[3].exprUnion()} } @@ -21325,7 +21329,7 @@ yydefault: case 1366: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6916 +//line sql.y:6920 { yyLOCAL = &PolygonPropertyFuncExpr{Property: InteriorRingN, Polygon: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} } @@ -21333,7 +21337,7 @@ yydefault: case 1367: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6920 +//line sql.y:6924 { yyLOCAL = &PolygonPropertyFuncExpr{Property: NumInteriorRings, Polygon: yyDollar[3].exprUnion()} } @@ -21341,7 +21345,7 @@ yydefault: case 1368: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6924 +//line sql.y:6928 { yyLOCAL = &GeomCollPropertyFuncExpr{Property: GeometryN, GeomColl: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} } @@ -21349,7 +21353,7 @@ yydefault: case 1369: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6928 +//line sql.y:6932 { yyLOCAL = &GeomCollPropertyFuncExpr{Property: NumGeometries, GeomColl: yyDollar[3].exprUnion()} } @@ -21357,7 +21361,7 @@ yydefault: case 1370: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6932 +//line sql.y:6936 { yyLOCAL = &GeoHashFromLatLongExpr{Longitude: yyDollar[3].exprUnion(), Latitude: yyDollar[5].exprUnion(), MaxLength: yyDollar[7].exprUnion()} } @@ -21365,7 +21369,7 @@ yydefault: case 1371: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6936 +//line sql.y:6940 { yyLOCAL = &GeoHashFromPointExpr{Point: yyDollar[3].exprUnion(), MaxLength: yyDollar[5].exprUnion()} } @@ -21373,7 +21377,7 @@ yydefault: case 1372: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6940 +//line sql.y:6944 { yyLOCAL = &GeomFromGeoHashExpr{GeomType: LatitudeFromHash, GeoHash: yyDollar[3].exprUnion()} } @@ -21381,7 +21385,7 @@ yydefault: case 1373: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6944 +//line sql.y:6948 { yyLOCAL = &GeomFromGeoHashExpr{GeomType: LongitudeFromHash, GeoHash: yyDollar[3].exprUnion()} } @@ -21389,7 +21393,7 @@ yydefault: case 1374: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6948 +//line sql.y:6952 { yyLOCAL = &GeomFromGeoHashExpr{GeomType: PointFromHash, GeoHash: yyDollar[3].exprUnion(), SridOpt: yyDollar[5].exprUnion()} } @@ -21397,7 +21401,7 @@ yydefault: case 1375: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6952 +//line sql.y:6956 { yyLOCAL = &GeomFromGeoJSONExpr{GeoJSON: yyDollar[3].exprUnion()} } @@ -21405,7 +21409,7 @@ yydefault: case 1376: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6956 +//line sql.y:6960 { yyLOCAL = &GeomFromGeoJSONExpr{GeoJSON: yyDollar[3].exprUnion(), HigherDimHandlerOpt: yyDollar[5].exprUnion()} } @@ -21413,7 +21417,7 @@ yydefault: case 1377: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6960 +//line sql.y:6964 { yyLOCAL = &GeomFromGeoJSONExpr{GeoJSON: yyDollar[3].exprUnion(), HigherDimHandlerOpt: yyDollar[5].exprUnion(), Srid: yyDollar[7].exprUnion()} } @@ -21421,7 +21425,7 @@ yydefault: case 1378: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6964 +//line sql.y:6968 { yyLOCAL = &GeoJSONFromGeomExpr{Geom: yyDollar[3].exprUnion()} } @@ -21429,7 +21433,7 @@ yydefault: case 1379: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6968 +//line sql.y:6972 { yyLOCAL = &GeoJSONFromGeomExpr{Geom: yyDollar[3].exprUnion(), MaxDecimalDigits: yyDollar[5].exprUnion()} } @@ -21437,7 +21441,7 @@ yydefault: case 1380: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6972 +//line sql.y:6976 { yyLOCAL = &GeoJSONFromGeomExpr{Geom: yyDollar[3].exprUnion(), MaxDecimalDigits: yyDollar[5].exprUnion(), Bitmask: yyDollar[7].exprUnion()} } @@ -21445,7 +21449,7 @@ yydefault: case 1381: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6976 +//line sql.y:6980 { yyLOCAL = &JSONObjectExpr{Params: yyDollar[3].jsonObjectParamsUnion()} } @@ -21453,7 +21457,7 @@ yydefault: case 1382: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6980 +//line sql.y:6984 { yyLOCAL = &JSONQuoteExpr{StringArg: yyDollar[3].exprUnion()} } @@ -21461,7 +21465,7 @@ yydefault: case 1383: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6984 +//line sql.y:6988 { yyLOCAL = &JSONContainsExpr{Target: yyDollar[3].exprUnion(), Candidate: yyDollar[5].exprsUnion()[0], PathList: yyDollar[5].exprsUnion()[1:]} } @@ -21469,7 +21473,7 @@ yydefault: case 1384: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6988 +//line sql.y:6992 { yyLOCAL = &JSONContainsPathExpr{JSONDoc: yyDollar[3].exprUnion(), OneOrAll: yyDollar[5].exprUnion(), PathList: yyDollar[7].exprsUnion()} } @@ -21477,7 +21481,7 @@ yydefault: case 1385: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6992 +//line sql.y:6996 { yyLOCAL = &JSONExtractExpr{JSONDoc: yyDollar[3].exprUnion(), PathList: yyDollar[5].exprsUnion()} } @@ -21485,7 +21489,7 @@ yydefault: case 1386: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6996 +//line sql.y:7000 { yyLOCAL = &JSONKeysExpr{JSONDoc: yyDollar[3].exprUnion()} } @@ -21493,7 +21497,7 @@ yydefault: case 1387: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7000 +//line sql.y:7004 { yyLOCAL = &JSONKeysExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion()} } @@ -21501,7 +21505,7 @@ yydefault: case 1388: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7004 +//line sql.y:7008 { yyLOCAL = &JSONOverlapsExpr{JSONDoc1: yyDollar[3].exprUnion(), JSONDoc2: yyDollar[5].exprUnion()} } @@ -21509,7 +21513,7 @@ yydefault: case 1389: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7008 +//line sql.y:7012 { yyLOCAL = &JSONSearchExpr{JSONDoc: yyDollar[3].exprUnion(), OneOrAll: yyDollar[5].exprUnion(), SearchStr: yyDollar[7].exprUnion()} } @@ -21517,7 +21521,7 @@ yydefault: case 1390: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:7012 +//line sql.y:7016 { yyLOCAL = &JSONSearchExpr{JSONDoc: yyDollar[3].exprUnion(), OneOrAll: yyDollar[5].exprUnion(), SearchStr: yyDollar[7].exprUnion(), EscapeChar: yyDollar[9].exprsUnion()[0], PathList: yyDollar[9].exprsUnion()[1:]} } @@ -21525,7 +21529,7 @@ yydefault: case 1391: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr -//line sql.y:7016 +//line sql.y:7020 { yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion()} } @@ -21533,7 +21537,7 @@ yydefault: case 1392: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7020 +//line sql.y:7024 { yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion(), EmptyOnResponse: yyDollar[7].jtOnResponseUnion()} } @@ -21541,7 +21545,7 @@ yydefault: case 1393: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7024 +//line sql.y:7028 { yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion(), ErrorOnResponse: yyDollar[7].jtOnResponseUnion()} } @@ -21549,7 +21553,7 @@ yydefault: case 1394: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL Expr -//line sql.y:7028 +//line sql.y:7032 { yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion(), EmptyOnResponse: yyDollar[7].jtOnResponseUnion(), ErrorOnResponse: yyDollar[8].jtOnResponseUnion()} } @@ -21557,7 +21561,7 @@ yydefault: case 1395: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7032 +//line sql.y:7036 { yyLOCAL = &JSONAttributesExpr{Type: DepthAttributeType, JSONDoc: yyDollar[3].exprUnion()} } @@ -21565,7 +21569,7 @@ yydefault: case 1396: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7036 +//line sql.y:7040 { yyLOCAL = &JSONAttributesExpr{Type: ValidAttributeType, JSONDoc: yyDollar[3].exprUnion()} } @@ -21573,7 +21577,7 @@ yydefault: case 1397: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7040 +//line sql.y:7044 { yyLOCAL = &JSONAttributesExpr{Type: TypeAttributeType, JSONDoc: yyDollar[3].exprUnion()} } @@ -21581,7 +21585,7 @@ yydefault: case 1398: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7044 +//line sql.y:7048 { yyLOCAL = &JSONAttributesExpr{Type: LengthAttributeType, JSONDoc: yyDollar[3].exprUnion()} } @@ -21589,7 +21593,7 @@ yydefault: case 1399: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7048 +//line sql.y:7052 { yyLOCAL = &JSONAttributesExpr{Type: LengthAttributeType, JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion()} } @@ -21597,7 +21601,7 @@ yydefault: case 1400: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7052 +//line sql.y:7056 { yyLOCAL = &JSONValueModifierExpr{Type: JSONArrayAppendType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } @@ -21605,7 +21609,7 @@ yydefault: case 1401: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7056 +//line sql.y:7060 { yyLOCAL = &JSONValueModifierExpr{Type: JSONArrayInsertType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } @@ -21613,7 +21617,7 @@ yydefault: case 1402: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7060 +//line sql.y:7064 { yyLOCAL = &JSONValueModifierExpr{Type: JSONInsertType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } @@ -21621,7 +21625,7 @@ yydefault: case 1403: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7064 +//line sql.y:7068 { yyLOCAL = &JSONValueModifierExpr{Type: JSONReplaceType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } @@ -21629,7 +21633,7 @@ yydefault: case 1404: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7068 +//line sql.y:7072 { yyLOCAL = &JSONValueModifierExpr{Type: JSONSetType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } @@ -21637,7 +21641,7 @@ yydefault: case 1405: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7072 +//line sql.y:7076 { yyLOCAL = &JSONValueMergeExpr{Type: JSONMergeType, JSONDoc: yyDollar[3].exprUnion(), JSONDocList: yyDollar[5].exprsUnion()} } @@ -21645,7 +21649,7 @@ yydefault: case 1406: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7076 +//line sql.y:7080 { yyLOCAL = &JSONValueMergeExpr{Type: JSONMergePatchType, JSONDoc: yyDollar[3].exprUnion(), JSONDocList: yyDollar[5].exprsUnion()} } @@ -21653,7 +21657,7 @@ yydefault: case 1407: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7080 +//line sql.y:7084 { yyLOCAL = &JSONValueMergeExpr{Type: JSONMergePreserveType, JSONDoc: yyDollar[3].exprUnion(), JSONDocList: yyDollar[5].exprsUnion()} } @@ -21661,7 +21665,7 @@ yydefault: case 1408: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7084 +//line sql.y:7088 { yyLOCAL = &JSONRemoveExpr{JSONDoc: yyDollar[3].exprUnion(), PathList: yyDollar[5].exprsUnion()} } @@ -21669,7 +21673,7 @@ yydefault: case 1409: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7088 +//line sql.y:7092 { yyLOCAL = &JSONUnquoteExpr{JSONValue: yyDollar[3].exprUnion()} } @@ -21677,7 +21681,7 @@ yydefault: case 1410: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7092 +//line sql.y:7096 { yyLOCAL = &MultiPolygonExpr{PolygonParams: yyDollar[3].exprsUnion()} } @@ -21685,7 +21689,7 @@ yydefault: case 1411: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7096 +//line sql.y:7100 { yyLOCAL = &MultiPointExpr{PointParams: yyDollar[3].exprsUnion()} } @@ -21693,7 +21697,7 @@ yydefault: case 1412: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7100 +//line sql.y:7104 { yyLOCAL = &MultiLinestringExpr{LinestringParams: yyDollar[3].exprsUnion()} } @@ -21701,7 +21705,7 @@ yydefault: case 1413: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7104 +//line sql.y:7108 { yyLOCAL = &PolygonExpr{LinestringParams: yyDollar[3].exprsUnion()} } @@ -21709,7 +21713,7 @@ yydefault: case 1414: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7108 +//line sql.y:7112 { yyLOCAL = &LineStringExpr{PointParams: yyDollar[3].exprsUnion()} } @@ -21717,7 +21721,7 @@ yydefault: case 1415: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7112 +//line sql.y:7116 { yyLOCAL = &PointExpr{XCordinate: yyDollar[3].exprUnion(), YCordinate: yyDollar[5].exprUnion()} } @@ -21725,7 +21729,7 @@ yydefault: case 1416: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7116 +//line sql.y:7120 { yyLOCAL = &ArgumentLessWindowExpr{Type: yyDollar[1].argumentLessWindowExprTypeUnion(), OverClause: yyDollar[4].overClauseUnion()} } @@ -21733,7 +21737,7 @@ yydefault: case 1417: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7120 +//line sql.y:7124 { yyLOCAL = &FirstOrLastValueExpr{Type: yyDollar[1].firstOrLastValueExprTypeUnion(), Expr: yyDollar[3].exprUnion(), NullTreatmentClause: yyDollar[5].nullTreatmentClauseUnion(), OverClause: yyDollar[6].overClauseUnion()} } @@ -21741,7 +21745,7 @@ yydefault: case 1418: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:7124 +//line sql.y:7128 { yyLOCAL = &NtileExpr{N: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } @@ -21749,7 +21753,7 @@ yydefault: case 1419: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL Expr -//line sql.y:7128 +//line sql.y:7132 { yyLOCAL = &NTHValueExpr{Expr: yyDollar[3].exprUnion(), N: yyDollar[5].exprUnion(), FromFirstLastClause: yyDollar[7].fromFirstLastClauseUnion(), NullTreatmentClause: yyDollar[8].nullTreatmentClauseUnion(), OverClause: yyDollar[9].overClauseUnion()} } @@ -21757,7 +21761,7 @@ yydefault: case 1420: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7132 +//line sql.y:7136 { yyLOCAL = &LagLeadExpr{Type: yyDollar[1].lagLeadExprTypeUnion(), Expr: yyDollar[3].exprUnion(), NullTreatmentClause: yyDollar[5].nullTreatmentClauseUnion(), OverClause: yyDollar[6].overClauseUnion()} } @@ -21765,7 +21769,7 @@ yydefault: case 1421: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL Expr -//line sql.y:7136 +//line sql.y:7140 { yyLOCAL = &LagLeadExpr{Type: yyDollar[1].lagLeadExprTypeUnion(), Expr: yyDollar[3].exprUnion(), N: yyDollar[5].exprUnion(), Default: yyDollar[6].exprUnion(), NullTreatmentClause: yyDollar[8].nullTreatmentClauseUnion(), OverClause: yyDollar[9].overClauseUnion()} } @@ -21773,7 +21777,7 @@ yydefault: case 1422: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7140 +//line sql.y:7144 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprAdddate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} } @@ -21781,7 +21785,7 @@ yydefault: case 1423: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7144 +//line sql.y:7148 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprAdddate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[5].exprUnion(), Unit: IntervalNone} } @@ -21789,7 +21793,7 @@ yydefault: case 1424: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7148 +//line sql.y:7152 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprDateAdd, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} } @@ -21797,7 +21801,7 @@ yydefault: case 1425: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7152 +//line sql.y:7156 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprDateSub, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} } @@ -21805,7 +21809,7 @@ yydefault: case 1426: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7156 +//line sql.y:7160 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprSubdate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} } @@ -21813,7 +21817,7 @@ yydefault: case 1427: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7160 +//line sql.y:7164 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprSubdate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[5].exprUnion(), Unit: IntervalNone} } @@ -21821,7 +21825,7 @@ yydefault: case 1432: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7170 +//line sql.y:7174 { yyLOCAL = yyDollar[1].exprUnion() } @@ -21829,7 +21833,7 @@ yydefault: case 1433: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7174 +//line sql.y:7178 { yyLOCAL = NewIntLiteral(yyDollar[1].str) } @@ -21837,7 +21841,7 @@ yydefault: case 1434: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7178 +//line sql.y:7182 { yyLOCAL = yyDollar[1].variableUnion() } @@ -21845,7 +21849,7 @@ yydefault: case 1435: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7182 +//line sql.y:7186 { yyLOCAL = parseBindVariable(yylex, yyDollar[1].str[1:]) } @@ -21853,7 +21857,7 @@ yydefault: case 1436: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:7187 +//line sql.y:7191 { yyLOCAL = nil } @@ -21861,7 +21865,7 @@ yydefault: case 1437: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7191 +//line sql.y:7195 { yyLOCAL = yyDollar[2].exprUnion() } @@ -21869,7 +21873,7 @@ yydefault: case 1438: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7197 +//line sql.y:7201 { yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion()} } @@ -21877,7 +21881,7 @@ yydefault: case 1439: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7201 +//line sql.y:7205 { yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion()} } @@ -21885,7 +21889,7 @@ yydefault: case 1440: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:7205 +//line sql.y:7209 { yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion()} } @@ -21893,7 +21897,7 @@ yydefault: case 1441: yyDollar = yyS[yypt-12 : yypt+1] var yyLOCAL Expr -//line sql.y:7209 +//line sql.y:7213 { yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion(), ReturnOption: yyDollar[11].exprUnion()} } @@ -21901,7 +21905,7 @@ yydefault: case 1442: yyDollar = yyS[yypt-14 : yypt+1] var yyLOCAL Expr -//line sql.y:7213 +//line sql.y:7217 { // Match type is kept expression as TRIM( ' m ') is accepted yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion(), ReturnOption: yyDollar[11].exprUnion(), MatchType: yyDollar[13].exprUnion()} @@ -21910,7 +21914,7 @@ yydefault: case 1443: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7218 +//line sql.y:7222 { yyLOCAL = &RegexpLikeExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion()} } @@ -21918,7 +21922,7 @@ yydefault: case 1444: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7222 +//line sql.y:7226 { yyLOCAL = &RegexpLikeExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), MatchType: yyDollar[7].exprUnion()} } @@ -21926,7 +21930,7 @@ yydefault: case 1445: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7226 +//line sql.y:7230 { yyLOCAL = &RegexpReplaceExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Repl: yyDollar[7].exprUnion()} } @@ -21934,7 +21938,7 @@ yydefault: case 1446: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:7230 +//line sql.y:7234 { yyLOCAL = &RegexpReplaceExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Repl: yyDollar[7].exprUnion(), Position: yyDollar[9].exprUnion()} } @@ -21942,7 +21946,7 @@ yydefault: case 1447: yyDollar = yyS[yypt-12 : yypt+1] var yyLOCAL Expr -//line sql.y:7234 +//line sql.y:7238 { yyLOCAL = &RegexpReplaceExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Repl: yyDollar[7].exprUnion(), Position: yyDollar[9].exprUnion(), Occurrence: yyDollar[11].exprUnion()} } @@ -21950,7 +21954,7 @@ yydefault: case 1448: yyDollar = yyS[yypt-14 : yypt+1] var yyLOCAL Expr -//line sql.y:7238 +//line sql.y:7242 { // Match type is kept expression as TRIM( ' m ') is accepted yyLOCAL = &RegexpReplaceExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Repl: yyDollar[7].exprUnion(), Position: yyDollar[9].exprUnion(), Occurrence: yyDollar[11].exprUnion(), MatchType: yyDollar[13].exprUnion()} @@ -21959,7 +21963,7 @@ yydefault: case 1449: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7243 +//line sql.y:7247 { yyLOCAL = &RegexpSubstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion()} } @@ -21967,7 +21971,7 @@ yydefault: case 1450: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7247 +//line sql.y:7251 { yyLOCAL = &RegexpSubstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion()} } @@ -21975,7 +21979,7 @@ yydefault: case 1451: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:7251 +//line sql.y:7255 { yyLOCAL = &RegexpSubstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion()} } @@ -21983,7 +21987,7 @@ yydefault: case 1452: yyDollar = yyS[yypt-12 : yypt+1] var yyLOCAL Expr -//line sql.y:7255 +//line sql.y:7259 { // Match type is kept expression as TRIM( ' m ') is accepted yyLOCAL = &RegexpSubstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion(), MatchType: yyDollar[11].exprUnion()} @@ -21992,7 +21996,7 @@ yydefault: case 1453: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7262 +//line sql.y:7266 { yyLOCAL = &ExtractValueExpr{Fragment: yyDollar[3].exprUnion(), XPathExpr: yyDollar[5].exprUnion()} } @@ -22000,7 +22004,7 @@ yydefault: case 1454: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7266 +//line sql.y:7270 { yyLOCAL = &UpdateXMLExpr{Target: yyDollar[3].exprUnion(), XPathExpr: yyDollar[5].exprUnion(), NewXML: yyDollar[7].exprUnion()} } @@ -22008,7 +22012,7 @@ yydefault: case 1455: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7272 +//line sql.y:7276 { yyLOCAL = &PerformanceSchemaFuncExpr{Type: FormatBytesType, Argument: yyDollar[3].exprUnion()} } @@ -22016,7 +22020,7 @@ yydefault: case 1456: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7276 +//line sql.y:7280 { yyLOCAL = &PerformanceSchemaFuncExpr{Type: FormatPicoTimeType, Argument: yyDollar[3].exprUnion()} } @@ -22024,7 +22028,7 @@ yydefault: case 1457: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:7280 +//line sql.y:7284 { yyLOCAL = &PerformanceSchemaFuncExpr{Type: PsCurrentThreadIDType} } @@ -22032,7 +22036,7 @@ yydefault: case 1458: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7284 +//line sql.y:7288 { yyLOCAL = &PerformanceSchemaFuncExpr{Type: PsThreadIDType, Argument: yyDollar[3].exprUnion()} } @@ -22040,7 +22044,7 @@ yydefault: case 1459: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7290 +//line sql.y:7294 { yyLOCAL = >IDFuncExpr{Type: GTIDSubsetType, Set1: yyDollar[3].exprUnion(), Set2: yyDollar[5].exprUnion()} } @@ -22048,7 +22052,7 @@ yydefault: case 1460: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7294 +//line sql.y:7298 { yyLOCAL = >IDFuncExpr{Type: GTIDSubtractType, Set1: yyDollar[3].exprUnion(), Set2: yyDollar[5].exprUnion()} } @@ -22056,7 +22060,7 @@ yydefault: case 1461: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7298 +//line sql.y:7302 { yyLOCAL = >IDFuncExpr{Type: WaitForExecutedGTIDSetType, Set1: yyDollar[3].exprUnion()} } @@ -22064,7 +22068,7 @@ yydefault: case 1462: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7302 +//line sql.y:7306 { yyLOCAL = >IDFuncExpr{Type: WaitForExecutedGTIDSetType, Set1: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion()} } @@ -22072,7 +22076,7 @@ yydefault: case 1463: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7306 +//line sql.y:7310 { yyLOCAL = >IDFuncExpr{Type: WaitUntilSQLThreadAfterGTIDSType, Set1: yyDollar[3].exprUnion()} } @@ -22080,7 +22084,7 @@ yydefault: case 1464: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7310 +//line sql.y:7314 { yyLOCAL = >IDFuncExpr{Type: WaitUntilSQLThreadAfterGTIDSType, Set1: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion()} } @@ -22088,7 +22092,7 @@ yydefault: case 1465: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7314 +//line sql.y:7318 { yyLOCAL = >IDFuncExpr{Type: WaitUntilSQLThreadAfterGTIDSType, Set1: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion(), Channel: yyDollar[7].exprUnion()} } @@ -22096,7 +22100,7 @@ yydefault: case 1466: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7319 +//line sql.y:7323 { yyLOCAL = nil } @@ -22104,7 +22108,7 @@ yydefault: case 1467: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7323 +//line sql.y:7327 { yyLOCAL = yyDollar[2].convertTypeUnion() } @@ -22112,7 +22116,7 @@ yydefault: case 1468: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7329 +//line sql.y:7333 { yyLOCAL = IntervalDayHour } @@ -22120,7 +22124,7 @@ yydefault: case 1469: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7333 +//line sql.y:7337 { yyLOCAL = IntervalDayMicrosecond } @@ -22128,7 +22132,7 @@ yydefault: case 1470: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7337 +//line sql.y:7341 { yyLOCAL = IntervalDayMinute } @@ -22136,7 +22140,7 @@ yydefault: case 1471: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7341 +//line sql.y:7345 { yyLOCAL = IntervalDaySecond } @@ -22144,7 +22148,7 @@ yydefault: case 1472: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7345 +//line sql.y:7349 { yyLOCAL = IntervalHourMicrosecond } @@ -22152,7 +22156,7 @@ yydefault: case 1473: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7349 +//line sql.y:7353 { yyLOCAL = IntervalHourMinute } @@ -22160,7 +22164,7 @@ yydefault: case 1474: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7353 +//line sql.y:7357 { yyLOCAL = IntervalHourSecond } @@ -22168,7 +22172,7 @@ yydefault: case 1475: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7357 +//line sql.y:7361 { yyLOCAL = IntervalMinuteMicrosecond } @@ -22176,7 +22180,7 @@ yydefault: case 1476: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7361 +//line sql.y:7365 { yyLOCAL = IntervalMinuteSecond } @@ -22184,7 +22188,7 @@ yydefault: case 1477: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7365 +//line sql.y:7369 { yyLOCAL = IntervalSecondMicrosecond } @@ -22192,7 +22196,7 @@ yydefault: case 1478: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7369 +//line sql.y:7373 { yyLOCAL = IntervalYearMonth } @@ -22200,7 +22204,7 @@ yydefault: case 1479: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7373 +//line sql.y:7377 { yyLOCAL = IntervalDay } @@ -22208,7 +22212,7 @@ yydefault: case 1480: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7377 +//line sql.y:7381 { yyLOCAL = IntervalWeek } @@ -22216,7 +22220,7 @@ yydefault: case 1481: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7381 +//line sql.y:7385 { yyLOCAL = IntervalHour } @@ -22224,7 +22228,7 @@ yydefault: case 1482: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7385 +//line sql.y:7389 { yyLOCAL = IntervalMinute } @@ -22232,7 +22236,7 @@ yydefault: case 1483: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7389 +//line sql.y:7393 { yyLOCAL = IntervalMonth } @@ -22240,7 +22244,7 @@ yydefault: case 1484: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7393 +//line sql.y:7397 { yyLOCAL = IntervalQuarter } @@ -22248,7 +22252,7 @@ yydefault: case 1485: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7397 +//line sql.y:7401 { yyLOCAL = IntervalSecond } @@ -22256,7 +22260,7 @@ yydefault: case 1486: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7401 +//line sql.y:7405 { yyLOCAL = IntervalMicrosecond } @@ -22264,7 +22268,7 @@ yydefault: case 1487: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7405 +//line sql.y:7409 { yyLOCAL = IntervalYear } @@ -22272,7 +22276,7 @@ yydefault: case 1488: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7411 +//line sql.y:7415 { yyLOCAL = IntervalDay } @@ -22280,7 +22284,7 @@ yydefault: case 1489: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7415 +//line sql.y:7419 { yyLOCAL = IntervalWeek } @@ -22288,7 +22292,7 @@ yydefault: case 1490: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7419 +//line sql.y:7423 { yyLOCAL = IntervalHour } @@ -22296,7 +22300,7 @@ yydefault: case 1491: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7423 +//line sql.y:7427 { yyLOCAL = IntervalMinute } @@ -22304,7 +22308,7 @@ yydefault: case 1492: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7427 +//line sql.y:7431 { yyLOCAL = IntervalMonth } @@ -22312,7 +22316,7 @@ yydefault: case 1493: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7431 +//line sql.y:7435 { yyLOCAL = IntervalQuarter } @@ -22320,7 +22324,7 @@ yydefault: case 1494: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7435 +//line sql.y:7439 { yyLOCAL = IntervalSecond } @@ -22328,7 +22332,7 @@ yydefault: case 1495: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7439 +//line sql.y:7443 { yyLOCAL = IntervalMicrosecond } @@ -22336,7 +22340,7 @@ yydefault: case 1496: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7443 +//line sql.y:7447 { yyLOCAL = IntervalYear } @@ -22344,7 +22348,7 @@ yydefault: case 1497: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7447 +//line sql.y:7451 { yyLOCAL = IntervalDay } @@ -22352,7 +22356,7 @@ yydefault: case 1498: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7451 +//line sql.y:7455 { yyLOCAL = IntervalWeek } @@ -22360,7 +22364,7 @@ yydefault: case 1499: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7455 +//line sql.y:7459 { yyLOCAL = IntervalHour } @@ -22368,7 +22372,7 @@ yydefault: case 1500: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7459 +//line sql.y:7463 { yyLOCAL = IntervalMinute } @@ -22376,7 +22380,7 @@ yydefault: case 1501: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7463 +//line sql.y:7467 { yyLOCAL = IntervalMonth } @@ -22384,7 +22388,7 @@ yydefault: case 1502: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7467 +//line sql.y:7471 { yyLOCAL = IntervalQuarter } @@ -22392,7 +22396,7 @@ yydefault: case 1503: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7471 +//line sql.y:7475 { yyLOCAL = IntervalSecond } @@ -22400,7 +22404,7 @@ yydefault: case 1504: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7475 +//line sql.y:7479 { yyLOCAL = IntervalMicrosecond } @@ -22408,7 +22412,7 @@ yydefault: case 1505: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7479 +//line sql.y:7483 { yyLOCAL = IntervalYear } @@ -22416,7 +22420,7 @@ yydefault: case 1508: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int -//line sql.y:7489 +//line sql.y:7493 { yyLOCAL = 0 } @@ -22424,7 +22428,7 @@ yydefault: case 1509: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL int -//line sql.y:7493 +//line sql.y:7497 { yyLOCAL = 0 } @@ -22432,7 +22436,7 @@ yydefault: case 1510: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int -//line sql.y:7497 +//line sql.y:7501 { yyLOCAL = convertStringToInt(yyDollar[2].str) } @@ -22440,7 +22444,7 @@ yydefault: case 1511: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7507 +//line sql.y:7511 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("if"), Exprs: yyDollar[3].exprsUnion()} } @@ -22448,7 +22452,7 @@ yydefault: case 1512: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7511 +//line sql.y:7515 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("database"), Exprs: yyDollar[3].exprsUnion()} } @@ -22456,7 +22460,7 @@ yydefault: case 1513: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7515 +//line sql.y:7519 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("schema"), Exprs: yyDollar[3].exprsUnion()} } @@ -22464,7 +22468,7 @@ yydefault: case 1514: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7519 +//line sql.y:7523 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("mod"), Exprs: yyDollar[3].exprsUnion()} } @@ -22472,7 +22476,7 @@ yydefault: case 1515: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7523 +//line sql.y:7527 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("replace"), Exprs: yyDollar[3].exprsUnion()} } @@ -22480,7 +22484,7 @@ yydefault: case 1516: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7529 +//line sql.y:7533 { yyLOCAL = NoOption } @@ -22488,7 +22492,7 @@ yydefault: case 1517: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7533 +//line sql.y:7537 { yyLOCAL = BooleanModeOpt } @@ -22496,7 +22500,7 @@ yydefault: case 1518: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7537 +//line sql.y:7541 { yyLOCAL = NaturalLanguageModeOpt } @@ -22504,7 +22508,7 @@ yydefault: case 1519: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7541 +//line sql.y:7545 { yyLOCAL = NaturalLanguageModeWithQueryExpansionOpt } @@ -22512,33 +22516,33 @@ yydefault: case 1520: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7545 +//line sql.y:7549 { yyLOCAL = QueryExpansionOpt } yyVAL.union = yyLOCAL case 1521: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7551 +//line sql.y:7555 { yyVAL.str = string(yyDollar[1].identifierCI.String()) } case 1522: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7555 +//line sql.y:7559 { yyVAL.str = string(yyDollar[1].str) } case 1523: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7559 +//line sql.y:7563 { yyVAL.str = string(yyDollar[1].str) } case 1524: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7565 +//line sql.y:7569 { yyLOCAL = nil } @@ -22546,7 +22550,7 @@ yydefault: case 1525: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7569 +//line sql.y:7573 { yyLOCAL = &ConvertType{Type: string(yyDollar[2].str), Length: ptr.Of(convertStringToInt(yyDollar[4].str))} } @@ -22554,7 +22558,7 @@ yydefault: case 1526: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7573 +//line sql.y:7577 { yyLOCAL = &ConvertType{Type: string(yyDollar[2].str), Length: ptr.Of(convertStringToInt(yyDollar[4].str))} } @@ -22562,7 +22566,7 @@ yydefault: case 1527: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7579 +//line sql.y:7583 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } @@ -22570,7 +22574,7 @@ yydefault: case 1528: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7583 +//line sql.y:7587 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion(), Charset: yyDollar[3].columnCharset} } @@ -22578,7 +22582,7 @@ yydefault: case 1529: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7587 +//line sql.y:7591 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } @@ -22586,7 +22590,7 @@ yydefault: case 1530: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7591 +//line sql.y:7595 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } @@ -22594,7 +22598,7 @@ yydefault: case 1531: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7595 +//line sql.y:7599 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} yyLOCAL.Length = yyDollar[2].LengthScaleOption.Length @@ -22604,7 +22608,7 @@ yydefault: case 1532: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7601 +//line sql.y:7605 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } @@ -22612,7 +22616,7 @@ yydefault: case 1533: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7605 +//line sql.y:7609 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } @@ -22620,7 +22624,7 @@ yydefault: case 1534: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7609 +//line sql.y:7613 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } @@ -22628,7 +22632,7 @@ yydefault: case 1535: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7613 +//line sql.y:7617 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } @@ -22636,7 +22640,7 @@ yydefault: case 1536: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7617 +//line sql.y:7621 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } @@ -22644,7 +22648,7 @@ yydefault: case 1537: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7621 +//line sql.y:7625 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } @@ -22652,7 +22656,7 @@ yydefault: case 1538: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7625 +//line sql.y:7629 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } @@ -22660,7 +22664,7 @@ yydefault: case 1539: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7629 +//line sql.y:7633 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } @@ -22668,7 +22672,7 @@ yydefault: case 1540: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7633 +//line sql.y:7637 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } @@ -22676,7 +22680,7 @@ yydefault: case 1541: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7637 +//line sql.y:7641 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } @@ -22684,7 +22688,7 @@ yydefault: case 1542: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7643 +//line sql.y:7647 { yyLOCAL = false } @@ -22692,7 +22696,7 @@ yydefault: case 1543: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:7647 +//line sql.y:7651 { yyLOCAL = true } @@ -22700,7 +22704,7 @@ yydefault: case 1544: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:7652 +//line sql.y:7656 { yyLOCAL = nil } @@ -22708,34 +22712,34 @@ yydefault: case 1545: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7656 +//line sql.y:7660 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL case 1546: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7661 +//line sql.y:7665 { yyVAL.str = string("") } case 1547: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7665 +//line sql.y:7669 { yyVAL.str = encodeSQLString(yyDollar[2].str) } case 1548: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*When -//line sql.y:7671 +//line sql.y:7675 { yyLOCAL = []*When{yyDollar[1].whenUnion()} } yyVAL.union = yyLOCAL case 1549: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7675 +//line sql.y:7679 { yySLICE := (*[]*When)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].whenUnion()) @@ -22743,7 +22747,7 @@ yydefault: case 1550: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *When -//line sql.y:7681 +//line sql.y:7685 { yyLOCAL = &When{Cond: yyDollar[2].exprUnion(), Val: yyDollar[4].exprUnion()} } @@ -22751,7 +22755,7 @@ yydefault: case 1551: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:7686 +//line sql.y:7690 { yyLOCAL = nil } @@ -22759,7 +22763,7 @@ yydefault: case 1552: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7690 +//line sql.y:7694 { yyLOCAL = yyDollar[2].exprUnion() } @@ -22767,7 +22771,7 @@ yydefault: case 1553: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ColName -//line sql.y:7696 +//line sql.y:7700 { yyLOCAL = &ColName{Name: yyDollar[1].identifierCI} } @@ -22775,7 +22779,7 @@ yydefault: case 1554: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ColName -//line sql.y:7700 +//line sql.y:7704 { yyLOCAL = &ColName{Name: NewIdentifierCI(string(yyDollar[1].str))} } @@ -22783,7 +22787,7 @@ yydefault: case 1555: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColName -//line sql.y:7704 +//line sql.y:7708 { yyLOCAL = &ColName{Qualifier: TableName{Name: yyDollar[1].identifierCS}, Name: yyDollar[3].identifierCI} } @@ -22791,7 +22795,7 @@ yydefault: case 1556: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ColName -//line sql.y:7708 +//line sql.y:7712 { yyLOCAL = &ColName{Qualifier: TableName{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCS}, Name: yyDollar[5].identifierCI} } @@ -22799,7 +22803,7 @@ yydefault: case 1557: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7714 +//line sql.y:7718 { yyLOCAL = yyDollar[1].colNameUnion() } @@ -22807,7 +22811,7 @@ yydefault: case 1558: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7718 +//line sql.y:7722 { yyLOCAL = &Offset{V: convertStringToInt(yyDollar[1].str)} } @@ -22815,7 +22819,7 @@ yydefault: case 1559: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7724 +//line sql.y:7728 { // TODO(sougou): Deprecate this construct. if yyDollar[1].identifierCI.Lowered() != "value" { @@ -22828,7 +22832,7 @@ yydefault: case 1560: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7733 +//line sql.y:7737 { yyLOCAL = NewIntLiteral(yyDollar[1].str) } @@ -22836,7 +22840,7 @@ yydefault: case 1561: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7737 +//line sql.y:7741 { yyLOCAL = parseBindVariable(yylex, yyDollar[1].str[1:]) } @@ -22844,7 +22848,7 @@ yydefault: case 1562: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *GroupBy -//line sql.y:7742 +//line sql.y:7746 { yyLOCAL = nil } @@ -22852,7 +22856,7 @@ yydefault: case 1563: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *GroupBy -//line sql.y:7746 +//line sql.y:7750 { yyLOCAL = &GroupBy{Exprs: yyDollar[3].exprsUnion(), WithRollup: yyDollar[4].booleanUnion()} } @@ -22860,7 +22864,7 @@ yydefault: case 1564: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7751 +//line sql.y:7755 { yyLOCAL = false } @@ -22868,7 +22872,7 @@ yydefault: case 1565: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:7755 +//line sql.y:7759 { yyLOCAL = true } @@ -22876,7 +22880,7 @@ yydefault: case 1566: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:7761 +//line sql.y:7765 { yyLOCAL = nil } @@ -22884,7 +22888,7 @@ yydefault: case 1567: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7765 +//line sql.y:7769 { yyLOCAL = yyDollar[2].exprUnion() } @@ -22892,7 +22896,7 @@ yydefault: case 1568: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *NamedWindow -//line sql.y:7771 +//line sql.y:7775 { yyLOCAL = &NamedWindow{yyDollar[2].windowDefinitionsUnion()} } @@ -22900,14 +22904,14 @@ yydefault: case 1569: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL NamedWindows -//line sql.y:7777 +//line sql.y:7781 { yyLOCAL = NamedWindows{yyDollar[1].namedWindowUnion()} } yyVAL.union = yyLOCAL case 1570: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7781 +//line sql.y:7785 { yySLICE := (*NamedWindows)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].namedWindowUnion()) @@ -22915,7 +22919,7 @@ yydefault: case 1571: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL NamedWindows -//line sql.y:7786 +//line sql.y:7790 { yyLOCAL = nil } @@ -22923,7 +22927,7 @@ yydefault: case 1572: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL NamedWindows -//line sql.y:7790 +//line sql.y:7794 { yyLOCAL = yyDollar[1].namedWindowsUnion() } @@ -22931,7 +22935,7 @@ yydefault: case 1573: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL OrderBy -//line sql.y:7795 +//line sql.y:7799 { yyLOCAL = nil } @@ -22939,7 +22943,7 @@ yydefault: case 1574: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderBy -//line sql.y:7799 +//line sql.y:7803 { yyLOCAL = yyDollar[1].orderByUnion() } @@ -22947,7 +22951,7 @@ yydefault: case 1575: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL OrderBy -//line sql.y:7805 +//line sql.y:7809 { yyLOCAL = yyDollar[3].orderByUnion() } @@ -22955,14 +22959,14 @@ yydefault: case 1576: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderBy -//line sql.y:7811 +//line sql.y:7815 { yyLOCAL = OrderBy{yyDollar[1].orderUnion()} } yyVAL.union = yyLOCAL case 1577: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7815 +//line sql.y:7819 { yySLICE := (*OrderBy)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].orderUnion()) @@ -22970,7 +22974,7 @@ yydefault: case 1578: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Order -//line sql.y:7821 +//line sql.y:7825 { yyLOCAL = &Order{Expr: yyDollar[1].exprUnion(), Direction: yyDollar[2].orderDirectionUnion()} } @@ -22978,7 +22982,7 @@ yydefault: case 1579: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL OrderDirection -//line sql.y:7826 +//line sql.y:7830 { yyLOCAL = AscOrder } @@ -22986,7 +22990,7 @@ yydefault: case 1580: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderDirection -//line sql.y:7830 +//line sql.y:7834 { yyLOCAL = AscOrder } @@ -22994,7 +22998,7 @@ yydefault: case 1581: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderDirection -//line sql.y:7834 +//line sql.y:7838 { yyLOCAL = DescOrder } @@ -23002,7 +23006,7 @@ yydefault: case 1582: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *Limit -//line sql.y:7839 +//line sql.y:7843 { yyLOCAL = nil } @@ -23010,7 +23014,7 @@ yydefault: case 1583: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Limit -//line sql.y:7843 +//line sql.y:7847 { yyLOCAL = yyDollar[1].limitUnion() } @@ -23018,7 +23022,7 @@ yydefault: case 1584: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Limit -//line sql.y:7849 +//line sql.y:7853 { yyLOCAL = &Limit{Rowcount: yyDollar[2].exprUnion()} } @@ -23026,7 +23030,7 @@ yydefault: case 1585: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Limit -//line sql.y:7853 +//line sql.y:7857 { yyLOCAL = &Limit{Offset: yyDollar[2].exprUnion(), Rowcount: yyDollar[4].exprUnion()} } @@ -23034,7 +23038,7 @@ yydefault: case 1586: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Limit -//line sql.y:7857 +//line sql.y:7861 { yyLOCAL = &Limit{Offset: yyDollar[4].exprUnion(), Rowcount: yyDollar[2].exprUnion()} } @@ -23042,7 +23046,7 @@ yydefault: case 1587: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7862 +//line sql.y:7866 { yyLOCAL = nil } @@ -23050,7 +23054,7 @@ yydefault: case 1588: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7866 +//line sql.y:7870 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion(), yyDollar[2].alterOptionUnion()} } @@ -23058,7 +23062,7 @@ yydefault: case 1589: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7870 +//line sql.y:7874 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion(), yyDollar[2].alterOptionUnion()} } @@ -23066,7 +23070,7 @@ yydefault: case 1590: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7874 +//line sql.y:7878 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} } @@ -23074,7 +23078,7 @@ yydefault: case 1591: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7878 +//line sql.y:7882 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} } @@ -23082,7 +23086,7 @@ yydefault: case 1592: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7885 +//line sql.y:7889 { yyLOCAL = &LockOption{Type: DefaultType} } @@ -23090,7 +23094,7 @@ yydefault: case 1593: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7889 +//line sql.y:7893 { yyLOCAL = &LockOption{Type: NoneType} } @@ -23098,7 +23102,7 @@ yydefault: case 1594: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7893 +//line sql.y:7897 { yyLOCAL = &LockOption{Type: SharedType} } @@ -23106,7 +23110,7 @@ yydefault: case 1595: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7897 +//line sql.y:7901 { yyLOCAL = &LockOption{Type: ExclusiveType} } @@ -23114,7 +23118,7 @@ yydefault: case 1596: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7903 +//line sql.y:7907 { yyLOCAL = AlgorithmValue(yyDollar[3].str) } @@ -23122,7 +23126,7 @@ yydefault: case 1597: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7907 +//line sql.y:7911 { yyLOCAL = AlgorithmValue(yyDollar[3].str) } @@ -23130,7 +23134,7 @@ yydefault: case 1598: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7911 +//line sql.y:7915 { yyLOCAL = AlgorithmValue(yyDollar[3].str) } @@ -23138,93 +23142,93 @@ yydefault: case 1599: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7915 +//line sql.y:7919 { yyLOCAL = AlgorithmValue(yyDollar[3].str) } yyVAL.union = yyLOCAL case 1600: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7920 +//line sql.y:7924 { yyVAL.str = "" } case 1602: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7927 +//line sql.y:7931 { yyVAL.str = string(yyDollar[3].str) } case 1603: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7931 +//line sql.y:7935 { yyVAL.str = string(yyDollar[3].str) } case 1604: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7935 +//line sql.y:7939 { yyVAL.str = string(yyDollar[3].str) } case 1605: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7940 +//line sql.y:7944 { yyVAL.str = "" } case 1606: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7944 +//line sql.y:7948 { yyVAL.str = yyDollar[3].str } case 1607: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7950 +//line sql.y:7954 { yyVAL.str = string(yyDollar[1].str) } case 1608: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7954 +//line sql.y:7958 { yyVAL.str = string(yyDollar[1].str) } case 1609: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7959 +//line sql.y:7963 { yyVAL.str = "" } case 1610: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:7963 +//line sql.y:7967 { yyVAL.str = yyDollar[2].str } case 1611: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7968 +//line sql.y:7972 { yyVAL.str = "cascaded" } case 1612: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7972 +//line sql.y:7976 { yyVAL.str = string(yyDollar[1].str) } case 1613: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7976 +//line sql.y:7980 { yyVAL.str = string(yyDollar[1].str) } case 1614: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*ProcParameter -//line sql.y:7981 +//line sql.y:7985 { yyLOCAL = nil } @@ -23232,7 +23236,7 @@ yydefault: case 1615: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*ProcParameter -//line sql.y:7985 +//line sql.y:7989 { yyLOCAL = yyDollar[1].procParamsUnion() } @@ -23240,14 +23244,14 @@ yydefault: case 1616: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*ProcParameter -//line sql.y:7991 +//line sql.y:7995 { yyLOCAL = []*ProcParameter{yyDollar[1].procParamUnion()} } yyVAL.union = yyLOCAL case 1617: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7995 +//line sql.y:7999 { yySLICE := (*[]*ProcParameter)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].procParamUnion()) @@ -23255,7 +23259,7 @@ yydefault: case 1618: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ProcParameter -//line sql.y:8001 +//line sql.y:8005 { yyLOCAL = &ProcParameter{Mode: yyDollar[1].procParamModeUnion(), Name: yyDollar[2].identifierCI, Type: yyDollar[3].columnType} } @@ -23263,7 +23267,7 @@ yydefault: case 1619: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL ProcParameterMode -//line sql.y:8006 +//line sql.y:8010 { yyLOCAL = InMode } @@ -23271,7 +23275,7 @@ yydefault: case 1620: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ProcParameterMode -//line sql.y:8010 +//line sql.y:8014 { yyLOCAL = InMode } @@ -23279,7 +23283,7 @@ yydefault: case 1621: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ProcParameterMode -//line sql.y:8014 +//line sql.y:8018 { yyLOCAL = InoutMode } @@ -23287,7 +23291,7 @@ yydefault: case 1622: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ProcParameterMode -//line sql.y:8018 +//line sql.y:8022 { yyLOCAL = OutMode } @@ -23295,7 +23299,7 @@ yydefault: case 1623: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *Definer -//line sql.y:8023 +//line sql.y:8027 { yyLOCAL = nil } @@ -23303,7 +23307,7 @@ yydefault: case 1625: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *Definer -//line sql.y:8030 +//line sql.y:8034 { yyLOCAL = yyDollar[3].definerUnion() } @@ -23311,7 +23315,7 @@ yydefault: case 1626: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Definer -//line sql.y:8036 +//line sql.y:8040 { yyLOCAL = &Definer{ Name: string(yyDollar[1].str), @@ -23321,7 +23325,7 @@ yydefault: case 1627: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *Definer -//line sql.y:8042 +//line sql.y:8046 { yyLOCAL = &Definer{ Name: string(yyDollar[1].str), @@ -23331,7 +23335,7 @@ yydefault: case 1628: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Definer -//line sql.y:8048 +//line sql.y:8052 { yyLOCAL = &Definer{ Name: yyDollar[1].str, @@ -23341,32 +23345,32 @@ yydefault: yyVAL.union = yyLOCAL case 1629: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8057 +//line sql.y:8061 { yyVAL.str = encodeSQLString(yyDollar[1].str) } case 1630: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8061 +//line sql.y:8065 { yyVAL.str = formatIdentifier(yyDollar[1].str) } case 1631: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8066 +//line sql.y:8070 { yyVAL.str = "" } case 1632: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8070 +//line sql.y:8074 { yyVAL.str = formatAddress(yyDollar[1].str) } case 1633: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Lock -//line sql.y:8076 +//line sql.y:8080 { yyLOCAL = ForUpdateLock } @@ -23374,7 +23378,7 @@ yydefault: case 1634: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Lock -//line sql.y:8080 +//line sql.y:8084 { yyLOCAL = ForUpdateLockNoWait } @@ -23382,7 +23386,7 @@ yydefault: case 1635: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Lock -//line sql.y:8084 +//line sql.y:8088 { yyLOCAL = ForUpdateLockSkipLocked } @@ -23390,7 +23394,7 @@ yydefault: case 1636: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Lock -//line sql.y:8088 +//line sql.y:8092 { yyLOCAL = ForShareLock } @@ -23398,7 +23402,7 @@ yydefault: case 1637: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Lock -//line sql.y:8092 +//line sql.y:8096 { yyLOCAL = ForShareLockNoWait } @@ -23406,7 +23410,7 @@ yydefault: case 1638: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Lock -//line sql.y:8096 +//line sql.y:8100 { yyLOCAL = ForShareLockSkipLocked } @@ -23414,7 +23418,7 @@ yydefault: case 1639: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Lock -//line sql.y:8100 +//line sql.y:8104 { yyLOCAL = ShareModeLock } @@ -23422,7 +23426,7 @@ yydefault: case 1640: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:8106 +//line sql.y:8110 { yyLOCAL = &SelectInto{Type: IntoOutfileS3, FileName: encodeSQLString(yyDollar[4].str), Charset: yyDollar[5].columnCharset, FormatOption: yyDollar[6].str, ExportOption: yyDollar[7].str, Manifest: yyDollar[8].str, Overwrite: yyDollar[9].str} } @@ -23430,7 +23434,7 @@ yydefault: case 1641: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:8110 +//line sql.y:8114 { yyLOCAL = &SelectInto{Type: IntoDumpfile, FileName: encodeSQLString(yyDollar[3].str), Charset: ColumnCharset{}, FormatOption: "", ExportOption: "", Manifest: "", Overwrite: ""} } @@ -23438,7 +23442,7 @@ yydefault: case 1642: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:8114 +//line sql.y:8118 { yyLOCAL = &SelectInto{Type: IntoOutfile, FileName: encodeSQLString(yyDollar[3].str), Charset: yyDollar[4].columnCharset, FormatOption: "", ExportOption: yyDollar[5].str, Manifest: "", Overwrite: ""} } @@ -23446,14 +23450,14 @@ yydefault: case 1643: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:8118 +//line sql.y:8122 { yyLOCAL = &SelectInto{Type: IntoVariables, VarList: yyDollar[2].variablesUnion()} } yyVAL.union = yyLOCAL case 1644: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:8124 +//line sql.y:8128 { yySLICE := (*[]*Variable)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].variableUnion()) @@ -23461,7 +23465,7 @@ yydefault: case 1645: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*Variable -//line sql.y:8128 +//line sql.y:8132 { yyLOCAL = []*Variable{yyDollar[1].variableUnion()} } @@ -23469,7 +23473,7 @@ yydefault: case 1646: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Variable -//line sql.y:8134 +//line sql.y:8138 { yyLOCAL = yyDollar[1].variableUnion() } @@ -23477,177 +23481,177 @@ yydefault: case 1647: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Variable -//line sql.y:8138 +//line sql.y:8142 { yyLOCAL = &Variable{Name: createIdentifierCI(yyDollar[1].str), Scope: NoScope} } yyVAL.union = yyLOCAL case 1648: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8143 +//line sql.y:8147 { yyVAL.str = "" } case 1649: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:8147 +//line sql.y:8151 { yyVAL.str = " format csv" + yyDollar[3].str } case 1650: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:8151 +//line sql.y:8155 { yyVAL.str = " format text" + yyDollar[3].str } case 1651: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8156 +//line sql.y:8160 { yyVAL.str = "" } case 1652: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8160 +//line sql.y:8164 { yyVAL.str = " header" } case 1653: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8165 +//line sql.y:8169 { yyVAL.str = "" } case 1654: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:8169 +//line sql.y:8173 { yyVAL.str = " manifest on" } case 1655: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:8173 +//line sql.y:8177 { yyVAL.str = " manifest off" } case 1656: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8178 +//line sql.y:8182 { yyVAL.str = "" } case 1657: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:8182 +//line sql.y:8186 { yyVAL.str = " overwrite on" } case 1658: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:8186 +//line sql.y:8190 { yyVAL.str = " overwrite off" } case 1659: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:8192 +//line sql.y:8196 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } case 1660: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8197 +//line sql.y:8201 { yyVAL.str = "" } case 1661: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:8201 +//line sql.y:8205 { yyVAL.str = " lines" + yyDollar[2].str } case 1662: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8207 +//line sql.y:8211 { yyVAL.str = yyDollar[1].str } case 1663: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:8211 +//line sql.y:8215 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } case 1664: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:8217 +//line sql.y:8221 { yyVAL.str = " starting by " + encodeSQLString(yyDollar[3].str) } case 1665: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:8221 +//line sql.y:8225 { yyVAL.str = " terminated by " + encodeSQLString(yyDollar[3].str) } case 1666: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8226 +//line sql.y:8230 { yyVAL.str = "" } case 1667: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:8230 +//line sql.y:8234 { yyVAL.str = " " + yyDollar[1].str + yyDollar[2].str } case 1668: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8236 +//line sql.y:8240 { yyVAL.str = yyDollar[1].str } case 1669: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:8240 +//line sql.y:8244 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } case 1670: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:8246 +//line sql.y:8250 { yyVAL.str = " terminated by " + encodeSQLString(yyDollar[3].str) } case 1671: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:8250 +//line sql.y:8254 { yyVAL.str = yyDollar[1].str + " enclosed by " + encodeSQLString(yyDollar[4].str) } case 1672: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:8254 +//line sql.y:8258 { yyVAL.str = " escaped by " + encodeSQLString(yyDollar[3].str) } case 1673: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8259 +//line sql.y:8263 { yyVAL.str = "" } case 1674: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8263 +//line sql.y:8267 { yyVAL.str = " optionally" } case 1675: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *Insert -//line sql.y:8276 +//line sql.y:8280 { yyLOCAL = &Insert{Rows: yyDollar[2].valuesUnion(), RowAlias: yyDollar[3].rowAliasUnion()} } @@ -23655,7 +23659,7 @@ yydefault: case 1676: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Insert -//line sql.y:8280 +//line sql.y:8284 { yyLOCAL = &Insert{Rows: yyDollar[1].tableStmtUnion()} } @@ -23663,7 +23667,7 @@ yydefault: case 1677: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *Insert -//line sql.y:8284 +//line sql.y:8288 { yyLOCAL = &Insert{Columns: yyDollar[2].columnsUnion(), Rows: yyDollar[5].valuesUnion(), RowAlias: yyDollar[6].rowAliasUnion()} } @@ -23671,7 +23675,7 @@ yydefault: case 1678: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *Insert -//line sql.y:8288 +//line sql.y:8292 { yyLOCAL = &Insert{Columns: []IdentifierCI{}, Rows: yyDollar[4].valuesUnion(), RowAlias: yyDollar[5].rowAliasUnion()} } @@ -23679,7 +23683,7 @@ yydefault: case 1679: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Insert -//line sql.y:8292 +//line sql.y:8296 { yyLOCAL = &Insert{Columns: yyDollar[2].columnsUnion(), Rows: yyDollar[4].tableStmtUnion()} } @@ -23687,7 +23691,7 @@ yydefault: case 1680: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:8298 +//line sql.y:8302 { yyLOCAL = Columns{yyDollar[1].identifierCI} } @@ -23695,21 +23699,21 @@ yydefault: case 1681: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Columns -//line sql.y:8302 +//line sql.y:8306 { yyLOCAL = Columns{yyDollar[3].identifierCI} } yyVAL.union = yyLOCAL case 1682: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:8306 +//line sql.y:8310 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) } case 1683: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:8310 +//line sql.y:8314 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[5].identifierCI) @@ -23717,7 +23721,7 @@ yydefault: case 1684: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *RowAlias -//line sql.y:8315 +//line sql.y:8319 { yyLOCAL = nil } @@ -23725,7 +23729,7 @@ yydefault: case 1685: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *RowAlias -//line sql.y:8319 +//line sql.y:8323 { yyLOCAL = &RowAlias{TableName: yyDollar[2].identifierCS} } @@ -23733,7 +23737,7 @@ yydefault: case 1686: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *RowAlias -//line sql.y:8323 +//line sql.y:8327 { yyLOCAL = &RowAlias{TableName: yyDollar[2].identifierCS, Columns: yyDollar[4].columnsUnion()} } @@ -23741,7 +23745,7 @@ yydefault: case 1687: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:8328 +//line sql.y:8332 { yyLOCAL = nil } @@ -23749,7 +23753,7 @@ yydefault: case 1688: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:8332 +//line sql.y:8336 { yyLOCAL = yyDollar[5].updateExprsUnion() } @@ -23757,14 +23761,14 @@ yydefault: case 1689: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Values -//line sql.y:8338 +//line sql.y:8342 { yyLOCAL = Values{yyDollar[1].valTupleUnion()} } yyVAL.union = yyLOCAL case 1690: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:8342 +//line sql.y:8346 { yySLICE := (*Values)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].valTupleUnion()) @@ -23772,14 +23776,14 @@ yydefault: case 1691: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Values -//line sql.y:8348 +//line sql.y:8352 { yyLOCAL = Values{yyDollar[1].valTupleUnion()} } yyVAL.union = yyLOCAL case 1692: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:8352 +//line sql.y:8356 { yySLICE := (*Values)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].valTupleUnion()) @@ -23787,7 +23791,7 @@ yydefault: case 1693: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ValTuple -//line sql.y:8358 +//line sql.y:8362 { yyLOCAL = yyDollar[1].valTupleUnion() } @@ -23795,7 +23799,7 @@ yydefault: case 1694: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ValTuple -//line sql.y:8362 +//line sql.y:8366 { yyLOCAL = ValTuple{} } @@ -23803,7 +23807,7 @@ yydefault: case 1695: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ValTuple -//line sql.y:8368 +//line sql.y:8372 { yyLOCAL = yyDollar[1].valTupleUnion() } @@ -23811,7 +23815,7 @@ yydefault: case 1696: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL ValTuple -//line sql.y:8372 +//line sql.y:8376 { yyLOCAL = ValTuple{} } @@ -23819,7 +23823,7 @@ yydefault: case 1697: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ValTuple -//line sql.y:8378 +//line sql.y:8382 { yyLOCAL = ValTuple(yyDollar[2].exprsUnion()) } @@ -23827,7 +23831,7 @@ yydefault: case 1698: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL ValTuple -//line sql.y:8384 +//line sql.y:8388 { yyLOCAL = ValTuple(yyDollar[3].exprsUnion()) } @@ -23835,7 +23839,7 @@ yydefault: case 1701: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:8394 +//line sql.y:8398 { if len(yyDollar[1].valTupleUnion()) == 1 { yyLOCAL = yyDollar[1].valTupleUnion()[0] @@ -23847,14 +23851,14 @@ yydefault: case 1702: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:8404 +//line sql.y:8408 { yyLOCAL = UpdateExprs{yyDollar[1].updateExprUnion()} } yyVAL.union = yyLOCAL case 1703: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:8408 +//line sql.y:8412 { yySLICE := (*UpdateExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].updateExprUnion()) @@ -23862,21 +23866,21 @@ yydefault: case 1704: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *UpdateExpr -//line sql.y:8414 +//line sql.y:8418 { yyLOCAL = &UpdateExpr{Name: yyDollar[1].colNameUnion(), Expr: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 1706: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:8421 +//line sql.y:8425 { yyVAL.str = "charset" } case 1709: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:8431 +//line sql.y:8435 { yyLOCAL = NewStrLiteral(yyDollar[1].identifierCI.String()) } @@ -23884,7 +23888,7 @@ yydefault: case 1710: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:8435 +//line sql.y:8439 { yyLOCAL = NewStrLiteral(yyDollar[1].str) } @@ -23892,7 +23896,7 @@ yydefault: case 1711: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:8439 +//line sql.y:8443 { yyLOCAL = &Default{} } @@ -23900,7 +23904,7 @@ yydefault: case 1714: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:8448 +//line sql.y:8452 { yyLOCAL = false } @@ -23908,7 +23912,7 @@ yydefault: case 1715: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:8450 +//line sql.y:8454 { yyLOCAL = true } @@ -23916,7 +23920,7 @@ yydefault: case 1716: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:8453 +//line sql.y:8457 { yyLOCAL = false } @@ -23924,7 +23928,7 @@ yydefault: case 1717: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:8455 +//line sql.y:8459 { yyLOCAL = true } @@ -23932,7 +23936,7 @@ yydefault: case 1718: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:8458 +//line sql.y:8462 { yyLOCAL = false } @@ -23940,7 +23944,7 @@ yydefault: case 1719: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL bool -//line sql.y:8460 +//line sql.y:8464 { yyLOCAL = true } @@ -23948,7 +23952,7 @@ yydefault: case 1720: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Ignore -//line sql.y:8463 +//line sql.y:8467 { yyLOCAL = false } @@ -23956,33 +23960,33 @@ yydefault: case 1721: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Ignore -//line sql.y:8465 +//line sql.y:8469 { yyLOCAL = true } yyVAL.union = yyLOCAL case 1722: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8468 +//line sql.y:8472 { yyVAL.empty = struct{}{} } case 1723: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8470 +//line sql.y:8474 { yyVAL.empty = struct{}{} } case 1724: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8472 +//line sql.y:8476 { yyVAL.empty = struct{}{} } case 1725: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:8476 +//line sql.y:8480 { yyLOCAL = &CallProc{Name: yyDollar[2].tableName, Params: yyDollar[4].exprsUnion()} } @@ -23990,7 +23994,7 @@ yydefault: case 1726: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []Expr -//line sql.y:8481 +//line sql.y:8485 { yyLOCAL = nil } @@ -23998,7 +24002,7 @@ yydefault: case 1727: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []Expr -//line sql.y:8485 +//line sql.y:8489 { yyLOCAL = yyDollar[1].exprsUnion() } @@ -24006,7 +24010,7 @@ yydefault: case 1728: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:8490 +//line sql.y:8494 { yyLOCAL = nil } @@ -24014,7 +24018,7 @@ yydefault: case 1729: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:8492 +//line sql.y:8496 { yyLOCAL = []*IndexOption{yyDollar[1].indexOptionUnion()} } @@ -24022,63 +24026,63 @@ yydefault: case 1730: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:8496 +//line sql.y:8500 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str), String: string(yyDollar[2].identifierCI.String())} } yyVAL.union = yyLOCAL case 1731: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8502 +//line sql.y:8506 { yyVAL.identifierCI = yyDollar[1].identifierCI } case 1732: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8506 +//line sql.y:8510 { yyVAL.identifierCI = NewIdentifierCI(string(yyDollar[1].str)) } case 1734: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8513 +//line sql.y:8517 { yyVAL.identifierCI = NewIdentifierCI(string(yyDollar[1].str)) } case 1735: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8519 +//line sql.y:8523 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } case 1736: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8523 +//line sql.y:8527 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } case 1737: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8529 +//line sql.y:8533 { yyVAL.identifierCS = NewIdentifierCS("") } case 1738: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8533 +//line sql.y:8537 { yyVAL.identifierCS = yyDollar[1].identifierCS } case 1740: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8540 +//line sql.y:8544 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } case 1741: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:8546 +//line sql.y:8550 { yyLOCAL = &Kill{Type: yyDollar[2].killTypeUnion(), ProcesslistID: convertStringToUInt64(yyDollar[3].str)} } @@ -24086,7 +24090,7 @@ yydefault: case 1742: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL KillType -//line sql.y:8552 +//line sql.y:8556 { yyLOCAL = ConnectionType } @@ -24094,7 +24098,7 @@ yydefault: case 1743: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL KillType -//line sql.y:8556 +//line sql.y:8560 { yyLOCAL = ConnectionType } @@ -24102,42 +24106,42 @@ yydefault: case 1744: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL KillType -//line sql.y:8560 +//line sql.y:8564 { yyLOCAL = QueryType } yyVAL.union = yyLOCAL case 2411: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:9255 +//line sql.y:9259 { } case 2412: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:9260 +//line sql.y:9264 { } case 2413: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:9264 +//line sql.y:9268 { skipToEnd(yylex) } case 2414: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:9269 +//line sql.y:9273 { skipToEnd(yylex) } case 2415: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:9273 +//line sql.y:9277 { skipToEnd(yylex) } case 2416: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:9277 +//line sql.y:9281 { skipToEnd(yylex) } diff --git a/go/vt/sqlparser/sql.y b/go/vt/sqlparser/sql.y index a8ed0716422..39d8b1b760d 100644 --- a/go/vt/sqlparser/sql.y +++ b/go/vt/sqlparser/sql.y @@ -5294,6 +5294,10 @@ select_expression_list: } | select_expression_list ',' select_expression { + if starExpr, ok := $3.(*StarExpr); ok && starExpr.TableName.IsEmpty() { + yylex.Error("syntax error: unexpected '*'") + return 1 + } res := $1 res.Exprs = append(res.Exprs, $3) $$ = res diff --git a/go/vt/vtgate/planbuilder/testdata/dml_cases.json b/go/vt/vtgate/planbuilder/testdata/dml_cases.json index 370d24af4f3..d6d4b563cfe 100644 --- a/go/vt/vtgate/planbuilder/testdata/dml_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/dml_cases.json @@ -4038,7 +4038,7 @@ { "comment": "insert using select with more columns in select after accounting for star column", "query": "insert into music(id, user_id) select id, *, 2 from user", - "plan": "VT03006: column count does not match value count with the row", + "plan": "syntax error: unexpected '*' at position 44", "skip_e2e": true }, { diff --git a/go/vt/vtgate/planbuilder/testdata/unknown_schema_cases.json b/go/vt/vtgate/planbuilder/testdata/unknown_schema_cases.json index df4459d9e0f..8647220afd8 100644 --- a/go/vt/vtgate/planbuilder/testdata/unknown_schema_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/unknown_schema_cases.json @@ -47,7 +47,7 @@ { "comment": "ORDER BY on select multi *", "query": "select *, name, *, col from user order by col", - "plan": "VT09015: schema tracking required" + "plan": "syntax error: unexpected '*' at position 18" }, { "comment": "Group by column number, used with non-aliased expression (duplicated code)", diff --git a/go/vt/vtgate/semantics/early_rewriter_test.go b/go/vt/vtgate/semantics/early_rewriter_test.go index 074deb39f64..3b00ce77e82 100644 --- a/go/vt/vtgate/semantics/early_rewriter_test.go +++ b/go/vt/vtgate/semantics/early_rewriter_test.go @@ -769,10 +769,6 @@ func TestSemTableDependenciesAfterExpandStar(t *testing.T) { otherTbl int expandedCol int }{{ - sql: "select a, * from t1", - expSQL: "select a, a from t1", - otherTbl: -1, sameTbl: 0, expandedCol: 1, - }, { sql: "select t2.a, t1.a, t1.* from t1, t2", expSQL: "select t2.a, t1.a, t1.a from t1, t2", otherTbl: 0, sameTbl: 1, expandedCol: 2, diff --git a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go index 09ace916f11..320d7311f76 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go @@ -640,7 +640,7 @@ func TestBuildPlayerPlan(t *testing.T) { Filter: "select c1, * from t1", }}, }, - err: "failed to build table replication plan for t1 table: invalid expression: * in query: select c1, * from t1", + err: "failed to build table replication plan for t1 table: syntax error: unexpected '*' at position 13 in query: select c1, * from t1", }, { // no distinct in func input: &binlogdatapb.Filter{ diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go index 8f4cac52408..dd260567e7a 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go @@ -730,7 +730,7 @@ func TestPlanBuilder(t *testing.T) { // analyzeExpr tests. inTable: t1, inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select id, * from t1"}, - outErr: `unsupported: *`, + outErr: `syntax error: unexpected '*' at position 13`, }, { inTable: t1, inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select none from t1"}, From c6d1d99c0d4946891bbb500d940e2308f87ec64a Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 16:46:53 -0800 Subject: [PATCH 086/112] [release-22.0] Fix `DROP CONSTRAINT` to work the same way as MySQL (#19183) (#19240) Signed-off-by: Nick Van Wiggeren Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Nick Van Wiggeren --- go/vt/schemadiff/onlineddl.go | 2 +- go/vt/schemadiff/onlineddl_test.go | 7 ++++++ go/vt/schemadiff/schema.go | 39 +++++++++++++++++++++--------- go/vt/schemadiff/table.go | 24 +++++++++++++----- go/vt/schemadiff/table_test.go | 18 ++++++++++++++ go/vt/sqlparser/ast_funcs.go | 2 ++ go/vt/sqlparser/constants.go | 2 ++ go/vt/sqlparser/parse_test.go | 2 +- go/vt/sqlparser/sql.go | 2 +- go/vt/sqlparser/sql.y | 2 +- 10 files changed, 78 insertions(+), 22 deletions(-) diff --git a/go/vt/schemadiff/onlineddl.go b/go/vt/schemadiff/onlineddl.go index 06f3384c8fd..4ae66dad401 100644 --- a/go/vt/schemadiff/onlineddl.go +++ b/go/vt/schemadiff/onlineddl.go @@ -671,7 +671,7 @@ func ValidateAndEditAlterTableStatement(originalTableName string, baseUUID strin validateWalk := func(node sqlparser.SQLNode) (kontinue bool, err error) { switch node := node.(type) { case *sqlparser.DropKey: - if node.Type == sqlparser.CheckKeyType || node.Type == sqlparser.ForeignKeyType { + if node.Type == sqlparser.CheckKeyType || node.Type == sqlparser.ForeignKeyType || node.Type == sqlparser.ConstraintType { // drop a check or a foreign key constraint mappedName, ok := constraintMap[node.Name.String()] if !ok { diff --git a/go/vt/schemadiff/onlineddl_test.go b/go/vt/schemadiff/onlineddl_test.go index fb8710f8498..a7e7f4494e8 100644 --- a/go/vt/schemadiff/onlineddl_test.go +++ b/go/vt/schemadiff/onlineddl_test.go @@ -1217,6 +1217,13 @@ func TestValidateAndEditAlterTableStatement(t *testing.T) { }, expect: []string{"alter table t drop foreign key ibfk_1_aaaaaaaaaaaaaa"}, }, + { + alter: "alter table t drop constraint t_ibfk_1", + m: map[string]string{ + "t_ibfk_1": "ibfk_1_aaaaaaaaaaaaaa", + }, + expect: []string{"alter table t drop constraint ibfk_1_aaaaaaaaaaaaaa"}, + }, } env := NewTestEnv() diff --git a/go/vt/schemadiff/schema.go b/go/vt/schemadiff/schema.go index 5b578834089..afa537fe7c0 100644 --- a/go/vt/schemadiff/schema.go +++ b/go/vt/schemadiff/schema.go @@ -133,6 +133,21 @@ func getForeignKeyParentTableNames(createTable *sqlparser.CreateTable) (names [] return names } +func findForeignKeyDefinition(createTable *sqlparser.CreateTable, constraintName string) *sqlparser.ForeignKeyDefinition { + if createTable == nil || createTable.TableSpec == nil { + return nil + } + for _, cs := range createTable.TableSpec.Constraints { + if strings.EqualFold(cs.Name.String(), constraintName) { + if fk, ok := cs.Details.(*sqlparser.ForeignKeyDefinition); ok { + return fk + } + return nil + } + } + return nil +} + // getViewDependentTableNames analyzes a CREATE VIEW definition and extracts all tables/views read by this view func getViewDependentTableNames(createView *sqlparser.CreateView) (names []string) { _ = sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) { @@ -1006,21 +1021,21 @@ func (s *Schema) SchemaDiff(other *Schema, hints *DiffHints) (*SchemaDiff, error } return checkChildForeignKeyDefinition(fk, diff) case *sqlparser.DropKey: - if node.Type != sqlparser.ForeignKeyType { + switch node.Type { + case sqlparser.ForeignKeyType, sqlparser.ConstraintType: + // Possibly dropping a foreign key; we need to check if this constraint references another table. + // The DropKey statement itself only _names_ the constraint, but does not have information + // about the parent, columns, etc. So we need to find the constraint in the CreateTable statement. + fk := findForeignKeyDefinition(diff.from.CreateTable, node.Name.String()) + if fk == nil { + return true, nil + } + parentTableName := fk.ReferenceDefinition.ReferencedTable.Name.String() + checkDependencies(diff, []string{parentTableName}) + default: // Not interesting return true, nil } - // Dropping a foreign key; we need to understand which table this foreign key used to reference. - // The DropKey statement itself only _names_ the constraint, but does not have information - // about the parent, columns, etc. So we need to find the constraint in the CreateTable statement. - for _, cs := range diff.from.CreateTable.TableSpec.Constraints { - if strings.EqualFold(cs.Name.String(), node.Name.String()) { - if check, ok := cs.Details.(*sqlparser.ForeignKeyDefinition); ok { - parentTableName := check.ReferenceDefinition.ReferencedTable.Name.String() - checkDependencies(diff, []string{parentTableName}) - } - } - } } return true, nil diff --git a/go/vt/schemadiff/table.go b/go/vt/schemadiff/table.go index eb118555371..5e53178e221 100644 --- a/go/vt/schemadiff/table.go +++ b/go/vt/schemadiff/table.go @@ -2107,7 +2107,7 @@ func sortAlterOptions(diff *AlterTableEntityDiff) { optionOrder := func(opt sqlparser.AlterOption) int { switch opt := opt.(type) { case *sqlparser.DropKey: - if opt.Type == sqlparser.ForeignKeyType { + if opt.Type == sqlparser.ForeignKeyType || opt.Type == sqlparser.ConstraintType { return 1 } return 2 @@ -2267,13 +2267,25 @@ func (c *CreateTableEntity) apply(diff *AlterTableEntityDiff) error { break } } - case sqlparser.ForeignKeyType, sqlparser.CheckKeyType: + case sqlparser.ForeignKeyType, sqlparser.CheckKeyType, sqlparser.ConstraintType: for i, constraint := range c.TableSpec.Constraints { - if strings.EqualFold(constraint.Name.String(), opt.Name.String()) { - found = true - c.TableSpec.Constraints = append(c.TableSpec.Constraints[0:i], c.TableSpec.Constraints[i+1:]...) - break + if !strings.EqualFold(constraint.Name.String(), opt.Name.String()) { + continue + } + switch opt.Type { + case sqlparser.ForeignKeyType: + if _, ok := constraint.Details.(*sqlparser.ForeignKeyDefinition); !ok { + continue + } + case sqlparser.CheckKeyType: + if _, ok := constraint.Details.(*sqlparser.CheckConstraintDefinition); !ok { + continue + } + case sqlparser.ConstraintType: } + found = true + c.TableSpec.Constraints = append(c.TableSpec.Constraints[0:i], c.TableSpec.Constraints[i+1:]...) + break } default: return &UnsupportedApplyOperationError{Statement: sqlparser.CanonicalString(opt)} diff --git a/go/vt/schemadiff/table_test.go b/go/vt/schemadiff/table_test.go index ca907b58ac6..46925fb2068 100644 --- a/go/vt/schemadiff/table_test.go +++ b/go/vt/schemadiff/table_test.go @@ -2954,6 +2954,18 @@ func TestValidate(t *testing.T) { alter: "alter table t drop column e", to: "create table t (id int, dateT datetime, primary key (id), constraint unix_epoch check (dateT < '1970-01-01'))", }, + { + name: "drop check for foreign key constraint", + from: "create table t (id int primary key, i int, constraint f foreign key (i) references parent(id))", + alter: "alter table t drop check f", + expectErr: &ApplyKeyNotFoundError{Table: "t", Key: "f"}, + }, + { + name: "drop foreign key for check constraint", + from: "create table t (id int primary key, i int, constraint chk check (i > 0))", + alter: "alter table t drop foreign key chk", + expectErr: &ApplyKeyNotFoundError{Table: "t", Key: "chk"}, + }, // Foreign keys { name: "existing foreign key, no such column", @@ -3045,6 +3057,12 @@ func TestValidate(t *testing.T) { alter: "alter table t drop key `i`", to: "create table t (id int primary key, i int, key i2 (i), constraint f foreign key (i) references parent(id))", }, + { + name: "drop constraint foreign key", + from: "create table t (id int primary key, i int, key i_idx (i), constraint f foreign key (i) references parent(id))", + alter: "alter table t drop constraint f", + to: "create table t (id int primary key, i int, key i_idx (i))", + }, } hints := DiffHints{} env := NewTestEnv() diff --git a/go/vt/sqlparser/ast_funcs.go b/go/vt/sqlparser/ast_funcs.go index 90d73df9691..1a33b8728ff 100644 --- a/go/vt/sqlparser/ast_funcs.go +++ b/go/vt/sqlparser/ast_funcs.go @@ -2316,6 +2316,8 @@ func (key DropKeyType) ToString() string { return NormalKeyTypeStr case CheckKeyType: return CheckKeyTypeStr + case ConstraintType: + return ConstraintTypeStr default: return "Unknown DropKeyType" } diff --git a/go/vt/sqlparser/constants.go b/go/vt/sqlparser/constants.go index f1b614a12cf..37a8676ee50 100644 --- a/go/vt/sqlparser/constants.go +++ b/go/vt/sqlparser/constants.go @@ -353,6 +353,7 @@ const ( ForeignKeyTypeStr = "foreign key" NormalKeyTypeStr = "key" CheckKeyTypeStr = "check" + ConstraintTypeStr = "constraint" // TrimType strings BothTrimStr = "both" @@ -943,6 +944,7 @@ const ( ForeignKeyType NormalKeyType CheckKeyType + ConstraintType ) // LockOptionType constants diff --git a/go/vt/sqlparser/parse_test.go b/go/vt/sqlparser/parse_test.go index 0ad5202a34a..70bf24e140e 100644 --- a/go/vt/sqlparser/parse_test.go +++ b/go/vt/sqlparser/parse_test.go @@ -1735,7 +1735,7 @@ var ( input: "alter table a drop check ch_1", }, { input: "alter table a drop constraint ch_1", - output: "alter table a drop check ch_1", + output: "alter table a drop constraint ch_1", }, { input: "alter table a drop foreign key kx", }, { diff --git a/go/vt/sqlparser/sql.go b/go/vt/sqlparser/sql.go index af1b78a4cef..dcea38cb51e 100644 --- a/go/vt/sqlparser/sql.go +++ b/go/vt/sqlparser/sql.go @@ -15510,7 +15510,7 @@ yydefault: var yyLOCAL AlterOption //line sql.y:3477 { - yyLOCAL = &DropKey{Type: CheckKeyType, Name: yyDollar[3].identifierCI} + yyLOCAL = &DropKey{Type: ConstraintType, Name: yyDollar[3].identifierCI} } yyVAL.union = yyLOCAL case 630: diff --git a/go/vt/sqlparser/sql.y b/go/vt/sqlparser/sql.y index 39d8b1b760d..b16c82152da 100644 --- a/go/vt/sqlparser/sql.y +++ b/go/vt/sqlparser/sql.y @@ -3475,7 +3475,7 @@ alter_option: } | DROP CONSTRAINT sql_id { - $$ = &DropKey{Type:CheckKeyType, Name:$3} + $$ = &DropKey{Type:ConstraintType, Name:$3} } | FORCE { From afde3ab83fc98ee53406c44f2e8e1a88531a1489 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 12:50:29 +0100 Subject: [PATCH 087/112] [release-22.0] CI: Address our two flakiest tests (#19587) (#19594) Signed-off-by: Matt Lord Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Matt Lord --- .../vttablet/tabletmanager/framework_test.go | 14 +++++--- .../tabletmanager/rpc_vreplication_test.go | 2 +- .../vreplication/framework_test.go | 9 +++++ .../vreplication/vplayer_flaky_test.go | 35 ++++++++++++++----- 4 files changed, 46 insertions(+), 14 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/framework_test.go b/go/vt/vttablet/tabletmanager/framework_test.go index 8e03f73bf79..70bfa3c50af 100644 --- a/go/vt/vttablet/tabletmanager/framework_test.go +++ b/go/vt/vttablet/tabletmanager/framework_test.go @@ -23,6 +23,7 @@ import ( "strconv" "strings" "sync" + "sync/atomic" "testing" "github.com/stretchr/testify/require" @@ -59,6 +60,8 @@ const ( gtidPosition = "16b1039f-22b6-11ed-b765-0a43f95f28a3:1-220" ) +var testEnvCounter atomic.Int64 + func init() { tabletconn.RegisterDialer("grpc", func(ctx context.Context, tablet *topodatapb.Tablet, failFast grpcclient.FailFast) (queryservice.QueryService, error) { return &tabletconntest.FakeQueryService{ @@ -90,12 +93,13 @@ type testEnv struct { func newTestEnv(t *testing.T, ctx context.Context, sourceKeyspace string, sourceShards []string) *testEnv { vttablet.InitVReplicationConfigDefaults() + protoName := fmt.Sprintf("%s_%d", t.Name(), testEnvCounter.Add(1)) tenv := &testEnv{ ctx: context.Background(), tmc: newFakeTMClient(), cells: []string{"zone1"}, dbName: "tmtestdb", - protoName: t.Name(), + protoName: protoName, } tenv.mu.Lock() defer tenv.mu.Unlock() @@ -104,7 +108,7 @@ func newTestEnv(t *testing.T, ctx context.Context, sourceKeyspace string, source tenv.tmc.sourceShards = sourceShards tenv.tmc.schema = defaultSchema - tabletconn.RegisterDialer(t.Name(), func(ctx context.Context, tablet *topodatapb.Tablet, failFast grpcclient.FailFast) (queryservice.QueryService, error) { + tabletconn.RegisterDialer(protoName, func(ctx context.Context, tablet *topodatapb.Tablet, failFast grpcclient.FailFast) (queryservice.QueryService, error) { tenv.mu.Lock() defer tenv.mu.Unlock() if qs, ok := tenv.tmc.tablets[int(tablet.Alias.Uid)]; ok { @@ -112,11 +116,11 @@ func newTestEnv(t *testing.T, ctx context.Context, sourceKeyspace string, source } return nil, fmt.Errorf("tablet %d not found", tablet.Alias.Uid) }) - tabletconntest.SetProtocol(fmt.Sprintf("go.vt.vttablet.tabletmanager.framework_test_%s", t.Name()), tenv.protoName) - tmclient.RegisterTabletManagerClientFactory(t.Name(), func() tmclient.TabletManagerClient { + tabletconntest.SetProtocol("go.vt.vttablet.tabletmanager.framework_test_"+protoName, protoName) + tmclient.RegisterTabletManagerClientFactory(protoName, func() tmclient.TabletManagerClient { return tenv.tmc }) - tmclienttest.SetProtocol(fmt.Sprintf("go.vt.vttablet.tabletmanager.framework_test_%s", t.Name()), tenv.protoName) + tmclienttest.SetProtocol("go.vt.vttablet.tabletmanager.framework_test_"+protoName, protoName) tenv.db = fakesqldb.New(t) tenv.mysqld = mysqlctl.NewFakeMysqlDaemon(tenv.db) diff --git a/go/vt/vttablet/tabletmanager/rpc_vreplication_test.go b/go/vt/vttablet/tabletmanager/rpc_vreplication_test.go index 16e805055a7..bc33ea29eb7 100644 --- a/go/vt/vttablet/tabletmanager/rpc_vreplication_test.go +++ b/go/vt/vttablet/tabletmanager/rpc_vreplication_test.go @@ -1848,7 +1848,7 @@ func addInvariants(dbClient *binlogplayer.MockDBClient, vreplID, sourceTabletUID "0", )) dbClient.AddInvariant(fmt.Sprintf(updatePickedSourceTablet, cell, sourceTabletUID, vreplID), &sqltypes.Result{}) - dbClient.AddInvariant("update _vt.vreplication set state='Running', message='' where id=1", &sqltypes.Result{}) + dbClient.AddInvariant("update _vt.vreplication set state='Running', message=left('', 1000) where id=1", &sqltypes.Result{}) dbClient.AddInvariant(vreplication.SqlMaxAllowedPacket, sqltypes.MakeTestResult( sqltypes.MakeTestFields( "max_allowed_packet", diff --git a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go index 9f2647a8770..2a17768b2ad 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go @@ -71,6 +71,7 @@ var ( vrepldb = "vrepl" globalDBQueries = make(chan string, 1000) lastMultiExecQuery = "" + lastMultiExecQueryMu sync.Mutex testForeignKeyQueries = false testSetForeignKeyQueries = false doNotLogDBQueries = false @@ -521,10 +522,18 @@ func (dbc *realDBClient) ExecuteFetchMulti(query string, maxrows int) ([]*sqltyp } results = append(results, qr) } + lastMultiExecQueryMu.Lock() lastMultiExecQuery = query + lastMultiExecQueryMu.Unlock() return results, nil } +func getLastMultiExecQuery() string { + lastMultiExecQueryMu.Lock() + defer lastMultiExecQueryMu.Unlock() + return lastMultiExecQuery +} + func (dbc *realDBClient) SupportsCapability(capability capabilities.FlavorCapability) (bool, error) { return dbc.conn.SupportsCapability(capability) } diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go index 57c3db6691c..7eb892c4151 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go @@ -3634,7 +3634,6 @@ func TestPlayerBatchMode(t *testing.T) { require.LessOrEqual(t, len(stmt), maxBatchSize, "expected output statement is longer than the max batch size (%d): %s", maxBatchSize, stmt) } expectNontxQueries(t, output, recvTimeout) - time.Sleep(1 * time.Second) if tcase.table != "" { expectData(t, tcase.table, tcase.data) } @@ -3646,15 +3645,35 @@ func TestPlayerBatchMode(t *testing.T) { expectedBulkInserts += tcase.expectedBulkInserts expectedTrxBatchCommits++ // Should only ever be 1 per test case expectedTrxBatchExecs += tcase.expectedNonCommitBatches - if tcase.expectedInLastBatch != "" { // We expect the trx to be split - require.Regexpf(t, regexp.MustCompile(fmt.Sprintf(trxLastBatchExpectRE, regexp.QuoteMeta(tcase.expectedInLastBatch))), lastMultiExecQuery, "Unexpected batch statement: %s", lastMultiExecQuery) + + // Poll until the batch query and stats counters are updated. + // These are set asynchronously on the vplayer goroutine after + // the commit completes, so we poll rather than using a fixed sleep. + var batchRE *regexp.Regexp + if tcase.expectedInLastBatch != "" { + batchRE = regexp.MustCompile(fmt.Sprintf(trxLastBatchExpectRE, regexp.QuoteMeta(tcase.expectedInLastBatch))) } else { - require.Regexpf(t, regexp.MustCompile(fmt.Sprintf(trxFullBatchExpectRE, regexp.QuoteMeta(strings.Join(tcase.output, ";")))), lastMultiExecQuery, "Unexpected batch statement: %s", lastMultiExecQuery) + batchRE = regexp.MustCompile(fmt.Sprintf(trxFullBatchExpectRE, regexp.QuoteMeta(strings.Join(tcase.output, ";")))) } - require.Equal(t, expectedBulkInserts, stats.BulkQueryCount.Counts()["insert"], "expected %d bulk inserts but got %d", expectedBulkInserts, stats.BulkQueryCount.Counts()["insert"]) - require.Equal(t, expectedBulkDeletes, stats.BulkQueryCount.Counts()["delete"], "expected %d bulk deletes but got %d", expectedBulkDeletes, stats.BulkQueryCount.Counts()["delete"]) - require.Equal(t, expectedTrxBatchExecs, stats.TrxQueryBatchCount.Counts()["without_commit"], "expected %d trx batch execs but got %d", expectedTrxBatchExecs, stats.TrxQueryBatchCount.Counts()["without_commit"]) - require.Equal(t, expectedTrxBatchCommits, stats.TrxQueryBatchCount.Counts()["with_commit"], "expected %d trx batch commits but got %d", expectedTrxBatchCommits, stats.TrxQueryBatchCount.Counts()["with_commit"]) + require.Eventually(t, func() bool { + got := getLastMultiExecQuery() + if !batchRE.MatchString(got) { + return false + } + if stats.BulkQueryCount.Counts()["insert"] != expectedBulkInserts { + return false + } + if stats.BulkQueryCount.Counts()["delete"] != expectedBulkDeletes { + return false + } + if stats.TrxQueryBatchCount.Counts()["without_commit"] != expectedTrxBatchExecs { + return false + } + if stats.TrxQueryBatchCount.Counts()["with_commit"] != expectedTrxBatchCommits { + return false + } + return true + }, 10*time.Second, 100*time.Millisecond, "batch query or stats mismatch after timeout; lastMultiExecQuery: %s", getLastMultiExecQuery()) }) } } From 9dfea4614f13af4c8c0b5fc635666ab0beb91bb8 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 12:51:10 +0100 Subject: [PATCH 088/112] [release-22.0] `ci`: run code coverage CI only on go packages that had changes (#19431) (#19590) Signed-off-by: Tim Vaillancourt Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Tim Vaillancourt Co-authored-by: Claude Sonnet 4.6 --- .github/workflows/codecov.yml | 100 +++++++++++++++++++++++++--------- .gitignore | 2 + Makefile | 8 +-- tools/run_codecov.sh | 18 ++++++ 4 files changed, 94 insertions(+), 34 deletions(-) create mode 100755 tools/run_codecov.sh diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 69bfef8ce77..c31570d461f 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -1,5 +1,7 @@ name: Code Coverage on: + schedule: + - cron: '0 0 * * 6' # Saturday midnight UTC push: branches: - "main" @@ -8,7 +10,7 @@ on: pull_request: branches: '**' concurrency: - group: format('{0}-{1}', ${{ github.ref }}, 'Code Coverage') + group: format('{0}-{1}-{2}', ${{ github.ref }}, ${{ github.event_name }}, 'Code Coverage') cancel-in-progress: true permissions: read-all @@ -22,10 +24,21 @@ jobs: - name: Check out code uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: + fetch-depth: 0 persist-credentials: 'false' + - name: Determine run mode + id: mode + run: | + if [ "${{ github.event_name }}" = "schedule" ]; then + echo "is_full_run=true" >> "$GITHUB_OUTPUT" + else + echo "is_full_run=false" >> "$GITHUB_OUTPUT" + fi + - name: Check for changes in files relevant to code coverage - uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1 + if: steps.mode.outputs.is_full_run != 'true' + uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 id: changes with: token: '' @@ -38,27 +51,63 @@ jobs: - Makefile - name: Set up Go - if: steps.changes.outputs.changed_files == 'true' - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + if: steps.mode.outputs.is_full_run == 'true' || steps.changes.outputs.changed_files == 'true' + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: go-version-file: go.mod + - name: Detect changed Go packages + if: steps.mode.outputs.is_full_run != 'true' && steps.changes.outputs.changed_files == 'true' + id: packages + run: | + BASE_SHA="${{ github.event.pull_request.base.sha }}" + HEAD_SHA="${{ github.event.pull_request.head.sha }}" + CHANGED_GO_FILES=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA" -- '*.go') + + if [ -z "$CHANGED_GO_FILES" ]; then + echo "BASE_SHA=$BASE_SHA" + echo "HEAD_SHA=$HEAD_SHA" + echo "packages=$PACKAGES" + + echo "packages=" >> "$GITHUB_OUTPUT" + exit 0 + fi + + PACKAGE_DIRS=$(echo "$CHANGED_GO_FILES" | xargs -n1 dirname | sort -u) + + # Validate as Go packages and exclude endtoend tests + PACKAGES="" + for dir in $PACKAGE_DIRS; do + case "$dir" in + */endtoend*|go/cmd/vttestserver*) continue ;; + esac + if go list "./$dir" >/dev/null 2>&1; then + PACKAGES="${PACKAGES:+$PACKAGES }$dir" + fi + done + + echo "BASE_SHA=$BASE_SHA" + echo "HEAD_SHA=$HEAD_SHA" + echo "packages=$PACKAGES" + + echo "packages=$PACKAGES" >> "$GITHUB_OUTPUT" + - name: Set up python - if: steps.changes.outputs.changed_files == 'true' - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 + if: steps.mode.outputs.is_full_run == 'true' || (steps.changes.outputs.changed_files == 'true' && steps.packages.outputs.packages != '') + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 - name: Tune the OS - if: steps.changes.outputs.changed_files == 'true' + if: steps.mode.outputs.is_full_run == 'true' || (steps.changes.outputs.changed_files == 'true' && steps.packages.outputs.packages != '') uses: ./.github/actions/tune-os - name: Setup MySQL - if: steps.changes.outputs.changed_files == 'true' + if: steps.mode.outputs.is_full_run == 'true' || (steps.changes.outputs.changed_files == 'true' && steps.packages.outputs.packages != '') uses: ./.github/actions/setup-mysql with: flavor: mysql-8.0 - name: Get dependencies - if: steps.changes.outputs.changed_files == 'true' + if: steps.mode.outputs.is_full_run == 'true' || (steps.changes.outputs.changed_files == 'true' && steps.packages.outputs.packages != '') run: | export DEBIAN_FRONTEND="noninteractive" sudo apt-get update @@ -73,35 +122,32 @@ jobs: go install golang.org/x/tools/cmd/goimports@latest - name: Run make tools - if: steps.changes.outputs.changed_files == 'true' + if: steps.mode.outputs.is_full_run == 'true' || (steps.changes.outputs.changed_files == 'true' && steps.packages.outputs.packages != '') run: | make tools - - name: Run unit tests and generate code coverage reports - if: steps.changes.outputs.changed_files == 'true' - timeout-minutes: 45 + - name: Run coverage tests + if: steps.mode.outputs.is_full_run == 'true' || (steps.changes.outputs.changed_files == 'true' && steps.packages.outputs.packages != '') + timeout-minutes: 60 run: | set -exo pipefail - # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file - # which musn't be more than 107 characters long. export VTDATAROOT="/tmp/" - export NOVTADMINBUILD=1 + source build.env - # Exclude endtoend tests from the coverage report. - # TODO: figure out how best to include our endtoend tests in the coverage report. - rm -rf go/test/endtoend go/*/endtoend go/vt/*/endtoend go/cmd/vttestserver - - make unit_test_cover - - # Restore the files we deleted as codecov tries to fix their paths. - git reset --hard HEAD + if [ "${{ steps.mode.outputs.is_full_run }}" = "true" ]; then + make unit_test_cover + else + make COVERAGE_PACKAGES="${{ steps.packages.outputs.packages }}" unit_test_cover + fi - - name: Upload coverage reports to codecov.io - if: steps.changes.outputs.changed_files == 'true' - uses: codecov/codecov-action@015f24e6818733317a2da2edd6290ab26238649a # https://github.com/codecov/codecov-action/releases/tag/v5.0.7 + - name: Upload coverage reports + if: steps.mode.outputs.is_full_run == 'true' || (steps.changes.outputs.changed_files == 'true' && steps.packages.outputs.packages != '') + uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2 with: + files: coverage.out fail_ci_if_error: true verbose: true + flags: ${{ steps.mode.outputs.is_full_run == 'true' && '' || 'partial' }} env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.gitignore b/.gitignore index e8c441d3bd7..3a471a05d22 100644 --- a/.gitignore +++ b/.gitignore @@ -93,3 +93,5 @@ report # mise files .mise.toml /errors/ +go/flags/endtoend/count_flags.sh +/coverage.out diff --git a/Makefile b/Makefile index 30779a0ddf4..c666175b4b7 100644 --- a/Makefile +++ b/Makefile @@ -219,13 +219,7 @@ e2e_test: build # Run the code coverage tools, compute aggregate. unit_test_cover: build dependency_check demo - source build.env - go test $(VT_GO_PARALLEL) -count=1 -failfast -covermode=atomic -coverpkg=vitess.io/vitess/go/... -coverprofile=coverage.out ./go/... - # Handle go tool cover failures due to not handling `//line` directives, which - # the goyacc compiler adds to the generated parser in sql.go. See: - # https://github.com/golang/go/issues/41222 - sed -i'' -e '/^vitess.io\/vitess\/go\/vt\/sqlparser\/yaccpar/d' coverage.out - go tool $(VT_GO_PARALLEL) cover -html=coverage.out + source build.env && tools/run_codecov.sh $(COVERAGE_PACKAGES) unit_test_race: build dependency_check RACE=1 tools/unit_test_runner.sh diff --git a/tools/run_codecov.sh b/tools/run_codecov.sh new file mode 100755 index 00000000000..c95a9157a7b --- /dev/null +++ b/tools/run_codecov.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# Run go test with coverage for one or more Go package directories. +# Usage: run_codecov.sh [dir ...] +# Example: run_codecov.sh go/vt/topo go/vt/vtctl +# +# With no arguments, runs coverage on all packages under go/. + +set -euo pipefail + +DIRS=("${@:-go}") + +COVERPKG=$(printf 'vitess.io/vitess/%s/...,' "${DIRS[@]}"); COVERPKG="${COVERPKG%,}" + +go test -count=1 \ + -covermode=atomic \ + -coverpkg="$COVERPKG" \ + -coverprofile=coverage.out \ + $(printf './%s/... ' "${DIRS[@]}") From 5937c4de673a0a329acb2b275c816541d0735718 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 10:20:21 -0400 Subject: [PATCH 089/112] [release-22.0] `vtorc`: support analysis ordering, improve semi-sync rollout (#19427) (#19471) Signed-off-by: Tim Vaillancourt Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Tim Vaillancourt --- go/test/endtoend/vtorc/general/vtorc_test.go | 84 +++ go/vt/vtorc/inst/analysis.go | 25 +- go/vt/vtorc/inst/analysis_dao.go | 197 ++----- go/vt/vtorc/inst/analysis_dao_test.go | 156 +++--- go/vt/vtorc/inst/analysis_problem.go | 512 ++++++++++++++++++ go/vt/vtorc/inst/analysis_problem_test.go | 257 +++++++++ go/vt/vtorc/inst/analysis_test.go | 70 +++ go/vt/vtorc/logic/topology_recovery.go | 119 ++-- go/vt/vtorc/logic/topology_recovery_dao.go | 6 +- .../vtorc/logic/topology_recovery_dao_test.go | 6 +- go/vt/vtorc/logic/topology_recovery_test.go | 40 +- go/vt/vtorc/server/api.go | 4 +- go/vt/vtorc/test/recovery_analysis.go | 3 +- 13 files changed, 1193 insertions(+), 286 deletions(-) create mode 100644 go/vt/vtorc/inst/analysis_problem.go create mode 100644 go/vt/vtorc/inst/analysis_problem_test.go create mode 100644 go/vt/vtorc/inst/analysis_test.go diff --git a/go/test/endtoend/vtorc/general/vtorc_test.go b/go/test/endtoend/vtorc/general/vtorc_test.go index 2d50aa2030a..eb554707345 100644 --- a/go/test/endtoend/vtorc/general/vtorc_test.go +++ b/go/test/endtoend/vtorc/general/vtorc_test.go @@ -18,7 +18,9 @@ package general import ( "context" + "encoding/json" "fmt" + "strconv" "testing" "time" @@ -892,3 +894,85 @@ func TestFullStatusConnectionPooling(t *testing.T) { assert.Equal(t, 200, status) assert.Equal(t, "null", resp) } + +// TestSemiSyncRecoveryOrdering verifies that when the durability policy changes +// to semi_sync, VTOrc fixes ReplicaSemiSyncMustBeSet before PrimarySemiSyncMustBeSet. +// This ordering is enforced by the AfterAnalyses/BeforeAnalyses dependencies. +func TestSemiSyncRecoveryOrdering(t *testing.T) { + defer utils.PrintVTOrcLogsOnFailure(t, clusterInfo.ClusterInstance) + // Start with durability "none" so no semi-sync is required initially. + utils.SetupVttabletsAndVTOrcs(t, clusterInfo, 2, 0, nil, cluster.VTOrcConfiguration{ + PreventCrossCellFailover: true, + }, 1, policy.DurabilityNone) + keyspace := &clusterInfo.ClusterInstance.Keyspaces[0] + shard0 := &keyspace.Shards[0] + + // Wait for primary election and healthy replication. + primary := utils.ShardPrimaryTablet(t, clusterInfo, keyspace, shard0) + assert.NotNil(t, primary, "should have elected a primary") + utils.CheckReplication(t, clusterInfo, primary, shard0.Vttablets, 10*time.Second) + + vtorc := clusterInfo.ClusterInstance.VTOrcProcesses[0] + utils.WaitForSuccessfulRecoveryCount(t, vtorc, logic.ElectNewPrimaryRecoveryName, 1) + + // Change durability to semi_sync. VTOrc should detect that replicas and primary + // need semi-sync enabled, and fix them in the correct order. + out, err := clusterInfo.ClusterInstance.VtctldClientProcess.ExecuteCommandWithOutput( + "SetKeyspaceDurabilityPolicy", keyspace.Name, "--durability-policy="+policy.DurabilitySemiSync) + require.NoError(t, err, out) + + // Poll the database-state API to verify recovery ordering. + // The topology_recovery table has auto-incremented recovery_id values that + // reflect execution order. All ReplicaSemiSyncMustBeSet recovery_ids should + // be less than any PrimarySemiSyncMustBeSet recovery_id. + type tableState struct { + TableName string + Rows []map[string]any + } + + assert.EventuallyWithT(t, func(c *assert.CollectT) { + status, response, err := utils.MakeAPICall(t, vtorc, "/api/database-state") + assert.NoError(c, err) + assert.Equal(c, 200, status) + + var tables []tableState + if !assert.NoError(c, json.Unmarshal([]byte(response), &tables)) { + return + } + + var maxReplicaRecoveryID, minPrimaryRecoveryID int + var replicaCount, primaryCount int + for _, table := range tables { + if table.TableName != "topology_recovery" { + continue + } + for _, row := range table.Rows { + analysis, _ := row["analysis"].(string) + recoveryIDStr, _ := row["recovery_id"].(string) + recoveryID, err := strconv.Atoi(recoveryIDStr) + if err != nil { + continue + } + switch inst.AnalysisCode(analysis) { + case inst.ReplicaSemiSyncMustBeSet: + replicaCount++ + if replicaCount == 1 || recoveryID > maxReplicaRecoveryID { + maxReplicaRecoveryID = recoveryID + } + case inst.PrimarySemiSyncMustBeSet: + primaryCount++ + if primaryCount == 1 || recoveryID < minPrimaryRecoveryID { + minPrimaryRecoveryID = recoveryID + } + } + } + } + + assert.Greater(c, replicaCount, 0, "should have ReplicaSemiSyncMustBeSet recoveries") + assert.Greater(c, primaryCount, 0, "should have PrimarySemiSyncMustBeSet recoveries") + if replicaCount > 0 && primaryCount > 0 { + assert.Less(c, maxReplicaRecoveryID, minPrimaryRecoveryID, + "all ReplicaSemiSyncMustBeSet recoveries should have lower recovery_id than PrimarySemiSyncMustBeSet") + } + }, 30*time.Second, time.Second) +} diff --git a/go/vt/vtorc/inst/analysis.go b/go/vt/vtorc/inst/analysis.go index b8eeb3a3c9f..9497dc20d45 100644 --- a/go/vt/vtorc/inst/analysis.go +++ b/go/vt/vtorc/inst/analysis.go @@ -21,6 +21,7 @@ import ( "time" topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/vt/vtorc/config" ) @@ -84,12 +85,12 @@ const ( // Key of this map is a InstanceAnalysis.String() type PeerAnalysisMap map[string]int -type ReplicationAnalysisHints struct { +type DetectionAnalysisHints struct { AuditAnalysis bool } -// ReplicationAnalysis notes analysis on replication chain status, per instance -type ReplicationAnalysis struct { +// DetectionAnalysis notes analysis on replication chain status, per instance +type DetectionAnalysis struct { AnalyzedInstanceAlias string AnalyzedInstancePrimaryAlias string @@ -114,11 +115,13 @@ type ReplicationAnalysis struct { CountReplicas uint CountValidReplicas uint CountValidReplicatingReplicas uint + CountValidSemiSyncReplicatingReplicas uint ReplicationStopped bool ErrantGTID string ReplicaNetTimeout int32 HeartbeatInterval float64 Analysis AnalysisCode + AnalysisMatchedProblems []*DetectionAnalysisProblemMeta Description string StructureAnalysis []StructureAnalysisCode OracleGTIDImmediateTopology bool @@ -147,11 +150,21 @@ type ReplicationAnalysis struct { IsDiskStalled bool } -func (replicationAnalysis *ReplicationAnalysis) MarshalJSON() ([]byte, error) { +// hasMinSemiSyncAckers returns true if there are a minimum number of semi-sync ackers enabled and replicating. +// True is always returned if the durability policy does not require semi-sync ackers (eg: "none"). This gives +// a useful signal if it is safe to enable semi-sync without risk of stalling ongoing PRIMARY writes. +func hasMinSemiSyncAckers(durabler policy.Durabler, primary *topodatapb.Tablet, analysis *DetectionAnalysis) bool { + if durabler == nil || analysis == nil { + return false + } + return int(analysis.CountValidSemiSyncReplicatingReplicas) >= durabler.SemiSyncAckers(primary) +} + +func (detectionAnalysis *DetectionAnalysis) MarshalJSON() ([]byte, error) { i := struct { - ReplicationAnalysis + DetectionAnalysis }{} - i.ReplicationAnalysis = *replicationAnalysis + i.DetectionAnalysis = *detectionAnalysis return json.Marshal(i) } diff --git a/go/vt/vtorc/inst/analysis_dao.go b/go/vt/vtorc/inst/analysis_dao.go index 6479923dda3..f4ba598cb9c 100644 --- a/go/vt/vtorc/inst/analysis_dao.go +++ b/go/vt/vtorc/inst/analysis_dao.go @@ -18,7 +18,6 @@ package inst import ( "fmt" - "math" "time" "github.com/patrickmn/go-cache" @@ -51,9 +50,9 @@ func initializeAnalysisDaoPostConfiguration() { } type clusterAnalysis struct { - hasClusterwideAction bool - totalTablets int - primaryAlias string + hasShardWideAction bool + totalTablets int + primaryAlias string // primaryTimestamp is the most recent primary term start time observed for the shard. primaryTimestamp time.Time @@ -62,17 +61,17 @@ type clusterAnalysis struct { durability policy.Durabler } -// GetReplicationAnalysis will check for replication problems (dead primary; unreachable primary; etc) -func GetReplicationAnalysis(keyspace string, shard string, hints *ReplicationAnalysisHints) ([]*ReplicationAnalysis, error) { - var result []*ReplicationAnalysis - appendAnalysis := func(analysis *ReplicationAnalysis) { +// GetDetectionAnalysis will check for replication problems (dead primary; unreachable primary; etc) +func GetDetectionAnalysis(keyspace string, shard string, hints *DetectionAnalysisHints) ([]*DetectionAnalysis, error) { + var result []*DetectionAnalysis + appendAnalysis := func(analysis *DetectionAnalysis) { if analysis.Analysis == NoProblem && len(analysis.StructureAnalysis) == 0 { return } result = append(result, analysis) } - // TODO(sougou); deprecate ReduceReplicationAnalysisCount + // TODO(sougou); deprecate ReduceDetectionAnalysisCount args := sqlutils.Args(config.GetReasonableReplicationLagSeconds(), ValidSecondsFromSeenToLastAttemptedCheck(), config.GetReasonableReplicationLagSeconds(), keyspace, shard) query := `SELECT vitess_tablet.info AS tablet_info, @@ -194,6 +193,15 @@ func GetReplicationAnalysis(keyspace string, shard string, hints *ReplicationAna ), 0 ) AS count_valid_semi_sync_replicas, + IFNULL( + SUM( + replica_instance.last_checked <= replica_instance.last_seen + AND replica_instance.replica_io_running != 0 + AND replica_instance.replica_sql_running != 0 + AND replica_instance.semi_sync_replica_enabled != 0 + ), + 0 + ) AS count_valid_semi_sync_replicating_replicas, IFNULL( SUM( replica_instance.log_bin @@ -283,7 +291,7 @@ func GetReplicationAnalysis(keyspace string, shard string, hints *ReplicationAna clusters := make(map[string]*clusterAnalysis) err := db.Db.QueryVTOrc(query, args, func(m sqlutils.RowMap) error { - a := &ReplicationAnalysis{ + a := &DetectionAnalysis{ Analysis: NoProblem, } @@ -348,6 +356,7 @@ func GetReplicationAnalysis(keyspace string, shard string, hints *ReplicationAna a.SemiSyncBlocked = m.GetBool("semi_sync_blocked") a.SemiSyncReplicaEnabled = m.GetBool("semi_sync_replica_enabled") a.CountSemiSyncReplicasEnabled = m.GetUint("count_semi_sync_replicas") + a.CountValidSemiSyncReplicatingReplicas = m.GetUint("count_valid_semi_sync_replicating_replicas") // countValidSemiSyncReplicasEnabled := m.GetUint("count_valid_semi_sync_replicas") a.SemiSyncPrimaryWaitForReplicaCount = m.GetUint("semi_sync_primary_wait_for_replica_count") a.SemiSyncPrimaryClients = m.GetUint("semi_sync_primary_clients") @@ -402,8 +411,8 @@ func GetReplicationAnalysis(keyspace string, shard string, hints *ReplicationAna ca := clusters[keyspaceShard] // Increment the total number of tablets. ca.totalTablets += 1 - if ca.hasClusterwideAction { - // We can only take one cluster level action at a time. + if ca.hasShardWideAction { + // We can only take one shard-wide action at a time. return nil } if ca.durability == nil { @@ -411,142 +420,30 @@ func GetReplicationAnalysis(keyspace string, shard string, hints *ReplicationAna return nil } isInvalid := m.GetBool("is_invalid") - if a.IsClusterPrimary && isInvalid { - a.Analysis = InvalidPrimary - a.Description = "VTOrc hasn't been able to reach the primary even once since restart/shutdown" - } else if isInvalid { - a.Analysis = InvalidReplica - a.Description = "VTOrc hasn't been able to reach the replica even once since restart/shutdown" - } else if a.IsClusterPrimary && !a.LastCheckValid && a.IsDiskStalled { - a.Analysis = PrimaryDiskStalled - a.Description = "Primary has a stalled disk" - ca.hasClusterwideAction = true - } else if a.IsClusterPrimary && !a.LastCheckValid && a.CountReplicas == 0 { - a.Analysis = DeadPrimaryWithoutReplicas - a.Description = "Primary cannot be reached by vtorc and has no replica" - ca.hasClusterwideAction = true - // - } else if a.IsClusterPrimary && !a.LastCheckValid && a.CountValidReplicas == a.CountReplicas && a.CountValidReplicatingReplicas == 0 { - a.Analysis = DeadPrimary - a.Description = "Primary cannot be reached by vtorc and none of its replicas is replicating" - ca.hasClusterwideAction = true - // - } else if a.IsClusterPrimary && !a.LastCheckValid && a.CountReplicas > 0 && a.CountValidReplicas == 0 && a.CountValidReplicatingReplicas == 0 { - a.Analysis = DeadPrimaryAndReplicas - a.Description = "Primary cannot be reached by vtorc and none of its replicas is replicating" - ca.hasClusterwideAction = true - // - } else if a.IsClusterPrimary && !a.LastCheckValid && a.CountValidReplicas < a.CountReplicas && a.CountValidReplicas > 0 && a.CountValidReplicatingReplicas == 0 { - a.Analysis = DeadPrimaryAndSomeReplicas - a.Description = "Primary cannot be reached by vtorc; some of its replicas are unreachable and none of its reachable replicas is replicating" - ca.hasClusterwideAction = true - // - } else if a.IsClusterPrimary && !a.IsPrimary { - a.Analysis = PrimaryHasPrimary - a.Description = "Primary is replicating from somewhere else" - ca.hasClusterwideAction = true - // - } else if a.IsClusterPrimary && a.IsReadOnly { - a.Analysis = PrimaryIsReadOnly - a.Description = "Primary is read-only" - // - } else if a.IsClusterPrimary && policy.SemiSyncAckers(ca.durability, tablet) != 0 && !a.SemiSyncPrimaryEnabled { - a.Analysis = PrimarySemiSyncMustBeSet - a.Description = "Primary semi-sync must be set" - // - } else if a.IsClusterPrimary && policy.SemiSyncAckers(ca.durability, tablet) == 0 && a.SemiSyncPrimaryEnabled { - a.Analysis = PrimarySemiSyncMustNotBeSet - a.Description = "Primary semi-sync must not be set" - // - } else if a.IsClusterPrimary && a.CurrentTabletType != topodatapb.TabletType_UNKNOWN && a.CurrentTabletType != topodatapb.TabletType_PRIMARY { - a.Analysis = PrimaryCurrentTypeMismatch - a.Description = "Primary tablet's current type is not PRIMARY" - } else if topo.IsReplicaType(a.TabletType) && a.ErrantGTID != "" { - a.Analysis = ErrantGTIDDetected - a.Description = "Tablet has errant GTIDs" - } else if isStaleTopoPrimary(a, ca) { - a.Analysis = StaleTopoPrimary - a.Description = "Primary tablet is stale, older than current primary" - } else if topo.IsReplicaType(a.TabletType) && ca.primaryAlias == "" && a.ShardPrimaryTermTimestamp == "" { - // ClusterHasNoPrimary should only be detected when the shard record doesn't have any primary term start time specified either. - a.Analysis = ClusterHasNoPrimary - a.Description = "Cluster has no primary" - ca.hasClusterwideAction = true - } else if topo.IsReplicaType(a.TabletType) && ca.primaryAlias == "" && a.ShardPrimaryTermTimestamp != "" { - // If there are no primary tablets, but the shard primary start time isn't empty, then we know - // the primary tablet was deleted. - a.Analysis = PrimaryTabletDeleted - a.Description = "Primary tablet has been deleted" - ca.hasClusterwideAction = true - } else if a.IsPrimary && a.SemiSyncBlocked && a.CountSemiSyncReplicasEnabled >= a.SemiSyncPrimaryWaitForReplicaCount { - // The primary is reporting that semi-sync monitor is blocked on writes. - // There are enough replicas configured to send semi-sync ACKs such that the primary shouldn't be blocked. - // There is some network diruption in progress. We should run an ERS. - a.Analysis = PrimarySemiSyncBlocked - a.Description = "Writes seem to be blocked on semi-sync acks on the primary, even though sufficient replicas are configured to send ACKs" - ca.hasClusterwideAction = true - } else if topo.IsReplicaType(a.TabletType) && !a.IsReadOnly { - a.Analysis = ReplicaIsWritable - a.Description = "Replica is writable" - // - } else if topo.IsReplicaType(a.TabletType) && a.IsPrimary { - a.Analysis = NotConnectedToPrimary - a.Description = "Not connected to the primary" - // - } else if topo.IsReplicaType(a.TabletType) && !a.IsPrimary && math.Round(a.HeartbeatInterval*2) != float64(a.ReplicaNetTimeout) { - a.Analysis = ReplicaMisconfigured - a.Description = "Replica has been misconfigured" - // - } else if topo.IsReplicaType(a.TabletType) && !a.IsPrimary && ca.primaryAlias != "" && a.AnalyzedInstancePrimaryAlias != ca.primaryAlias { - a.Analysis = ConnectedToWrongPrimary - a.Description = "Connected to wrong primary" - // - } else if topo.IsReplicaType(a.TabletType) && !a.IsPrimary && a.ReplicationStopped { - a.Analysis = ReplicationStopped - a.Description = "Replication is stopped" - // - } else if topo.IsReplicaType(a.TabletType) && !a.IsPrimary && policy.IsReplicaSemiSync(ca.durability, primaryTablet, tablet) && !a.SemiSyncReplicaEnabled { - a.Analysis = ReplicaSemiSyncMustBeSet - a.Description = "Replica semi-sync must be set" - // - } else if topo.IsReplicaType(a.TabletType) && !a.IsPrimary && !policy.IsReplicaSemiSync(ca.durability, primaryTablet, tablet) && a.SemiSyncReplicaEnabled { - a.Analysis = ReplicaSemiSyncMustNotBeSet - a.Description = "Replica semi-sync must not be set" - // - // TODO(sougou): Events below here are either ignored or not possible. - } else if a.IsPrimary && !a.LastCheckValid && a.CountLaggingReplicas == a.CountReplicas && a.CountDelayedReplicas < a.CountReplicas && a.CountValidReplicatingReplicas > 0 { - a.Analysis = UnreachablePrimaryWithLaggingReplicas - a.Description = "Primary cannot be reached by vtorc and all of its replicas are lagging" - // - } else if a.IsPrimary && !a.LastCheckValid && !a.LastCheckPartialSuccess && a.CountValidReplicas > 0 && a.CountValidReplicatingReplicas > 0 { - // partial success is here to reduce noise - a.Analysis = UnreachablePrimary - a.Description = "Primary cannot be reached by vtorc but it has replicating replicas; possibly a network/host issue" - // - } else if a.IsPrimary && a.SemiSyncPrimaryEnabled && a.SemiSyncPrimaryStatus && a.SemiSyncPrimaryWaitForReplicaCount > 0 && a.SemiSyncPrimaryClients < a.SemiSyncPrimaryWaitForReplicaCount { - if isStaleBinlogCoordinates { - a.Analysis = LockedSemiSyncPrimary - a.Description = "Semi sync primary is locked since it doesn't get enough replica acknowledgements" - } else { - a.Analysis = LockedSemiSyncPrimaryHypothesis - a.Description = "Semi sync primary seems to be locked, more samplings needed to validate" + var matchedProblems []*DetectionAnalysisProblem + for _, problem := range detectionAnalysisProblems { + // When isInvalid is true, instance data is unreliable (never been reached). + // Only InvalidPrimary/InvalidReplica should match; postProcessAnalyses + // handles upgrading InvalidPrimary to DeadPrimary if needed. + if isInvalid && problem.Meta.Analysis != InvalidPrimary && problem.Meta.Analysis != InvalidReplica { + continue + } + if problem.HasMatch(a, ca, primaryTablet, tablet, isInvalid, isStaleBinlogCoordinates) { + matchedProblems = append(matchedProblems, problem) + } + } + if len(matchedProblems) > 0 { + sortDetectionAnalysisMatchedProblems(matchedProblems) + for _, problem := range matchedProblems { + a.AnalysisMatchedProblems = append(a.AnalysisMatchedProblems, problem.Meta) } - // - } else if a.IsPrimary && a.LastCheckValid && a.CountReplicas == 1 && a.CountValidReplicas == a.CountReplicas && a.CountValidReplicatingReplicas == 0 { - a.Analysis = PrimarySingleReplicaNotReplicating - a.Description = "Primary is reachable but its single replica is not replicating" - } else if a.IsPrimary && a.LastCheckValid && a.CountReplicas == 1 && a.CountValidReplicas == 0 { - a.Analysis = PrimarySingleReplicaDead - a.Description = "Primary is reachable but its single replica is dead" - // - } else if a.IsPrimary && a.LastCheckValid && a.CountReplicas > 1 && a.CountValidReplicas == a.CountReplicas && a.CountValidReplicatingReplicas == 0 { - a.Analysis = AllPrimaryReplicasNotReplicating - a.Description = "Primary is reachable but none of its replicas is replicating" - // - } else if a.IsPrimary && a.LastCheckValid && a.CountReplicas > 1 && a.CountValidReplicas < a.CountReplicas && a.CountValidReplicas > 0 && a.CountValidReplicatingReplicas == 0 { - a.Analysis = AllPrimaryReplicasNotReplicatingOrDead - a.Description = "Primary is reachable but none of its replicas is replicating" - // + // We return a single problem per tablet. Any remaining problems will be discovered/recovered + // by VTOrc(s) on future polls. Often many problems are resolved by a single recovery of the + // first problem. The first element of matchedProblems is the highest-priority problem. + chosenProblem := matchedProblems[0] + a.Analysis = chosenProblem.Meta.Analysis + a.Description = chosenProblem.Meta.Description + ca.hasShardWideAction = chosenProblem.Meta.Priority == detectionAnalysisPriorityShardWideAction } // else if a.IsPrimary && a.CountReplicas == 0 { // a.Analysis = PrimaryWithoutReplicas @@ -608,13 +505,13 @@ func GetReplicationAnalysis(keyspace string, shard string, hints *ReplicationAna if err != nil { log.Error(err) } - // TODO: result, err = getConcensusReplicationAnalysis(result) + // TODO: result, err = getConcensusDetectionAnalysis(result) return result, err } // isStaleTopoPrimary returns true when a tablet has type PRIMARY in the topology and has an older primary term // start time than the shard's current primary. -func isStaleTopoPrimary(tablet *ReplicationAnalysis, cluster *clusterAnalysis) bool { +func isStaleTopoPrimary(tablet *DetectionAnalysis, cluster *clusterAnalysis) bool { if tablet.TabletType != topodatapb.TabletType_PRIMARY { return false } @@ -623,7 +520,7 @@ func isStaleTopoPrimary(tablet *ReplicationAnalysis, cluster *clusterAnalysis) b } // postProcessAnalyses is used to update different analyses based on the information gleaned from looking at all the analyses together instead of individual data. -func postProcessAnalyses(result []*ReplicationAnalysis, clusters map[string]*clusterAnalysis) []*ReplicationAnalysis { +func postProcessAnalyses(result []*DetectionAnalysis, clusters map[string]*clusterAnalysis) []*DetectionAnalysis { for { // Store whether we have changed the result of replication analysis or not. resultChanged := false diff --git a/go/vt/vtorc/inst/analysis_dao_test.go b/go/vt/vtorc/inst/analysis_dao_test.go index ddf2e9bc0af..cdb15d209fc 100644 --- a/go/vt/vtorc/inst/analysis_dao_test.go +++ b/go/vt/vtorc/inst/analysis_dao_test.go @@ -45,10 +45,10 @@ var initialSQL = []string{ `INSERT INTO vitess_keyspace VALUES('ks',0,'semi_sync');`, } -// TestGetReplicationAnalysisDecision tests the code of GetReplicationAnalysis decision-making. It doesn't check the SQL query +// TestGetDetectionAnalysisDecision tests the code of GetDetectionAnalysis decision-making. It doesn't check the SQL query // run by it. It only checks the analysis part after the rows have been read. This tests fakes the db and explicitly returns the // rows that are specified in the test. -func TestGetReplicationAnalysisDecision(t *testing.T) { +func TestGetDetectionAnalysisDecision(t *testing.T) { tests := []struct { name string info []*test.InfoForRecoveryAnalysis @@ -61,7 +61,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "ClusterHasNoPrimary", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -80,7 +80,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "PrimaryTabletDeleted", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -100,7 +100,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "StalledDiskPrimary", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -125,7 +125,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "PrimarySemiSyncBlocked", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -155,7 +155,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "LockedSemiSync", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -185,7 +185,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "DeadPrimary", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -209,7 +209,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "DeadPrimaryWithoutReplicas", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -231,7 +231,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "DeadPrimaryAndReplicas", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -253,7 +253,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "DeadPrimaryAndSomeReplicas", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -277,7 +277,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "PrimaryHasPrimary", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -300,7 +300,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "PrimaryIsReadOnly", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -324,7 +324,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "PrimaryCurrentTypeMismatch", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -347,7 +347,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "Unknown tablet type shouldn't run the mismatch recovery analysis", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 101}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -373,7 +373,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "PrimarySemiSyncMustNotBeSet", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -397,7 +397,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "PrimarySemiSyncMustBeSet", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -405,13 +405,15 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlHostname: "localhost", MysqlPort: 6709, }, - DurabilityPolicy: policy.DurabilitySemiSync, - LastCheckValid: 1, - CountReplicas: 4, - CountValidReplicas: 4, - IsPrimary: 1, - SemiSyncPrimaryEnabled: 0, - CurrentTabletType: int(topodatapb.TabletType_PRIMARY), + DurabilityPolicy: policy.DurabilitySemiSync, + LastCheckValid: 1, + CountReplicas: 4, + CountValidReplicas: 4, + CountValidReplicatingReplicas: 4, + CountValidSemiSyncReplicatingReplicas: 1, + IsPrimary: 1, + SemiSyncPrimaryEnabled: 0, + CurrentTabletType: int(topodatapb.TabletType_PRIMARY), }}, keyspaceWanted: "ks", shardWanted: "0", @@ -421,7 +423,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "NotConnectedToPrimary", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 101}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -440,7 +442,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { CurrentTabletType: int(topodatapb.TabletType_PRIMARY), }, { TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -460,7 +462,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "ReplicaIsWritable", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 101}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -479,7 +481,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { CurrentTabletType: int(topodatapb.TabletType_PRIMARY), }, { TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -489,7 +491,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { }, DurabilityPolicy: policy.DurabilityNone, PrimaryTabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 101}, }, LastCheckValid: 1, ReadOnly: 0, @@ -502,7 +504,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "ConnectedToWrongPrimary", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 101}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -521,7 +523,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { CurrentTabletType: int(topodatapb.TabletType_PRIMARY), }, { TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -531,7 +533,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { }, DurabilityPolicy: policy.DurabilityNone, PrimaryTabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 102}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 102}, }, LastCheckValid: 1, ReadOnly: 1, @@ -544,7 +546,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "ReplicationStopped", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 101}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -563,7 +565,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { CurrentTabletType: int(topodatapb.TabletType_PRIMARY), }, { TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -573,7 +575,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { }, DurabilityPolicy: policy.DurabilityNone, PrimaryTabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 101}, }, LastCheckValid: 1, ReadOnly: 1, @@ -587,7 +589,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "No recoveries on drained tablets", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 101}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -606,7 +608,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { CurrentTabletType: int(topodatapb.TabletType_PRIMARY), }, { TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -616,7 +618,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { }, DurabilityPolicy: policy.DurabilityNone, PrimaryTabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 101}, }, LastCheckValid: 1, ReadOnly: 1, @@ -630,7 +632,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "ReplicaMisconfigured", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 101}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -649,7 +651,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { CurrentTabletType: int(topodatapb.TabletType_PRIMARY), }, { TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -659,7 +661,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { }, DurabilityPolicy: policy.DurabilityNone, PrimaryTabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 101}, }, LastCheckValid: 1, ReadOnly: 1, @@ -674,7 +676,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "ReplicaSemiSyncMustBeSet", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 101}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -694,7 +696,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { CurrentTabletType: int(topodatapb.TabletType_PRIMARY), }, { TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -703,7 +705,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlPort: 6709, }, PrimaryTabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 101}, }, DurabilityPolicy: policy.DurabilitySemiSync, LastCheckValid: 1, @@ -718,7 +720,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "ReplicaSemiSyncMustNotBeSet", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 101}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -737,7 +739,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { CurrentTabletType: int(topodatapb.TabletType_PRIMARY), }, { TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -746,7 +748,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { MysqlPort: 6709, }, PrimaryTabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 101}, }, DurabilityPolicy: policy.DurabilityNone, LastCheckValid: 1, @@ -761,7 +763,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "SnapshotKeyspace", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -782,7 +784,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "EmptyDurabilityPolicy", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -803,7 +805,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "Empty database_instance table", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 101}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -823,7 +825,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { CurrentTabletType: int(topodatapb.TabletType_PRIMARY), }, { TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -842,7 +844,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "DeadPrimary when VTOrc is starting up", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 101}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -854,7 +856,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { IsInvalid: 1, }, { TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -866,7 +868,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { ReplicationStopped: 1, }, { TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 103}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 103}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -885,7 +887,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "Invalid Primary", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 101}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -904,7 +906,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "ErrantGTID", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 101}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -923,7 +925,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { CurrentTabletType: int(topodatapb.TabletType_PRIMARY), }, { TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -934,7 +936,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { DurabilityPolicy: policy.DurabilityNone, ErrantGTID: "some errant GTID", PrimaryTabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 101}, }, LastCheckValid: 1, ReadOnly: 1, @@ -947,7 +949,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { name: "ErrantGTID on a non-replica", info: []*test.InfoForRecoveryAnalysis{{ TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 101}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -966,7 +968,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { CurrentTabletType: int(topodatapb.TabletType_PRIMARY), }, { TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -977,7 +979,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { DurabilityPolicy: policy.DurabilityNone, ErrantGTID: "some errant GTID", PrimaryTabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 101}, }, LastCheckValid: 1, ReadOnly: 1, @@ -1001,7 +1003,7 @@ func TestGetReplicationAnalysisDecision(t *testing.T) { } db.Db = test.NewTestDB([][]sqlutils.RowMap{rowMaps}) - got, err := GetReplicationAnalysis("", "", &ReplicationAnalysisHints{}) + got, err := GetDetectionAnalysis("", "", &DetectionAnalysisHints{}) if tt.wantErr != "" { require.EqualError(t, err, tt.wantErr) return @@ -1036,7 +1038,7 @@ func TestStalePrimary(t *testing.T) { info := []*test.InfoForRecoveryAnalysis{ { TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 101}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -1060,7 +1062,7 @@ func TestStalePrimary(t *testing.T) { }, { TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 100}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -1070,7 +1072,7 @@ func TestStalePrimary(t *testing.T) { }, DurabilityPolicy: policy.DurabilitySemiSync, PrimaryTabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 101}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 101}, }, LastCheckValid: 1, ReadOnly: 1, @@ -1079,7 +1081,7 @@ func TestStalePrimary(t *testing.T) { }, { TabletInfo: &topodatapb.Tablet{ - Alias: &topodatapb.TabletAlias{Cell: "zon1", Uid: 102}, + Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 102}, Hostname: "localhost", Keyspace: "ks", Shard: "0", @@ -1110,7 +1112,7 @@ func TestStalePrimary(t *testing.T) { // Each sampling should yield the placeholder analysis that represents the future recovery behavior once // the demotion logic is implemented, which makes this test fail until the actual fix is in place. for range 2 { - got, err := GetReplicationAnalysis("", "", &ReplicationAnalysisHints{}) + got, err := GetDetectionAnalysis("", "", &DetectionAnalysisHints{}) require.NoError(t, err, "expected detection analysis to run without error") require.Len(t, got, 1, "expected exactly one analysis entry for the shard") require.Equal(t, AnalysisCode("StaleTopoPrimary"), got[0].Analysis, "expected stale primary analysis") @@ -1119,11 +1121,11 @@ func TestStalePrimary(t *testing.T) { } } -// TestGetReplicationAnalysis tests the entire GetReplicationAnalysis. It inserts data into the database and runs the function. -// The database is not faked. This is intended to give more test coverage. This test is more comprehensive but more expensive than TestGetReplicationAnalysisDecision. +// TestGetDetectionAnalysis tests the entire GetDetectionAnalysis. It inserts data into the database and runs the function. +// The database is not faked. This is intended to give more test coverage. This test is more comprehensive but more expensive than TestGetDetectionAnalysisDecision. // This test is somewhere between a unit test, and an end-to-end test. It is specifically useful for testing situations which are hard to come by in end-to-end test, but require // real-world data to test specifically. -func TestGetReplicationAnalysis(t *testing.T) { +func TestGetDetectionAnalysis(t *testing.T) { // The test is intended to be used as follows. The initial data is stored into the database. Following this, some specific queries are run that each individual test specifies to get the desired state. tests := []struct { name string @@ -1185,7 +1187,7 @@ func TestGetReplicationAnalysis(t *testing.T) { require.NoError(t, err) } - got, err := GetReplicationAnalysis("", "", &ReplicationAnalysisHints{}) + got, err := GetDetectionAnalysis("", "", &DetectionAnalysisHints{}) require.NoError(t, err) if tt.codeWanted == NoProblem { require.Len(t, got, 0) @@ -1292,12 +1294,12 @@ func TestPostProcessAnalyses(t *testing.T) { tests := []struct { name string - analyses []*ReplicationAnalysis - want []*ReplicationAnalysis + analyses []*DetectionAnalysis + want []*DetectionAnalysis }{ { name: "No processing needed", - analyses: []*ReplicationAnalysis{ + analyses: []*DetectionAnalysis{ { Analysis: ReplicationStopped, TabletType: topodatapb.TabletType_REPLICA, @@ -1318,7 +1320,7 @@ func TestPostProcessAnalyses(t *testing.T) { }, { name: "Conversion of InvalidPrimary to DeadPrimary", - analyses: []*ReplicationAnalysis{ + analyses: []*DetectionAnalysis{ { Analysis: InvalidPrimary, AnalyzedInstanceAlias: "zone1-100", @@ -1358,7 +1360,7 @@ func TestPostProcessAnalyses(t *testing.T) { ClusterDetails: ks80, }, }, - want: []*ReplicationAnalysis{ + want: []*DetectionAnalysis{ { Analysis: DeadPrimary, AnalyzedInstanceAlias: "zone1-100", @@ -1381,7 +1383,7 @@ func TestPostProcessAnalyses(t *testing.T) { }, { name: "Unable to convert InvalidPrimary to DeadPrimary", - analyses: []*ReplicationAnalysis{ + analyses: []*DetectionAnalysis{ { Analysis: InvalidPrimary, AnalyzedInstanceAlias: "zone1-100", diff --git a/go/vt/vtorc/inst/analysis_problem.go b/go/vt/vtorc/inst/analysis_problem.go new file mode 100644 index 00000000000..ebfa89fc112 --- /dev/null +++ b/go/vt/vtorc/inst/analysis_problem.go @@ -0,0 +1,512 @@ +/* +Copyright 2026 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package inst + +import ( + "math" + "slices" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/topoproto" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" +) + +const ( + detectionAnalysisPriorityShardWideAction = iota + detectionAnalysisPriorityCritical + detectionAnalysisPriorityHigh + detectionAnalysisPriorityMedium + detectionAnalysisPriorityLow +) + +// DetectionAnalysisProblemMeta contains basic metadata describing a problem. +type DetectionAnalysisProblemMeta struct { + // Analysis is the AnalysisCode representing the type of problem. + Analysis AnalysisCode + + // Description is a human-readable description of the problem. + Description string + + // Priority is an integer influencing the priority sorting of problems. A lower + // number is considered to be higher in the sort, with 0 being the top-priority. + Priority int +} + +// DetectionAnalysisProblem describes how to match, sort and track a problem. +type DetectionAnalysisProblem struct { + // Meta contains the metadata describing a problem. + Meta *DetectionAnalysisProblemMeta + + // AfterAnalyses defines problems that must be recovered before this problem. + AfterAnalyses []AnalysisCode + + // BeforeAnalyses defines problems that must be recovered after this problem. + BeforeAnalyses []AnalysisCode + + // MatchFunc is a function that returns true when the provided conditions match this problem. + MatchFunc func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool +} + +// RequiresOrderedExecution returns true if the problem must be executed +// sequentially relative to other problems in the same shard. +func (dap *DetectionAnalysisProblem) RequiresOrderedExecution() bool { + return dap.Meta.Priority == detectionAnalysisPriorityShardWideAction || len(dap.BeforeAnalyses) > 0 || len(dap.AfterAnalyses) > 0 +} + +// GetPriority returns the priority of a problem as an int. +func (dap *DetectionAnalysisProblem) GetPriority() int { + if dap.Meta == nil { + return 0 + } + return dap.Meta.Priority +} + +// GetDetectionAnalysisProblem returns the DetectionAnalysisProblem for the given AnalysisCode. +func GetDetectionAnalysisProblem(code AnalysisCode) *DetectionAnalysisProblem { + for _, p := range detectionAnalysisProblems { + if p.Meta.Analysis == code { + return p + } + } + return nil +} + +// HasMatch returns true if a DetectionAnalysisProblem matches the provided states. +func (dap *DetectionAnalysisProblem) HasMatch(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + if a == nil || ca == nil || dap.MatchFunc == nil { + return false + } + return dap.MatchFunc(a, ca, primary, tablet, isInvalid, isStaleBinlogCoordinates) +} + +// detectionAnalysisProblems contains all possible problems to match during detection analysis. +var detectionAnalysisProblems = []*DetectionAnalysisProblem{ + // InvalidPrimary and InvalidReplica + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: InvalidPrimary, + Description: "VTOrc hasn't been able to reach the primary even once since restart/shutdown", + Priority: detectionAnalysisPriorityCritical, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return a.IsClusterPrimary && isInvalid + }, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: InvalidReplica, + Description: "VTOrc hasn't been able to reach the replica even once since restart/shutdown", + Priority: detectionAnalysisPriorityLow, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return isInvalid + }, + }, + + // PrimaryDiskStalled + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: PrimaryDiskStalled, + Description: "Primary has a stalled disk", + Priority: detectionAnalysisPriorityShardWideAction, + }, + BeforeAnalyses: []AnalysisCode{DeadPrimary, DeadPrimaryAndReplicas, DeadPrimaryAndSomeReplicas, DeadPrimaryWithoutReplicas}, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return a.IsClusterPrimary && !a.LastCheckValid && a.IsDiskStalled + }, + }, + + // DeadPrimary* + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: DeadPrimaryWithoutReplicas, + Description: "Primary cannot be reached by vtorc and has no replica", + Priority: detectionAnalysisPriorityShardWideAction, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return a.IsClusterPrimary && !a.LastCheckValid && a.CountReplicas == 0 + }, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: DeadPrimary, + Description: "Primary cannot be reached by vtorc and none of its replicas is replicating", + Priority: detectionAnalysisPriorityShardWideAction, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return a.IsClusterPrimary && !a.LastCheckValid && a.CountReplicas > 0 && a.CountValidReplicas == a.CountReplicas && a.CountValidReplicatingReplicas == 0 + }, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: DeadPrimaryAndReplicas, + Description: "Primary cannot be reached by vtorc and none of its replicas is replicating", + Priority: detectionAnalysisPriorityShardWideAction, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return a.IsClusterPrimary && !a.LastCheckValid && a.CountReplicas > 0 && a.CountValidReplicas == 0 && a.CountValidReplicatingReplicas == 0 + }, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: DeadPrimaryAndSomeReplicas, + Description: "Primary cannot be reached by vtorc; some of its replicas are unreachable and none of its reachable replicas is replicating", + Priority: detectionAnalysisPriorityShardWideAction, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return a.IsClusterPrimary && !a.LastCheckValid && a.CountValidReplicas < a.CountReplicas && a.CountValidReplicas > 0 && a.CountValidReplicatingReplicas == 0 + }, + }, + + // PrimaryHasPrimary + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: PrimaryHasPrimary, + Description: "Primary is replicating from somewhere else", + Priority: detectionAnalysisPriorityShardWideAction, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return a.IsClusterPrimary && !a.IsPrimary + }, + }, + + // MySQL read-only checks + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: PrimaryIsReadOnly, + Description: "Primary is read-only", + Priority: detectionAnalysisPriorityHigh, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return a.IsClusterPrimary && a.IsReadOnly + }, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: ReplicaIsWritable, + Description: "Replica is writable", + Priority: detectionAnalysisPriorityMedium, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return topo.IsReplicaType(a.TabletType) && !a.IsReadOnly + }, + }, + + // Semi-sync checks + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: PrimarySemiSyncMustBeSet, + Description: "Primary semi-sync must be set", + Priority: detectionAnalysisPriorityMedium, + }, + AfterAnalyses: []AnalysisCode{ReplicaSemiSyncMustBeSet}, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + if !hasMinSemiSyncAckers(ca.durability, primary, a) { + return false + } + return a.IsClusterPrimary && policy.SemiSyncAckers(ca.durability, tablet) != 0 && !a.SemiSyncPrimaryEnabled + }, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: PrimarySemiSyncMustNotBeSet, + Description: "Primary semi-sync must not be set", + Priority: detectionAnalysisPriorityMedium, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return a.IsClusterPrimary && policy.SemiSyncAckers(ca.durability, tablet) == 0 && a.SemiSyncPrimaryEnabled + }, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: ReplicaSemiSyncMustBeSet, + Description: "Replica semi-sync must be set", + Priority: detectionAnalysisPriorityMedium, + }, + BeforeAnalyses: []AnalysisCode{PrimarySemiSyncMustBeSet}, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return topo.IsReplicaType(a.TabletType) && !a.IsPrimary && policy.IsReplicaSemiSync(ca.durability, primary, tablet) && !a.SemiSyncReplicaEnabled + }, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: ReplicaSemiSyncMustNotBeSet, + Description: "Replica semi-sync must not be set", + Priority: detectionAnalysisPriorityMedium, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return topo.IsReplicaType(a.TabletType) && !a.IsPrimary && !policy.IsReplicaSemiSync(ca.durability, primary, tablet) && a.SemiSyncReplicaEnabled + }, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: PrimarySemiSyncBlocked, + Description: "Writes seem to be blocked on semi-sync acks on the primary, even though sufficient replicas are configured to send ACKs", + Priority: detectionAnalysisPriorityShardWideAction, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return a.IsClusterPrimary && a.IsPrimary && a.SemiSyncBlocked && a.CountSemiSyncReplicasEnabled >= a.SemiSyncPrimaryWaitForReplicaCount + }, + }, + + // Primary tablet type checks + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: PrimaryCurrentTypeMismatch, + Description: "Primary tablet's current type is not PRIMARY", + Priority: detectionAnalysisPriorityMedium, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return a.IsClusterPrimary && a.CurrentTabletType != topodatapb.TabletType_UNKNOWN && a.CurrentTabletType != topodatapb.TabletType_PRIMARY + }, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: StaleTopoPrimary, + Description: "Primary tablet is stale, older than current primary", + Priority: detectionAnalysisPriorityHigh, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return isStaleTopoPrimary(a, ca) + }, + }, + + // Errant GTID + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: ErrantGTIDDetected, + Description: "Tablet has errant GTIDs", + Priority: detectionAnalysisPriorityMedium, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return topo.IsReplicaType(a.TabletType) && a.ErrantGTID != "" + }, + }, + + // Cluster primary checks + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: ClusterHasNoPrimary, + Description: "Cluster has no primary", + Priority: detectionAnalysisPriorityShardWideAction, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return topo.IsReplicaType(a.TabletType) && ca.primaryAlias == "" && a.ShardPrimaryTermTimestamp == "" + }, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: PrimaryTabletDeleted, + Description: "Primary tablet has been deleted", + Priority: detectionAnalysisPriorityShardWideAction, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return topo.IsReplicaType(a.TabletType) && ca.primaryAlias == "" && a.ShardPrimaryTermTimestamp != "" + }, + }, + + // Replica connectivity checks + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: NotConnectedToPrimary, + Description: "Not connected to the primary", + Priority: detectionAnalysisPriorityMedium, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return topo.IsReplicaType(a.TabletType) && a.IsPrimary + }, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: ReplicaMisconfigured, + Description: "Replica has been misconfigured", + Priority: detectionAnalysisPriorityMedium, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return topo.IsReplicaType(a.TabletType) && !a.IsPrimary && math.Round(a.HeartbeatInterval*2) != float64(a.ReplicaNetTimeout) + }, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: ConnectedToWrongPrimary, + Description: "Connected to wrong primary", + Priority: detectionAnalysisPriorityMedium, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return topo.IsReplicaType(a.TabletType) && !a.IsPrimary && ca.primaryAlias != "" && a.AnalyzedInstancePrimaryAlias != ca.primaryAlias + }, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: ReplicationStopped, + Description: "Replication is stopped", + Priority: detectionAnalysisPriorityMedium, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return topo.IsReplicaType(a.TabletType) && !a.IsPrimary && a.ReplicationStopped + }, + }, + + // Unreachable primary checks + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: UnreachablePrimaryWithLaggingReplicas, + Description: "Primary cannot be reached by vtorc and all of its replicas are lagging", + Priority: detectionAnalysisPriorityMedium, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return a.IsPrimary && !a.LastCheckValid && a.CountLaggingReplicas == a.CountReplicas && a.CountDelayedReplicas < a.CountReplicas && a.CountValidReplicatingReplicas > 0 + }, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: UnreachablePrimary, + Description: "Primary cannot be reached by vtorc but all of its replicas seem to be replicating; possibly a network/host issue", + Priority: detectionAnalysisPriorityMedium, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return a.IsPrimary && !a.LastCheckValid && !a.LastCheckPartialSuccess && a.CountValidReplicas > 0 && a.CountValidReplicatingReplicas == a.CountValidReplicas + }, + }, + // Locked semi-sync primary + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: LockedSemiSyncPrimary, + Description: "Semi sync primary is locked since it doesn't get enough replica acknowledgements", + Priority: detectionAnalysisPriorityMedium, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return a.IsPrimary && a.SemiSyncPrimaryEnabled && a.SemiSyncPrimaryStatus && a.SemiSyncPrimaryWaitForReplicaCount > 0 && a.SemiSyncPrimaryClients < a.SemiSyncPrimaryWaitForReplicaCount && isStaleBinlogCoordinates + }, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: LockedSemiSyncPrimaryHypothesis, + Description: "Semi sync primary seems to be locked, more samplings needed to validate", + Priority: detectionAnalysisPriorityMedium, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return a.IsPrimary && a.SemiSyncPrimaryEnabled && a.SemiSyncPrimaryStatus && a.SemiSyncPrimaryWaitForReplicaCount > 0 && a.SemiSyncPrimaryClients < a.SemiSyncPrimaryWaitForReplicaCount && !isStaleBinlogCoordinates + }, + }, + + // Primary replica health checks + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: PrimarySingleReplicaNotReplicating, + Description: "Primary is reachable but its single replica is not replicating", + Priority: detectionAnalysisPriorityMedium, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return a.IsPrimary && a.LastCheckValid && a.CountReplicas == 1 && a.CountValidReplicas == a.CountReplicas && a.CountValidReplicatingReplicas == 0 + }, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: PrimarySingleReplicaDead, + Description: "Primary is reachable but its single replica is dead", + Priority: detectionAnalysisPriorityMedium, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return a.IsPrimary && a.LastCheckValid && a.CountReplicas == 1 && a.CountValidReplicas == 0 + }, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: AllPrimaryReplicasNotReplicating, + Description: "Primary is reachable but none of its replicas is replicating", + Priority: detectionAnalysisPriorityLow, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return a.IsPrimary && a.LastCheckValid && a.CountReplicas > 1 && a.CountValidReplicas == a.CountReplicas && a.CountValidReplicatingReplicas == 0 + }, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: AllPrimaryReplicasNotReplicatingOrDead, + Description: "Primary is reachable but none of its replicas is replicating", + Priority: detectionAnalysisPriorityLow, + }, + MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { + return a.IsPrimary && a.LastCheckValid && a.CountReplicas > 1 && a.CountValidReplicas < a.CountReplicas && a.CountValidReplicas > 0 && a.CountValidReplicatingReplicas == 0 + }, + }, +} + +func sortDetectionAnalysisMatchedProblems(allProblems []*DetectionAnalysisProblem) { + // use slices.SortStableFunc because it keeps the original order of equal elements. + slices.SortStableFunc(allProblems, compareDetectionAnalysisProblems) +} + +// compareDetectionAnalysisProblems compares two DetectionAnalysisProblems using +// the same logic as sortDetectionAnalysisMatchedProblems. +func compareDetectionAnalysisProblems(a, b *DetectionAnalysisProblem) int { + if a.Meta == nil || b.Meta == nil { + return 0 + } + + // handle before/after dependencies + aAnalysis := a.Meta.Analysis + bAnalysis := b.Meta.Analysis + if slices.Contains(b.BeforeAnalyses, aAnalysis) || slices.Contains(a.AfterAnalyses, bAnalysis) { + return 1 + } + if slices.Contains(a.BeforeAnalyses, bAnalysis) || slices.Contains(b.AfterAnalyses, aAnalysis) { + return -1 + } + + // effective priority (lower is better). + aPriority := a.GetPriority() + bPriority := b.GetPriority() + switch { + case aPriority > bPriority: + return 1 + case aPriority < bPriority: + return -1 + } + + return 0 +} + +// sortDetectionAnalyses sorts a slice of DetectionAnalysis by looking up each +// entry's Analysis code in detectionAnalysisProblems and comparing using the +// same priority/dependency logic as sortDetectionAnalysisMatchedProblems. +func sortDetectionAnalyses(analyses []*DetectionAnalysis) { + slices.SortStableFunc(analyses, func(a, b *DetectionAnalysis) int { + aProblem := GetDetectionAnalysisProblem(a.Analysis) + bProblem := GetDetectionAnalysisProblem(b.Analysis) + if aProblem == nil || bProblem == nil { + return 0 + } + return compareDetectionAnalysisProblems(aProblem, bProblem) + }) +} + +// GroupDetectionAnalysesByShard groups a slice of DetectionAnalysis by shard key +// (topoproto.KeyspaceShardString) and sorts each group by priority. +func GroupDetectionAnalysesByShard(analyses []*DetectionAnalysis) map[string][]*DetectionAnalysis { + result := make(map[string][]*DetectionAnalysis) + for _, a := range analyses { + key := topoproto.KeyspaceShardString(a.AnalyzedKeyspace, a.AnalyzedShard) + result[key] = append(result[key], a) + } + for _, group := range result { + sortDetectionAnalyses(group) + } + return result +} diff --git a/go/vt/vtorc/inst/analysis_problem_test.go b/go/vt/vtorc/inst/analysis_problem_test.go new file mode 100644 index 00000000000..536d763bb8c --- /dev/null +++ b/go/vt/vtorc/inst/analysis_problem_test.go @@ -0,0 +1,257 @@ +/* +Copyright 2026 The Vitess Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package inst + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" +) + +func TestSortDetectionAnalysisMatchedProblems(t *testing.T) { + worstPriority := 10 + testCases := []struct { + name string + in []*DetectionAnalysisProblem + postSortByAnalysis []AnalysisCode + }{ + { + name: "default", + in: []*DetectionAnalysisProblem{ + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: InvalidReplica, + Description: "should be 2nd-last, not a shardWideAction, low priority", + Priority: detectionAnalysisPriorityLow, + }, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: InvalidReplica, + Description: "should be last, not a shardWideAction, worst priority", + Priority: worstPriority, + }, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: PrimaryIsReadOnly, + Description: "should be after DeadPrimary, high priority", + Priority: detectionAnalysisPriorityHigh, + }, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: PrimarySemiSyncMustBeSet, + Description: "should be after ReplicaSemiSyncMustBeSet, has an after dependency", + Priority: detectionAnalysisPriorityMedium, + }, + AfterAnalyses: []AnalysisCode{ReplicaSemiSyncMustBeSet}, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: ReplicaSemiSyncMustBeSet, + Description: "should be before PrimarySemiSyncMustBeSet, has a before dependency", + Priority: detectionAnalysisPriorityMedium, + }, + BeforeAnalyses: []AnalysisCode{PrimarySemiSyncMustBeSet}, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: DeadPrimary, + Description: "should be 1st, shard-wide action priority", + Priority: detectionAnalysisPriorityShardWideAction, + }, + }, + }, + postSortByAnalysis: []AnalysisCode{ + DeadPrimary, + PrimaryIsReadOnly, + ReplicaSemiSyncMustBeSet, + PrimarySemiSyncMustBeSet, + InvalidReplica, + InvalidReplica, + }, + }, + } + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + sorted := testCase.in + sortDetectionAnalysisMatchedProblems(sorted) + + require.Len(t, sorted, len(testCase.postSortByAnalysis)) + for i, analysis := range testCase.postSortByAnalysis { + assert.Equal(t, analysis, sorted[i].Meta.Analysis) + } + + // confirm last problem has the worstPriority + require.Equal(t, worstPriority, sorted[len(sorted)-1].Meta.Priority) + }) + } +} + +func TestRequiresOrderedExecution(t *testing.T) { + tests := []struct { + name string + problem *DetectionAnalysisProblem + expected bool + }{ + { + name: "shard-wide action priority", + problem: &DetectionAnalysisProblem{ + Meta: &DetectionAnalysisProblemMeta{Priority: detectionAnalysisPriorityShardWideAction}, + }, + expected: true, + }, + { + name: "critical priority", + problem: &DetectionAnalysisProblem{ + Meta: &DetectionAnalysisProblemMeta{Priority: detectionAnalysisPriorityCritical}, + }, + expected: false, + }, + { + name: "has BeforeAnalyses", + problem: &DetectionAnalysisProblem{ + Meta: &DetectionAnalysisProblemMeta{}, + BeforeAnalyses: []AnalysisCode{DeadPrimary}, + }, + expected: true, + }, + { + name: "has AfterAnalyses", + problem: &DetectionAnalysisProblem{ + Meta: &DetectionAnalysisProblemMeta{}, + AfterAnalyses: []AnalysisCode{DeadPrimary}, + }, + expected: true, + }, + { + name: "independent problem", + problem: &DetectionAnalysisProblem{ + Meta: &DetectionAnalysisProblemMeta{Priority: detectionAnalysisPriorityLow}, + }, + expected: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.expected, tt.problem.RequiresOrderedExecution()) + }) + } +} + +func TestGetDetectionAnalysisProblem(t *testing.T) { + problem := GetDetectionAnalysisProblem(DeadPrimary) + require.NotNil(t, problem) + assert.Equal(t, DeadPrimary, problem.Meta.Analysis) + + problem = GetDetectionAnalysisProblem("NonExistentCode") + assert.Nil(t, problem) +} + +func TestCompareDetectionAnalysisProblems(t *testing.T) { + tests := []struct { + name string + a, b *DetectionAnalysisProblem + expected int + }{ + { + name: "shard-wide action beats non-shard-wide", + a: &DetectionAnalysisProblem{ + Meta: &DetectionAnalysisProblemMeta{Priority: detectionAnalysisPriorityShardWideAction}, + }, + b: &DetectionAnalysisProblem{ + Meta: &DetectionAnalysisProblemMeta{Priority: detectionAnalysisPriorityHigh}, + }, + expected: -1, + }, + { + name: "higher priority wins", + a: &DetectionAnalysisProblem{ + Meta: &DetectionAnalysisProblemMeta{Priority: detectionAnalysisPriorityHigh}, + }, + b: &DetectionAnalysisProblem{ + Meta: &DetectionAnalysisProblemMeta{Priority: detectionAnalysisPriorityLow}, + }, + expected: -1, + }, + { + name: "equal priority", + a: &DetectionAnalysisProblem{ + Meta: &DetectionAnalysisProblemMeta{Priority: detectionAnalysisPriorityMedium}, + }, + b: &DetectionAnalysisProblem{ + Meta: &DetectionAnalysisProblemMeta{Priority: detectionAnalysisPriorityMedium}, + }, + expected: 0, + }, + { + name: "before dependency", + a: &DetectionAnalysisProblem{ + Meta: &DetectionAnalysisProblemMeta{Analysis: ReplicaSemiSyncMustBeSet}, + BeforeAnalyses: []AnalysisCode{PrimarySemiSyncMustBeSet}, + }, + b: &DetectionAnalysisProblem{ + Meta: &DetectionAnalysisProblemMeta{Analysis: PrimarySemiSyncMustBeSet}, + }, + expected: -1, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.expected, compareDetectionAnalysisProblems(tt.a, tt.b)) + }) + } +} + +func TestGroupDetectionAnalysesByShard(t *testing.T) { + analyses := []*DetectionAnalysis{ + { + Analysis: ReplicationStopped, + AnalyzedKeyspace: "ks1", + AnalyzedShard: "0", + TabletType: topodatapb.TabletType_REPLICA, + }, + { + Analysis: DeadPrimary, + AnalyzedKeyspace: "ks1", + AnalyzedShard: "0", + TabletType: topodatapb.TabletType_PRIMARY, + }, + { + Analysis: PrimaryIsReadOnly, + AnalyzedKeyspace: "ks2", + AnalyzedShard: "0", + TabletType: topodatapb.TabletType_PRIMARY, + }, + } + + result := GroupDetectionAnalysesByShard(analyses) + + require.Len(t, result, 2) + + // ks1/0 should have 2 entries, sorted with DeadPrimary first + ks1 := result["ks1/0"] + require.Len(t, ks1, 2) + assert.Equal(t, DeadPrimary, ks1[0].Analysis) + assert.Equal(t, ReplicationStopped, ks1[1].Analysis) + + // ks2/0 should have 1 entry + ks2 := result["ks2/0"] + require.Len(t, ks2, 1) + assert.Equal(t, PrimaryIsReadOnly, ks2[0].Analysis) +} diff --git a/go/vt/vtorc/inst/analysis_test.go b/go/vt/vtorc/inst/analysis_test.go new file mode 100644 index 00000000000..60aaeb790d0 --- /dev/null +++ b/go/vt/vtorc/inst/analysis_test.go @@ -0,0 +1,70 @@ +/* +Copyright 2026 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package inst + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" +) + +func TestHasMinSemiSyncAckers(t *testing.T) { + durablerNone, _ := policy.GetDurabilityPolicy("none") + durablerCrossCell, _ := policy.GetDurabilityPolicy("cross_cell") + tablet := &topodatapb.Tablet{Keyspace: t.Name(), Shard: "-"} + + testCases := []struct { + name string + durabler policy.Durabler + analysis *DetectionAnalysis + expect bool + }{ + { + name: "durability policy none", + analysis: &DetectionAnalysis{ + CountValidSemiSyncReplicatingReplicas: 0, + }, + durabler: durablerNone, + expect: true, + }, + { + name: "durability policy cross_cell without min ackers", + durabler: durablerCrossCell, + analysis: &DetectionAnalysis{ + CountValidSemiSyncReplicatingReplicas: 0, + }, + expect: false, + }, + { + name: "durability policy cross_cell with min ackers", + durabler: durablerCrossCell, + analysis: &DetectionAnalysis{ + CountValidSemiSyncReplicatingReplicas: uint(durablerCrossCell.SemiSyncAckers(tablet)), + }, + expect: true, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + assert.Equal(t, testCase.expect, hasMinSemiSyncAckers(testCase.durabler, tablet, testCase.analysis)) + }) + } +} diff --git a/go/vt/vtorc/logic/topology_recovery.go b/go/vt/vtorc/logic/topology_recovery.go index 60dc40e11e4..77355d00a72 100644 --- a/go/vt/vtorc/logic/topology_recovery.go +++ b/go/vt/vtorc/logic/topology_recovery.go @@ -21,7 +21,10 @@ import ( "encoding/json" "errors" "fmt" + "maps" "math/rand/v2" + "slices" + "sync" "sync/atomic" "time" @@ -120,7 +123,7 @@ const ( // TopologyRecovery represents an entry in the topology_recovery table type TopologyRecovery struct { ID int64 - AnalysisEntry inst.ReplicationAnalysis + AnalysisEntry inst.DetectionAnalysis SuccessorAlias string IsSuccessful bool AllErrors []string @@ -129,9 +132,9 @@ type TopologyRecovery struct { DetectionID int64 } -func NewTopologyRecovery(replicationAnalysis inst.ReplicationAnalysis) *TopologyRecovery { +func NewTopologyRecovery(detectionAnalysis inst.DetectionAnalysis) *TopologyRecovery { topologyRecovery := &TopologyRecovery{} - topologyRecovery.AnalysisEntry = replicationAnalysis + topologyRecovery.AnalysisEntry = detectionAnalysis topologyRecovery.AllErrors = []string{} return topologyRecovery } @@ -234,7 +237,7 @@ func resolveRecovery(topologyRecovery *TopologyRecovery, successorInstance *inst } // recoverPrimaryHasPrimary resets the replication on the primary instance -func recoverPrimaryHasPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { +func recoverPrimaryHasPrimary(ctx context.Context, analysisEntry *inst.DetectionAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { topologyRecovery, err = AttemptRecoveryRegistration(analysisEntry) if topologyRecovery == nil { message := fmt.Sprintf("found an active or recent recovery on %+v. Will not issue another fixPrimaryHasPrimary.", analysisEntry.AnalyzedInstanceAlias) @@ -265,7 +268,7 @@ func recoverPrimaryHasPrimary(ctx context.Context, analysisEntry *inst.Replicati // runEmergencyReparentOp runs a recovery for which we have to run ERS. Here waitForAllTablets is a boolean telling ERS whether it should wait for all the tablets // or is it okay to skip 1. -func runEmergencyReparentOp(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, recoveryName string, waitForAllTablets bool, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { +func runEmergencyReparentOp(ctx context.Context, analysisEntry *inst.DetectionAnalysis, recoveryName string, waitForAllTablets bool, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { // Read the tablet information from the database to find the shard and keyspace of the tablet tablet, err := inst.ReadTablet(analysisEntry.AnalyzedInstanceAlias) if err != nil { @@ -326,16 +329,16 @@ func runEmergencyReparentOp(ctx context.Context, analysisEntry *inst.Replication // recoverDeadPrimary checks a given analysis, decides whether to take action, and possibly takes action // Returns true when action was taken. -func recoverDeadPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { +func recoverDeadPrimary(ctx context.Context, analysisEntry *inst.DetectionAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { return runEmergencyReparentOp(ctx, analysisEntry, "RecoverDeadPrimary", false, logger) } // recoverPrimaryTabletDeleted tries to run a recovery for the case where the primary tablet has been deleted. -func recoverPrimaryTabletDeleted(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { +func recoverPrimaryTabletDeleted(ctx context.Context, analysisEntry *inst.DetectionAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { return runEmergencyReparentOp(ctx, analysisEntry, "PrimaryTabletDeleted", true, logger) } -func postErsCompletion(topologyRecovery *TopologyRecovery, analysisEntry *inst.ReplicationAnalysis, recoveryName string, promotedReplica *inst.Instance) { +func postErsCompletion(topologyRecovery *TopologyRecovery, analysisEntry *inst.DetectionAnalysis, recoveryName string, promotedReplica *inst.Instance) { if promotedReplica != nil { message := fmt.Sprintf("promoted replica: %+v", promotedReplica.InstanceAlias) _ = AuditTopologyRecovery(topologyRecovery, message) @@ -345,13 +348,13 @@ func postErsCompletion(topologyRecovery *TopologyRecovery, analysisEntry *inst.R } // checkAndRecoverGenericProblem is a general-purpose recovery function -func checkAndRecoverLockedSemiSyncPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { +func checkAndRecoverLockedSemiSyncPrimary(ctx context.Context, analysisEntry *inst.DetectionAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { logger.Warning("No actions in checkAndRecoverLockedSemiSyncPrimary") return false, nil, nil } // checkAndRecoverGenericProblem is a general-purpose recovery function -func checkAndRecoverGenericProblem(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (bool, *TopologyRecovery, error) { +func checkAndRecoverGenericProblem(ctx context.Context, analysisEntry *inst.DetectionAnalysis, logger *log.PrefixedLogger) (bool, *TopologyRecovery, error) { logger.Warning("No actions in checkAndRecoverGenericProblem") return false, nil, nil } @@ -446,7 +449,7 @@ func hasActionableRecovery(recoveryFunctionCode recoveryFunction) bool { // getCheckAndRecoverFunction gets the recovery function for the given code. func getCheckAndRecoverFunction(recoveryFunctionCode recoveryFunction) ( - checkAndRecoverFunction func(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error), + checkAndRecoverFunction func(ctx context.Context, analysisEntry *inst.DetectionAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error), ) { switch recoveryFunctionCode { case noRecoveryFunc: @@ -518,7 +521,7 @@ func isClusterWideRecovery(recoveryFunctionCode recoveryFunction) bool { } // analysisEntriesHaveSameRecovery tells whether the two analysis entries have the same recovery function or not -func analysisEntriesHaveSameRecovery(prevAnalysis, newAnalysis *inst.ReplicationAnalysis) bool { +func analysisEntriesHaveSameRecovery(prevAnalysis, newAnalysis *inst.DetectionAnalysis) bool { prevRecoveryFunctionCode := getCheckAndRecoverFunctionCode(prevAnalysis.Analysis, prevAnalysis.AnalyzedInstanceAlias) newRecoveryFunctionCode := getCheckAndRecoverFunctionCode(newAnalysis.Analysis, newAnalysis.AnalyzedInstanceAlias) return prevRecoveryFunctionCode == newRecoveryFunctionCode @@ -526,7 +529,7 @@ func analysisEntriesHaveSameRecovery(prevAnalysis, newAnalysis *inst.Replication // executeCheckAndRecoverFunction will choose the correct check & recovery function based on analysis. // It executes the function synchronously -func executeCheckAndRecoverFunction(analysisEntry *inst.ReplicationAnalysis) (err error) { +func executeCheckAndRecoverFunction(analysisEntry *inst.DetectionAnalysis) (err error) { countPendingRecoveries.Add(1) defer countPendingRecoveries.Add(-1) @@ -694,9 +697,9 @@ func executeCheckAndRecoverFunction(analysisEntry *inst.ReplicationAnalysis) (er } // checkIfAlreadyFixed checks whether the problem that the analysis entry represents has already been fixed by another agent or not -func checkIfAlreadyFixed(analysisEntry *inst.ReplicationAnalysis) (bool, error) { +func checkIfAlreadyFixed(analysisEntry *inst.DetectionAnalysis) (bool, error) { // Run a replication analysis again. We will check if the problem persisted - analysisEntries, err := inst.GetReplicationAnalysis(analysisEntry.ClusterDetails.Keyspace, analysisEntry.ClusterDetails.Shard, &inst.ReplicationAnalysisHints{}) + analysisEntries, err := inst.GetDetectionAnalysis(analysisEntry.ClusterDetails.Keyspace, analysisEntry.ClusterDetails.Shard, &inst.DetectionAnalysisHints{}) if err != nil { return false, err } @@ -712,31 +715,63 @@ func checkIfAlreadyFixed(analysisEntry *inst.ReplicationAnalysis) (bool, error) return true, nil } +// recoverShardAnalyses executes recoveries for a shard's analyses. Analyses +// that require ordered execution run sequentially first, then the remaining +// independent analyses fan out concurrently. +func recoverShardAnalyses(analyses []*inst.DetectionAnalysis, recoverFunc func(*inst.DetectionAnalysis) error) { + var concurrent []*inst.DetectionAnalysis + for _, analysisEntry := range analyses { + problem := inst.GetDetectionAnalysisProblem(analysisEntry.Analysis) + if problem != nil && problem.RequiresOrderedExecution() { + if err := recoverFunc(analysisEntry); err != nil { + log.Error(fmt.Sprintf("Failed to execute CheckAndRecover function: %+v", err)) + } + } else { + concurrent = append(concurrent, analysisEntry) + } + } + var wg sync.WaitGroup + for _, analysisEntry := range concurrent { + wg.Add(1) + go func() { + defer wg.Done() + if err := recoverFunc(analysisEntry); err != nil { + log.Error(fmt.Sprintf("Failed to execute CheckAndRecover function: %+v", err)) + } + }() + } + wg.Wait() +} + // CheckAndRecover is the main entry point for the recovery mechanism func CheckAndRecover() { // Allow the analysis to run even if we don't want to recover - replicationAnalysis, err := inst.GetReplicationAnalysis("", "", &inst.ReplicationAnalysisHints{AuditAnalysis: true}) + detectionAnalysis, err := inst.GetDetectionAnalysis("", "", &inst.DetectionAnalysisHints{AuditAnalysis: true}) if err != nil { log.Error(err) return } + analysisByShard := inst.GroupDetectionAnalysesByShard(detectionAnalysis) + // Regardless of if the problem is solved or not we want to monitor active // issues, we use a map of labels and set a counter to `1` for each problem // then we reset any counter that is not present in the current analysis. active := make(map[string]struct{}) - for _, e := range replicationAnalysis { - if e.Analysis != inst.NoProblem { - names := [...]string{ - string(e.Analysis), - e.AnalyzedInstanceAlias, - e.AnalyzedKeyspace, - e.AnalyzedShard, + for _, shardAnalyses := range analysisByShard { + for _, e := range shardAnalyses { + if e.Analysis != inst.NoProblem { + names := [...]string{ + string(e.Analysis), + e.AnalyzedInstanceAlias, + e.AnalyzedKeyspace, + e.AnalyzedShard, + } + + key := detectedProblems.GetLabelName(names[:]...) + active[key] = struct{}{} + detectedProblems.Set(names[:], 1) } - - key := detectedProblems.GetLabelName(names[:]...) - active[key] = struct{}{} - detectedProblems.Set(names[:], 1) } } @@ -747,19 +782,23 @@ func CheckAndRecover() { } } - // intentionally iterating entries in random order - for _, j := range rand.Perm(len(replicationAnalysis)) { - analysisEntry := replicationAnalysis[j] - + // Shuffle shard keys to ensure random processing order. Randomness helps reduce + // global shard lock contention when many VTOrcs watch the same shard(s). Within + // each shard, analyses are sorted by priority. Problems that require ordered + // execution (shard-wide actions or those with Before/After dependencies) run + // sequentially first, then independent problems fan out concurrently. + shardKeys := slices.Collect(maps.Keys(analysisByShard)) + rand.Shuffle(len(shardKeys), func(i, j int) { + shardKeys[i], shardKeys[j] = shardKeys[j], shardKeys[i] + }) + for _, key := range shardKeys { go func() { - if err := executeCheckAndRecoverFunction(analysisEntry); err != nil { - log.Error(err) - } + recoverShardAnalyses(analysisByShard[key], executeCheckAndRecoverFunction) }() } } -func postPrsCompletion(topologyRecovery *TopologyRecovery, analysisEntry *inst.ReplicationAnalysis, promotedReplica *inst.Instance) { +func postPrsCompletion(topologyRecovery *TopologyRecovery, analysisEntry *inst.DetectionAnalysis, promotedReplica *inst.Instance) { if promotedReplica != nil { message := fmt.Sprintf("promoted replica: %+v", promotedReplica.InstanceAlias) _ = AuditTopologyRecovery(topologyRecovery, message) @@ -769,7 +808,7 @@ func postPrsCompletion(topologyRecovery *TopologyRecovery, analysisEntry *inst.R } // electNewPrimary elects a new primary while none were present before. -func electNewPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { +func electNewPrimary(ctx context.Context, analysisEntry *inst.DetectionAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { topologyRecovery, err = AttemptRecoveryRegistration(analysisEntry) if topologyRecovery == nil || err != nil { message := fmt.Sprintf("found an active or recent recovery on %+v. Will not issue another electNewPrimary.", analysisEntry.AnalyzedInstanceAlias) @@ -823,7 +862,7 @@ func electNewPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysi } // fixPrimary sets the primary as read-write. -func fixPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { +func fixPrimary(ctx context.Context, analysisEntry *inst.DetectionAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { topologyRecovery, err = AttemptRecoveryRegistration(analysisEntry) if topologyRecovery == nil { message := fmt.Sprintf("found an active or recent recovery on %+v. Will not issue another fixPrimary.", analysisEntry.AnalyzedInstanceAlias) @@ -859,7 +898,7 @@ func fixPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, lo } // fixReplica sets the replica as read-only and points it at the current primary. -func fixReplica(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { +func fixReplica(ctx context.Context, analysisEntry *inst.DetectionAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { topologyRecovery, err = AttemptRecoveryRegistration(analysisEntry) if topologyRecovery == nil { message := fmt.Sprintf("found an active or recent recovery on %+v. Will not issue another fixReplica.", analysisEntry.AnalyzedInstanceAlias) @@ -907,7 +946,7 @@ func fixReplica(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, lo // demoteStaleTopoPrimary demotes a tablet that has a stale type of PRIMARY in the topology when a newer primary has // been elected. It demotes the tablet, updates its type to REPLICA in the topology, and sets its replication source // to the current primary. -func demoteStaleTopoPrimary(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { +func demoteStaleTopoPrimary(ctx context.Context, analysisEntry *inst.DetectionAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { alias := analysisEntry.AnalyzedInstanceAlias // Register the recovery before touching topology so multiple VTOrc instances do not race the demotion. @@ -978,7 +1017,7 @@ func forceDemotePrimary(ctx context.Context, tablet *topodatapb.Tablet) (*replic } // recoverErrantGTIDDetected changes the tablet type of a replica tablet that has errant GTIDs. -func recoverErrantGTIDDetected(ctx context.Context, analysisEntry *inst.ReplicationAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { +func recoverErrantGTIDDetected(ctx context.Context, analysisEntry *inst.DetectionAnalysis, logger *log.PrefixedLogger) (recoveryAttempted bool, topologyRecovery *TopologyRecovery, err error) { topologyRecovery, err = AttemptRecoveryRegistration(analysisEntry) if topologyRecovery == nil { message := fmt.Sprintf("found an active or recent recovery on %+v. Will not issue another recoverErrantGTIDDetected.", analysisEntry.AnalyzedInstanceAlias) diff --git a/go/vt/vtorc/logic/topology_recovery_dao.go b/go/vt/vtorc/logic/topology_recovery_dao.go index 137251c4fc8..ff6cf3755bb 100644 --- a/go/vt/vtorc/logic/topology_recovery_dao.go +++ b/go/vt/vtorc/logic/topology_recovery_dao.go @@ -29,7 +29,7 @@ import ( ) // InsertRecoveryDetection inserts the recovery analysis that has been detected. -func InsertRecoveryDetection(analysisEntry *inst.ReplicationAnalysis) error { +func InsertRecoveryDetection(analysisEntry *inst.DetectionAnalysis) error { sqlResult, err := db.ExecVTOrc(`INSERT OR IGNORE INTO recovery_detection ( alias, @@ -109,7 +109,7 @@ func writeTopologyRecovery(topologyRecovery *TopologyRecovery) (*TopologyRecover } // AttemptRecoveryRegistration tries to add a recovery entry; if this fails that means recovery is already in place. -func AttemptRecoveryRegistration(analysisEntry *inst.ReplicationAnalysis) (*TopologyRecovery, error) { +func AttemptRecoveryRegistration(analysisEntry *inst.DetectionAnalysis) (*TopologyRecovery, error) { // Check if there is an active recovery in progress for the cluster of the given instance. recoveries, err := ReadActiveClusterRecoveries(analysisEntry.ClusterDetails.Keyspace, analysisEntry.ClusterDetails.Shard) if err != nil { @@ -180,7 +180,7 @@ func readRecoveries(whereCondition string, limit string, args []any) ([]*Topolog limit, ) err := db.QueryVTOrc(query, args, func(m sqlutils.RowMap) error { - topologyRecovery := *NewTopologyRecovery(inst.ReplicationAnalysis{}) + topologyRecovery := *NewTopologyRecovery(inst.DetectionAnalysis{}) topologyRecovery.ID = m.GetInt64("recovery_id") topologyRecovery.RecoveryStartTimestamp = m.GetString("start_recovery") diff --git a/go/vt/vtorc/logic/topology_recovery_dao_test.go b/go/vt/vtorc/logic/topology_recovery_dao_test.go index 6a1d7c4c48f..a84c2bb1fca 100644 --- a/go/vt/vtorc/logic/topology_recovery_dao_test.go +++ b/go/vt/vtorc/logic/topology_recovery_dao_test.go @@ -39,7 +39,7 @@ func TestTopologyRecovery(t *testing.T) { require.NoError(t, err) }() - replicationAnalysis := inst.ReplicationAnalysis{ + detectionAnalysis := inst.DetectionAnalysis{ AnalyzedInstanceAlias: "zone1-0000000101", TabletType: tab101.Type, ClusterDetails: inst.ClusterInfo{ @@ -51,7 +51,7 @@ func TestTopologyRecovery(t *testing.T) { Analysis: inst.ReplicaIsWritable, IsReadOnly: false, } - topologyRecovery := NewTopologyRecovery(replicationAnalysis) + topologyRecovery := NewTopologyRecovery(detectionAnalysis) t.Run("writing to topology recovery", func(t *testing.T) { topologyRecovery, err = writeTopologyRecovery(topologyRecovery) @@ -142,7 +142,7 @@ func TestInsertRecoveryDetection(t *testing.T) { defer func() { db.ClearVTOrcDatabase() }() - ra := &inst.ReplicationAnalysis{ + ra := &inst.DetectionAnalysis{ AnalyzedInstanceAlias: "alias-1", Analysis: inst.ClusterHasNoPrimary, ClusterDetails: inst.ClusterInfo{ diff --git a/go/vt/vtorc/logic/topology_recovery_test.go b/go/vt/vtorc/logic/topology_recovery_test.go index de9ecd02848..069b5225074 100644 --- a/go/vt/vtorc/logic/topology_recovery_test.go +++ b/go/vt/vtorc/logic/topology_recovery_test.go @@ -18,6 +18,7 @@ package logic import ( "context" + "sync" "testing" "vitess.io/vitess/go/vt/log" @@ -105,7 +106,7 @@ func TestAnalysisEntriesHaveSameRecovery(t *testing.T) { t.Parallel() for _, tt := range tests { t.Run(string(tt.prevAnalysisCode)+","+string(tt.newAnalysisCode), func(t *testing.T) { - res := analysisEntriesHaveSameRecovery(&inst.ReplicationAnalysis{Analysis: tt.prevAnalysisCode}, &inst.ReplicationAnalysis{Analysis: tt.newAnalysisCode}) + res := analysisEntriesHaveSameRecovery(&inst.DetectionAnalysis{Analysis: tt.prevAnalysisCode}, &inst.DetectionAnalysis{Analysis: tt.newAnalysisCode}) require.Equal(t, tt.shouldBeEqual, res) }) } @@ -135,7 +136,7 @@ func TestElectNewPrimaryPanic(t *testing.T) { } err = inst.SaveTablet(tablet) require.NoError(t, err) - analysisEntry := &inst.ReplicationAnalysis{ + analysisEntry := &inst.DetectionAnalysis{ AnalyzedInstanceAlias: topoproto.TabletAliasString(tablet.Alias), } ctx, cancel := context.WithCancel(context.Background()) @@ -185,11 +186,11 @@ func TestRecoveryRegistration(t *testing.T) { require.NoError(t, err) err = inst.SaveTablet(replica) require.NoError(t, err) - primaryAnalysisEntry := inst.ReplicationAnalysis{ + primaryAnalysisEntry := inst.DetectionAnalysis{ AnalyzedInstanceAlias: topoproto.TabletAliasString(primary.Alias), Analysis: inst.ReplicationStopped, } - replicaAnalysisEntry := inst.ReplicationAnalysis{ + replicaAnalysisEntry := inst.DetectionAnalysis{ AnalyzedInstanceAlias: topoproto.TabletAliasString(replica.Alias), Analysis: inst.DeadPrimary, } @@ -311,3 +312,34 @@ func TestGetCheckAndRecoverFunctionCode(t *testing.T) { }) } } + +func TestRecoverShardAnalyses(t *testing.T) { + // DeadPrimary and PrimaryHasPrimary have detectionAnalysisPriorityShardWideAction, + // so they require ordered execution. ReplicationStopped and ReplicaIsWritable are + // medium priority with no shard-wide action or before/after dependencies, + // so they run concurrently. + analyses := []*inst.DetectionAnalysis{ + {Analysis: inst.ReplicationStopped, AnalyzedInstanceAlias: "replica1"}, + {Analysis: inst.DeadPrimary, AnalyzedInstanceAlias: "primary1"}, + {Analysis: inst.ReplicaIsWritable, AnalyzedInstanceAlias: "replica2"}, + {Analysis: inst.PrimaryHasPrimary, AnalyzedInstanceAlias: "primary2"}, + } + + var mu sync.Mutex + var order []inst.AnalysisCode + recoverFunc := func(entry *inst.DetectionAnalysis) error { + mu.Lock() + defer mu.Unlock() + order = append(order, entry.Analysis) + return nil + } + + recoverShardAnalyses(analyses, recoverFunc) + + require.Len(t, order, 4) + // Ordered recoveries must come first, in their original order. + require.Equal(t, inst.DeadPrimary, order[0]) + require.Equal(t, inst.PrimaryHasPrimary, order[1]) + // Concurrent recoveries come after, in any order. + require.ElementsMatch(t, []inst.AnalysisCode{inst.ReplicationStopped, inst.ReplicaIsWritable}, order[2:]) +} diff --git a/go/vt/vtorc/server/api.go b/go/vt/vtorc/server/api.go index 177f2c80333..8b524c5c238 100644 --- a/go/vt/vtorc/server/api.go +++ b/go/vt/vtorc/server/api.go @@ -250,14 +250,14 @@ func replicationAnalysisAPIHandler(response http.ResponseWriter, request *http.R http.Error(response, shardWithoutKeyspaceFilteringErrorStr, http.StatusBadRequest) return } - analysis, err := inst.GetReplicationAnalysis(keyspace, shard, &inst.ReplicationAnalysisHints{}) + analysis, err := inst.GetDetectionAnalysis(keyspace, shard, &inst.DetectionAnalysisHints{}) if err != nil { http.Error(response, err.Error(), http.StatusInternalServerError) return } // TODO: We can also add filtering for a specific instance too based on the tablet alias. - // Currently inst.ReplicationAnalysis doesn't store the tablet alias, but once it does we can filter on that too + // Currently inst.DetectionAnalysis doesn't store the tablet alias, but once it does we can filter on that too returnAsJSON(response, http.StatusOK, analysis) } diff --git a/go/vt/vtorc/test/recovery_analysis.go b/go/vt/vtorc/test/recovery_analysis.go index 50d065120af..ea1c25708e3 100644 --- a/go/vt/vtorc/test/recovery_analysis.go +++ b/go/vt/vtorc/test/recovery_analysis.go @@ -76,6 +76,7 @@ type InfoForRecoveryAnalysis struct { CountMixedBasedLoggingReplicas uint CountRowBasedLoggingReplicas uint CountDistinctMajorVersionsLoggingReplicas uint + CountValidSemiSyncReplicatingReplicas uint CountDelayedReplicas uint CountLaggingReplicas uint MinReplicaGTIDMode string @@ -106,7 +107,7 @@ func (info *InfoForRecoveryAnalysis) ConvertToRowMap() sqlutils.RowMap { rowMap["count_valid_oracle_gtid_replicas"] = sqlutils.CellData{String: fmt.Sprintf("%v", info.CountValidOracleGTIDReplicas), Valid: true} rowMap["count_valid_replicas"] = sqlutils.CellData{String: fmt.Sprintf("%v", info.CountValidReplicas), Valid: true} rowMap["count_valid_replicating_replicas"] = sqlutils.CellData{String: fmt.Sprintf("%v", info.CountValidReplicatingReplicas), Valid: true} - rowMap["data_center"] = sqlutils.CellData{String: info.DataCenter, Valid: true} + rowMap["count_valid_semi_sync_replicating_replicas"] = sqlutils.CellData{String: fmt.Sprintf("%v", info.CountValidSemiSyncReplicatingReplicas), Valid: true} rowMap["downtime_end_timestamp"] = sqlutils.CellData{String: info.DowntimeEndTimestamp, Valid: true} rowMap["downtime_remaining_seconds"] = sqlutils.CellData{String: fmt.Sprintf("%v", info.DowntimeRemainingSeconds), Valid: true} rowMap["durability_policy"] = sqlutils.CellData{String: info.DurabilityPolicy, Valid: true} From 99d81aac7dd76ddf52c50063b40836afe8786cc9 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 23:05:15 +0000 Subject: [PATCH 090/112] [release-22.0] planbuilder: fix panic when SELECT has duplicate subqueries (#19581) (#19605) Signed-off-by: Arthur Schreiber Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 Co-authored-by: Arthur Schreiber --- .../planbuilder/operators/projection.go | 13 +---- .../planbuilder/operators/subquery_builder.go | 23 ++++++-- .../planbuilder/testdata/select_cases.json | 57 +++++++++++++++++++ 3 files changed, 76 insertions(+), 17 deletions(-) diff --git a/go/vt/vtgate/planbuilder/operators/projection.go b/go/vt/vtgate/planbuilder/operators/projection.go index fb600f5eff0..1ff6b191a82 100644 --- a/go/vt/vtgate/planbuilder/operators/projection.go +++ b/go/vt/vtgate/planbuilder/operators/projection.go @@ -286,18 +286,7 @@ func (p *Projection) addUnexploredExpr(ae *sqlparser.AliasedExpr, e sqlparser.Ex return p.addProjExpr(newProjExprWithInner(ae, e)) } -func (p *Projection) addSubqueryExpr(ctx *plancontext.PlanningContext, ae *sqlparser.AliasedExpr, expr sqlparser.Expr, sqs ...*SubQuery) { - ap, err := p.GetAliasedProjections() - if err != nil { - panic(err) - } - for _, projExpr := range ap { - if ctx.SemTable.EqualsExprWithDeps(projExpr.EvalExpr, expr) { - // if we already have this column, we can just return the offset - return - } - } - +func (p *Projection) addSubqueryExpr(_ *plancontext.PlanningContext, ae *sqlparser.AliasedExpr, expr sqlparser.Expr, sqs ...*SubQuery) { pe := newProjExprWithInner(ae, expr) pe.Info = SubQueryExpression(sqs) diff --git a/go/vt/vtgate/planbuilder/operators/subquery_builder.go b/go/vt/vtgate/planbuilder/operators/subquery_builder.go index d9c29d936ab..3df5b8d3de5 100644 --- a/go/vt/vtgate/planbuilder/operators/subquery_builder.go +++ b/go/vt/vtgate/planbuilder/operators/subquery_builder.go @@ -343,16 +343,29 @@ func (sqb *SubQueryBuilder) pullOutValueSubqueries( if sqe == nil { return nil, nil } - var newSubqs []*SubQuery + var allSubqs []*SubQuery for idx, subq := range sqe.subq { - sqInner := createSubquery(ctx, original, subq, outerID, original, sqe.cols[idx], sqe.pullOutCode[idx], true) - newSubqs = append(newSubqs, sqInner) + argName := sqe.cols[idx] + if existing := sqb.findByArgName(argName); existing != nil { + allSubqs = append(allSubqs, existing) + continue + } + sqInner := createSubquery(ctx, original, subq, outerID, original, argName, sqe.pullOutCode[idx], true) + allSubqs = append(allSubqs, sqInner) + sqb.Inner = append(sqb.Inner, sqInner) } - sqb.Inner = append(sqb.Inner, newSubqs...) + return sqe.new, allSubqs +} - return sqe.new, newSubqs +func (sqb *SubQueryBuilder) findByArgName(name string) *SubQuery { + for _, sq := range sqb.Inner { + if sq.ArgName == name { + return sq + } + } + return nil } type subqueryExtraction struct { diff --git a/go/vt/vtgate/planbuilder/testdata/select_cases.json b/go/vt/vtgate/planbuilder/testdata/select_cases.json index a10274cbc78..edd1a315eba 100644 --- a/go/vt/vtgate/planbuilder/testdata/select_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/select_cases.json @@ -5548,6 +5548,63 @@ ] } }, + { + "comment": "Duplicate uncorrelated subqueries should not be deduplicated in the projection", + "query": "SELECT (SELECT count(*) FROM user_extra), (SELECT count(*) FROM user_extra) FROM user WHERE id = 1", + "plan": { + "Type": "Complex", + "QueryType": "SELECT", + "Original": "SELECT (SELECT count(*) FROM user_extra), (SELECT count(*) FROM user_extra) FROM user WHERE id = 1", + "Instructions": { + "OperatorType": "UncorrelatedSubquery", + "Variant": "PulloutValue", + "PulloutVars": [ + "__sq1" + ], + "Inputs": [ + { + "InputName": "SubQuery", + "OperatorType": "Aggregate", + "Variant": "Scalar", + "Aggregates": "sum_count_star(0) AS count(*)", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select count(*) from user_extra where 1 != 1", + "Query": "select count(*) from user_extra", + "Table": "user_extra" + } + ] + }, + { + "InputName": "Outer", + "OperatorType": "Route", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select :__sq1 /* INT64 */ as `(select count(*) from user_extra)`, :__sq1 /* INT64 */ as `(select count(*) from user_extra)` from `user` where 1 != 1", + "Query": "select :__sq1 /* INT64 */ as `(select count(*) from user_extra)`, :__sq1 /* INT64 */ as `(select count(*) from user_extra)` from `user` where id = 1", + "Table": "`user`", + "Values": [ + "1" + ], + "Vindex": "user_index" + } + ] + }, + "TablesUsed": [ + "user.user", + "user.user_extra" + ] + } + }, { "comment": "(OR 1 = 0) doesn't cause unnecessary scatter", "query": "select * from user where id = 1 or 1 = 0", From 2007573d4b4fd54b5d3ebc5f4fde0ebb96fd881e Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Wed, 11 Mar 2026 08:26:41 -0700 Subject: [PATCH 091/112] [release-22.0] Fix some linting issues (#19246) (#19247) Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- docker/test/run.sh | 26 +++++++++++++------------- test.go | 11 +++++------ tools/unit_test_runner.sh | 1 + 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/docker/test/run.sh b/docker/test/run.sh index f41e2b49c89..280e750679c 100755 --- a/docker/test/run.sh +++ b/docker/test/run.sh @@ -122,7 +122,7 @@ if [[ -n "$existing_cache_image" ]]; then fi # Fix permissions before copying files, to avoid AUFS bug other must have read/access permissions -chmod -R o=rx *; +chmod -R o=rx -- *; # This is required by the vtctld_web_test.py test. # Otherwise, /usr/bin/chromium will crash with the error: @@ -153,10 +153,10 @@ fi # Mount in host VTDATAROOT if one exists, since it might be a RAM disk or SSD. if [[ -n "$VTDATAROOT" ]]; then - hostdir=`mktemp -d $VTDATAROOT/test-XXX` - testid=`basename $hostdir` + hostdir=$(mktemp -d "$VTDATAROOT/test-XXX") + testid=$(basename "$hostdir") - chmod 777 $hostdir + chmod 777 "$hostdir" echo "Mounting host dir $hostdir as VTDATAROOT" args="$args -v $hostdir:/vt/vtdataroot --name=$testid -h $testid" @@ -201,12 +201,14 @@ bashcmd=$(append_cmd "$bashcmd" "$cmd") if tty -s; then # interactive shell # See above why we turn on "extglob" (extended Glob). - docker run -ti $args $image bash -O extglob -c "$bashcmd" + # shellcheck disable=SC2086 + docker run -ti $args "$image" bash -O extglob -c "$bashcmd" exitcode=$? else # non-interactive shell (kill child on signal) trap 'docker kill $testid &>/dev/null' SIGTERM SIGINT - docker run $args $image bash -O extglob -c "$bashcmd" & + # shellcheck disable=SC2086 + docker run $args "$image" bash -O extglob -c "$bashcmd" & wait $! exitcode=$? trap - SIGTERM SIGINT @@ -215,23 +217,21 @@ fi # Clean up host dir mounted VTDATAROOT if [[ -n "$hostdir" ]]; then # Use Docker user to clean up first, to avoid permission errors. - docker run --name=rm_$testid -v $hostdir:/vt/vtdataroot $image bash -c 'rm -rf /vt/vtdataroot/*' - docker rm -f rm_$testid &>/dev/null - rm -rf $hostdir + docker run --name="rm_$testid" -v "$hostdir":/vt/vtdataroot "$image" bash -c 'rm -rf /vt/vtdataroot/*' + docker rm -f "rm_$testid" &>/dev/null + rm -rf "$hostdir" fi # If requested, create the cache image. if [[ "$mode" == "create_cache" && $exitcode == 0 ]]; then msg="DO NOT PUSH: This is a temporary layer meant to persist e.g. the result of 'make build'. Never push this layer back to our official Docker Hub repository." - docker commit -m "$msg" $testid $cache_image - - if [[ $? != 0 ]]; then + if ! docker commit -m "$msg" "$testid" "$cache_image"; then exitcode=$? echo "ERROR: Failed to create Docker cache. Used command: docker commit -m '$msg' $testid $image" fi fi # Delete the container -docker rm -f $testid &>/dev/null +docker rm -f "$testid" &>/dev/null exit $exitcode diff --git a/test.go b/test.go index 3087a42b9c6..218ac4ecb96 100755 --- a/test.go +++ b/test.go @@ -285,7 +285,6 @@ func loadOneConfig(fileName string) (*Config, error) { return nil, err } return config2, nil - } // Get test configs. @@ -338,16 +337,16 @@ func main() { // Make output directory. outDir := path.Join("_test", fmt.Sprintf("%v.%v", startTime.Format("20060102-150405"), os.Getpid())) - if err := os.MkdirAll(outDir, os.FileMode(0755)); err != nil { + if err := os.MkdirAll(outDir, os.FileMode(0o755)); err != nil { log.Fatalf("Can't create output directory: %v", err) } junitDir := path.Join("_test", "junit") - if err := os.MkdirAll(junitDir, os.FileMode(0755)); err != nil { + if err := os.MkdirAll(junitDir, os.FileMode(0o755)); err != nil { log.Fatalf("Can't create junit directory: %v", err) } - logFile, err := os.OpenFile(path.Join(outDir, "test.log"), os.O_RDWR|os.O_CREATE, 0o0644) + logFile, err := os.OpenFile(path.Join(outDir, "test.log"), os.O_RDWR|os.O_CREATE, 0o644) if err != nil { log.Fatalf("Can't create log file: %v", err) } @@ -532,7 +531,7 @@ func main() { outFile := fmt.Sprintf("%v.%v-%v.log", test.flavor, test.name, test.runIndex+1) outFilePath := path.Join(outDir, outFile) test.logf("saving test output to %v", outFilePath) - if fileErr := os.WriteFile(outFilePath, output, os.FileMode(0644)); fileErr != nil { + if fileErr := os.WriteFile(outFilePath, output, os.FileMode(0o644)); fileErr != nil { test.logf("WriteFile error: %v", fileErr) } } @@ -723,7 +722,7 @@ func updateTestStats(name string, update func(*TestStats)) { log.Printf("Can't encode stats file: %v", err) return } - if err := os.WriteFile(statsFileName, data, 0644); err != nil { + if err := os.WriteFile(statsFileName, data, 0o644); err != nil { log.Printf("Can't write stats file: %v", err) } } diff --git a/tools/unit_test_runner.sh b/tools/unit_test_runner.sh index 7edb4d22ac7..ba24e8332c8 100755 --- a/tools/unit_test_runner.sh +++ b/tools/unit_test_runner.sh @@ -74,4 +74,5 @@ if [[ -n "${JSON_OUTPUT:-}" ]]; then GOTESTSUM_ARGS="$GOTESTSUM_ARGS --jsonfile $JSON_OUTPUT" fi +# shellcheck disable=SC2086 go tool gotestsum $GOTESTSUM_ARGS --packages="$packages_with_tests" -- $VT_GO_PARALLEL $RACE_FLAG -count=1 From 11110ebf0c66e6e8d66d94695c2f6cd2656f0a0c Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Wed, 11 Mar 2026 08:26:56 -0700 Subject: [PATCH 092/112] [release-22.0] `EmergencyReparentShard`: require stop replication error to be from `PRIMARY` (#19515) (#19607) Signed-off-by: Tim Vaillancourt Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Tim Vaillancourt Co-authored-by: Claude Opus 4.6 --- .../reservedconn/reconnect3/main_test.go | 6 ++ .../reservedconn/reconnect4/main_test.go | 6 ++ .../reparentutil/emergency_reparenter.go | 2 +- .../reparentutil/emergency_reparenter_test.go | 2 + go/vt/vtctl/reparentutil/replication.go | 55 +++++++++++- go/vt/vtctl/reparentutil/replication_test.go | 90 +++++++++++++++++-- 6 files changed, 149 insertions(+), 12 deletions(-) diff --git a/go/test/endtoend/vtgate/reservedconn/reconnect3/main_test.go b/go/test/endtoend/vtgate/reservedconn/reconnect3/main_test.go index decf2f0dfdd..02fed03c258 100644 --- a/go/test/endtoend/vtgate/reservedconn/reconnect3/main_test.go +++ b/go/test/endtoend/vtgate/reservedconn/reconnect3/main_test.go @@ -82,6 +82,12 @@ func TestMysqlDownServingChange(t *testing.T) { utils.Exec(t, conn, "set default_week_format = 1") _ = utils.Exec(t, conn, "select /*vt+ PLANNER=gen4 */ * from test") + // Disable VTOrc recoveries to prevent VTOrc from racing with the manual ERS below. + clusterInstance.DisableVTOrcRecoveries(t) + t.Cleanup(func() { + clusterInstance.EnableVTOrcRecoveries(t) + }) + primaryTablet := clusterInstance.Keyspaces[0].Shards[0].PrimaryTablet() require.NoError(t, primaryTablet.MysqlctlProcess.Stop()) diff --git a/go/test/endtoend/vtgate/reservedconn/reconnect4/main_test.go b/go/test/endtoend/vtgate/reservedconn/reconnect4/main_test.go index 320cbc87172..802a5533316 100644 --- a/go/test/endtoend/vtgate/reservedconn/reconnect4/main_test.go +++ b/go/test/endtoend/vtgate/reservedconn/reconnect4/main_test.go @@ -82,6 +82,12 @@ func TestVttabletDownServingChange(t *testing.T) { utils.Exec(t, conn, "set default_week_format = 1") _ = utils.Exec(t, conn, "select /*vt+ PLANNER=gen4 */ * from test") + // Disable VTOrc recoveries to prevent VTOrc from racing with the manual ERS below. + clusterInstance.DisableVTOrcRecoveries(t) + t.Cleanup(func() { + clusterInstance.EnableVTOrcRecoveries(t) + }) + primaryTablet := clusterInstance.Keyspaces[0].Shards[0].PrimaryTablet() require.NoError(t, primaryTablet.MysqlctlProcess.Stop()) diff --git a/go/vt/vtctl/reparentutil/emergency_reparenter.go b/go/vt/vtctl/reparentutil/emergency_reparenter.go index 513076b8f68..9f8d77f1534 100644 --- a/go/vt/vtctl/reparentutil/emergency_reparenter.go +++ b/go/vt/vtctl/reparentutil/emergency_reparenter.go @@ -206,7 +206,7 @@ func (erp *EmergencyReparenter) reparentShardLocked(ctx context.Context, ev *eve } // Stop replication on all the tablets and build their status map - stoppedReplicationSnapshot, err = stopReplicationAndBuildStatusMaps(ctx, erp.tmc, ev, tabletMap, topo.RemoteOperationTimeout, opts.IgnoreReplicas, opts.NewPrimaryAlias, opts.durability, opts.WaitAllTablets, erp.logger) + stoppedReplicationSnapshot, err = stopReplicationAndBuildStatusMaps(ctx, erp.tmc, ev, tabletMap, shardInfo.PrimaryAlias, topo.RemoteOperationTimeout, opts.IgnoreReplicas, opts.NewPrimaryAlias, opts.durability, opts.WaitAllTablets, erp.logger) if err != nil { return vterrors.Wrapf(err, "failed to stop replication and build status maps: %v", err) } diff --git a/go/vt/vtctl/reparentutil/emergency_reparenter_test.go b/go/vt/vtctl/reparentutil/emergency_reparenter_test.go index 888e6c77130..c483d35bfaa 100644 --- a/go/vt/vtctl/reparentutil/emergency_reparenter_test.go +++ b/go/vt/vtctl/reparentutil/emergency_reparenter_test.go @@ -1563,6 +1563,7 @@ func TestEmergencyReparenter_reparentShardLocked(t *testing.T) { Cell: "zone2", Uid: 100, }, + Type: topodatapb.TabletType_PRIMARY, Keyspace: "testkeyspace", Shard: "-", Hostname: "failed previous primary", @@ -1688,6 +1689,7 @@ func TestEmergencyReparenter_reparentShardLocked(t *testing.T) { Cell: "zone2", Uid: 100, }, + Type: topodatapb.TabletType_PRIMARY, Keyspace: "testkeyspace", Shard: "-", Hostname: "failed previous primary", diff --git a/go/vt/vtctl/reparentutil/replication.go b/go/vt/vtctl/reparentutil/replication.go index 46568a5164f..6fa5ea5c1cd 100644 --- a/go/vt/vtctl/reparentutil/replication.go +++ b/go/vt/vtctl/reparentutil/replication.go @@ -18,6 +18,7 @@ package reparentutil import ( "context" + "errors" "sync" "time" @@ -160,6 +161,30 @@ type replicationSnapshot struct { tabletsBackupState map[string]bool } +// tabletAliasError wraps an error with the tablet alias that produced it. +type tabletAliasError struct { + alias *topodatapb.TabletAlias + err error +} + +// Error returns the wrapped error. +func (e *tabletAliasError) Error() string { + if e.err == nil { + return "" + } + return e.err.Error() +} + +// GetAlias returns the tablet alias that produced the error. +func (e *tabletAliasError) GetAlias() *topodatapb.TabletAlias { + return e.alias +} + +// Unwrap returns the underlying error. +func (e *tabletAliasError) Unwrap() error { + return e.err +} + // stopReplicationAndBuildStatusMaps stops replication on all replicas, then // collects and returns a mapping of TabletAlias (as string) to their current // replication positions. @@ -169,6 +194,7 @@ func stopReplicationAndBuildStatusMaps( tmc tmclient.TabletManagerClient, ev *events.Reparent, tabletMap map[string]*topo.TabletInfo, + primaryAlias *topodatapb.TabletAlias, stopReplicationTimeout time.Duration, ignoredTablets sets.Set[string], tabletToWaitFor *topodatapb.TabletAlias, @@ -197,7 +223,12 @@ func stopReplicationAndBuildStatusMaps( var concurrencyErr concurrency.Error var err error defer func() { - concurrencyErr.Err = err + if err != nil { + concurrencyErr.Err = &tabletAliasError{ + alias: tabletInfo.GetAlias(), + err: err, + } + } concurrencyErr.MustWaitFor = mustWaitForTablet errChan <- concurrencyErr }() @@ -288,11 +319,29 @@ func stopReplicationAndBuildStatusMaps( // even in case of multiple failures. We rely on the revoke function below to determine if we have more failures than we can tolerate NumErrorsToWaitFor: numErrorsToWaitFor, } - errRecorder := errgroup.Wait(groupCancel, errChan) - if len(errRecorder.Errors) <= 1 { + + // Exit early if we encountered no errors. + if len(errRecorder.Errors) == 0 { return res, nil } + + // If there are recorded errors, confirm there is a single error from the PRIMARY. + // We intentionally do not check for specific error types here because the nature + // of ERS means we expect any number of possible errors from the PRIMARY we are + // abandoning (e.g. connection refused, context deadline, MySQL down, etc.) and + // we don't need to handle them differently — the goal is simply to confirm the + // error came from the PRIMARY tablet, not to diagnose why it failed. + if primaryAlias != nil && len(errRecorder.Errors) == 1 { + var tabletErr *tabletAliasError + if errors.As(errRecorder.Errors[0], &tabletErr) { + // Failure to reach the PRIMARY tablet is expected, return early. + if topoproto.TabletAliasEqual(primaryAlias, tabletErr.GetAlias()) { + return res, nil + } + } + } + // check that the tablets we were able to reach are sufficient for us to guarantee that no new write will be accepted by any tablet revokeSuccessful := haveRevoked(durability, res.reachableTablets, allTablets) if !revokeSuccessful { diff --git a/go/vt/vtctl/reparentutil/replication_test.go b/go/vt/vtctl/reparentutil/replication_test.go index af909d602ed..57f76a903a1 100644 --- a/go/vt/vtctl/reparentutil/replication_test.go +++ b/go/vt/vtctl/reparentutil/replication_test.go @@ -277,6 +277,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { durability string tmc *stopReplicationAndBuildStatusMapsTestTMClient tabletMap map[string]*topo.TabletInfo + primaryAlias *topodatapb.TabletAlias stopReplicasTimeout time.Duration ignoredTablets sets.Set[string] tabletToWaitFor *topodatapb.TabletAlias @@ -427,8 +428,9 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { }}, waitForAllTablets: true, shouldErr: false, - }, { - name: "timing check with wait for all tablets", + }, + { + name: "primary timeout with wait for all tablets", durability: policy.DurabilityNone, tmc: &stopReplicationAndBuildStatusMapsTestTMClient{ stopReplicationAndGetStatusResults: map[string]*struct { @@ -476,7 +478,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { }, }, "zone1-0000000102": { Tablet: &topodatapb.Tablet{ - Type: topodatapb.TabletType_REPLICA, + Type: topodatapb.TabletType_PRIMARY, Alias: &topodatapb.TabletAlias{ Cell: "zone1", Uid: 102, @@ -484,6 +486,10 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { }, }, }, + primaryAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 102, + }, ignoredTablets: sets.New[string](), expectedStatusMap: map[string]*replicationdatapb.StopReplicationStatus{ "zone1-0000000100": { @@ -812,6 +818,10 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { }, }, }, + primaryAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, ignoredTablets: sets.New[string](), expectedStatusMap: map[string]*replicationdatapb.StopReplicationStatus{ "zone1-0000000101": { @@ -887,6 +897,10 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { }, }, }, + primaryAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, ignoredTablets: sets.New[string](), expectedStatusMap: map[string]*replicationdatapb.StopReplicationStatus{ "zone1-0000000101": { @@ -952,6 +966,10 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { }, }, }, + primaryAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, ignoredTablets: sets.New[string](), expectedStatusMap: nil, expectedPrimaryStatusMap: nil, @@ -959,7 +977,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { shouldErr: true, // we get multiple errors, so we fail }, { - name: "stopReplicasTimeout exceeded", + name: "primary timeout exceeds stopReplicasTimeout", durability: policy.DurabilityNone, tmc: &stopReplicationAndBuildStatusMapsTestTMClient{ stopReplicationAndGetStatusDelays: map[string]time.Duration{ @@ -986,7 +1004,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { tabletMap: map[string]*topo.TabletInfo{ "zone1-0000000100": { Tablet: &topodatapb.Tablet{ - Type: topodatapb.TabletType_REPLICA, + Type: topodatapb.TabletType_PRIMARY, Alias: &topodatapb.TabletAlias{ Cell: "zone1", Uid: 100, @@ -1003,6 +1021,10 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { }, }, }, + primaryAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, stopReplicasTimeout: time.Millisecond * 5, ignoredTablets: sets.New[string](), expectedStatusMap: map[string]*replicationdatapb.StopReplicationStatus{ @@ -1023,7 +1045,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { shouldErr: false, }, { - name: "one tablet fails to StopReplication", + name: "replica failure to StopReplication returns an error", durability: policy.DurabilityNone, tmc: &stopReplicationAndBuildStatusMapsTestTMClient{ stopReplicationAndGetStatusResults: map[string]*struct { @@ -1077,7 +1099,59 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { Uid: 101, }, }}, - shouldErr: false, + shouldErr: true, + }, + { + // A single replica fails StopReplication, but primaryAlias points to a + // *different* tablet (the actual primary). The error doesn't match the + // primary alias, so we fall through to haveRevoked, which fails because + // the primary itself was not reached. + name: "single replica failure with primaryAlias set does not suppress error", + durability: policy.DurabilityNone, + tmc: &stopReplicationAndBuildStatusMapsTestTMClient{ + stopReplicationAndGetStatusResults: map[string]*struct { + StopStatus *replicationdatapb.StopReplicationStatus + Err error + }{ + "zone1-0000000100": { // replica fails + Err: assert.AnError, + }, + "zone1-0000000101": { // primary succeeds + StopStatus: &replicationdatapb.StopReplicationStatus{ + Before: &replicationdatapb.Status{Position: "MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429101:1-5", IoState: int32(replication.ReplicationStateRunning), SqlState: int32(replication.ReplicationStateRunning)}, + After: &replicationdatapb.Status{Position: "MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429101:1-9"}, + }, + }, + }, + }, + tabletMap: map[string]*topo.TabletInfo{ + "zone1-0000000100": { + Tablet: &topodatapb.Tablet{ + Type: topodatapb.TabletType_REPLICA, + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + }, + }, + "zone1-0000000101": { + Tablet: &topodatapb.Tablet{ + Type: topodatapb.TabletType_PRIMARY, + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 101, + }, + }, + }, + }, + // primaryAlias points to zone1-0000000101 (the primary), but the error + // came from zone1-0000000100 (a replica) — alias mismatch should not suppress. + primaryAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 101, + }, + ignoredTablets: sets.New[string](), + shouldErr: true, }, { name: "multiple tablets fail StopReplication", @@ -1300,7 +1374,7 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) { durability, err := policy.GetDurabilityPolicy(tt.durability) require.NoError(t, err) startTime := time.Now() - res, err := stopReplicationAndBuildStatusMaps(ctx, tt.tmc, &events.Reparent{}, tt.tabletMap, tt.stopReplicasTimeout, tt.ignoredTablets, tt.tabletToWaitFor, durability, tt.waitForAllTablets, logger) + res, err := stopReplicationAndBuildStatusMaps(ctx, tt.tmc, &events.Reparent{}, tt.tabletMap, tt.primaryAlias, tt.stopReplicasTimeout, tt.ignoredTablets, tt.tabletToWaitFor, durability, tt.waitForAllTablets, logger) totalTimeSpent := time.Since(startTime) if tt.timeSpent != 0 { assert.Greater(t, totalTimeSpent, tt.timeSpent) From 6ad5e3499fd066e14a9c3b4a131f4a312f2bdaec Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Wed, 11 Mar 2026 08:26:58 -0700 Subject: [PATCH 093/112] [release-22.0] `vtorc`: improvements to analysis ordering, handle semi-sync disable (#19488) (#19550) Signed-off-by: Tim Vaillancourt Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Tim Vaillancourt --- go/vt/vtorc/inst/analysis_problem.go | 16 +++++- go/vt/vtorc/inst/analysis_problem_test.go | 60 +++++++++++++++++++++-- 2 files changed, 71 insertions(+), 5 deletions(-) diff --git a/go/vt/vtorc/inst/analysis_problem.go b/go/vt/vtorc/inst/analysis_problem.go index ebfa89fc112..030af55ca8e 100644 --- a/go/vt/vtorc/inst/analysis_problem.go +++ b/go/vt/vtorc/inst/analysis_problem.go @@ -63,9 +63,19 @@ type DetectionAnalysisProblem struct { } // RequiresOrderedExecution returns true if the problem must be executed -// sequentially relative to other problems in the same shard. +// sequentially relative to other problems in the same shard. This includes +// problems that declare dependencies directly (BeforeAnalyses/AfterAnalyses) +// as well as problems that are referenced by another problem's dependencies. func (dap *DetectionAnalysisProblem) RequiresOrderedExecution() bool { - return dap.Meta.Priority == detectionAnalysisPriorityShardWideAction || len(dap.BeforeAnalyses) > 0 || len(dap.AfterAnalyses) > 0 + if dap.Meta.Priority == detectionAnalysisPriorityShardWideAction || len(dap.BeforeAnalyses) > 0 || len(dap.AfterAnalyses) > 0 { + return true + } + for _, p := range detectionAnalysisProblems { + if slices.Contains(p.BeforeAnalyses, dap.Meta.Analysis) || slices.Contains(p.AfterAnalyses, dap.Meta.Analysis) { + return true + } + } + return false } // GetPriority returns the priority of a problem as an int. @@ -228,6 +238,7 @@ var detectionAnalysisProblems = []*DetectionAnalysisProblem{ Description: "Primary semi-sync must not be set", Priority: detectionAnalysisPriorityMedium, }, + BeforeAnalyses: []AnalysisCode{ReplicaSemiSyncMustNotBeSet}, MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { return a.IsClusterPrimary && policy.SemiSyncAckers(ca.durability, tablet) == 0 && a.SemiSyncPrimaryEnabled }, @@ -249,6 +260,7 @@ var detectionAnalysisProblems = []*DetectionAnalysisProblem{ Description: "Replica semi-sync must not be set", Priority: detectionAnalysisPriorityMedium, }, + AfterAnalyses: []AnalysisCode{PrimarySemiSyncMustNotBeSet}, MatchFunc: func(a *DetectionAnalysis, ca *clusterAnalysis, primary, tablet *topodatapb.Tablet, isInvalid, isStaleBinlogCoordinates bool) bool { return topo.IsReplicaType(a.TabletType) && !a.IsPrimary && !policy.IsReplicaSemiSync(ca.durability, primary, tablet) && a.SemiSyncReplicaEnabled }, diff --git a/go/vt/vtorc/inst/analysis_problem_test.go b/go/vt/vtorc/inst/analysis_problem_test.go index 536d763bb8c..740d40db1db 100644 --- a/go/vt/vtorc/inst/analysis_problem_test.go +++ b/go/vt/vtorc/inst/analysis_problem_test.go @@ -76,12 +76,30 @@ func TestSortDetectionAnalysisMatchedProblems(t *testing.T) { Priority: detectionAnalysisPriorityShardWideAction, }, }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: ReplicaSemiSyncMustNotBeSet, + Description: "should be after PrimarySemiSyncMustNotBeSet, has an after dependency", + Priority: detectionAnalysisPriorityMedium, + }, + AfterAnalyses: []AnalysisCode{PrimarySemiSyncMustNotBeSet}, + }, + { + Meta: &DetectionAnalysisProblemMeta{ + Analysis: PrimarySemiSyncMustNotBeSet, + Description: "should be before ReplicaSemiSyncMustNotBeSet, has a before dependency", + Priority: detectionAnalysisPriorityMedium, + }, + BeforeAnalyses: []AnalysisCode{ReplicaSemiSyncMustNotBeSet}, + }, }, postSortByAnalysis: []AnalysisCode{ DeadPrimary, PrimaryIsReadOnly, ReplicaSemiSyncMustBeSet, PrimarySemiSyncMustBeSet, + PrimarySemiSyncMustNotBeSet, + ReplicaSemiSyncMustNotBeSet, InvalidReplica, InvalidReplica, }, @@ -126,7 +144,7 @@ func TestRequiresOrderedExecution(t *testing.T) { { name: "has BeforeAnalyses", problem: &DetectionAnalysisProblem{ - Meta: &DetectionAnalysisProblemMeta{}, + Meta: &DetectionAnalysisProblemMeta{Priority: detectionAnalysisPriorityMedium}, BeforeAnalyses: []AnalysisCode{DeadPrimary}, }, expected: true, @@ -134,11 +152,25 @@ func TestRequiresOrderedExecution(t *testing.T) { { name: "has AfterAnalyses", problem: &DetectionAnalysisProblem{ - Meta: &DetectionAnalysisProblemMeta{}, + Meta: &DetectionAnalysisProblemMeta{Priority: detectionAnalysisPriorityMedium}, AfterAnalyses: []AnalysisCode{DeadPrimary}, }, expected: true, }, + { + name: "referenced by another problem's BeforeAnalyses", + problem: &DetectionAnalysisProblem{ + Meta: &DetectionAnalysisProblemMeta{Analysis: ReplicaSemiSyncMustNotBeSet, Priority: detectionAnalysisPriorityMedium}, + }, + expected: true, + }, + { + name: "referenced by another problem's AfterAnalyses", + problem: &DetectionAnalysisProblem{ + Meta: &DetectionAnalysisProblemMeta{Analysis: PrimarySemiSyncMustNotBeSet, Priority: detectionAnalysisPriorityMedium}, + }, + expected: true, + }, { name: "independent problem", problem: &DetectionAnalysisProblem{ @@ -200,7 +232,7 @@ func TestCompareDetectionAnalysisProblems(t *testing.T) { expected: 0, }, { - name: "before dependency", + name: "before dependency - MustBeSet", a: &DetectionAnalysisProblem{ Meta: &DetectionAnalysisProblemMeta{Analysis: ReplicaSemiSyncMustBeSet}, BeforeAnalyses: []AnalysisCode{PrimarySemiSyncMustBeSet}, @@ -210,6 +242,28 @@ func TestCompareDetectionAnalysisProblems(t *testing.T) { }, expected: -1, }, + { + name: "before dependency - MustNotBeSet", + a: &DetectionAnalysisProblem{ + Meta: &DetectionAnalysisProblemMeta{Analysis: PrimarySemiSyncMustNotBeSet}, + BeforeAnalyses: []AnalysisCode{ReplicaSemiSyncMustNotBeSet}, + }, + b: &DetectionAnalysisProblem{ + Meta: &DetectionAnalysisProblemMeta{Analysis: ReplicaSemiSyncMustNotBeSet}, + }, + expected: -1, + }, + { + name: "after dependency - MustNotBeSet", + a: &DetectionAnalysisProblem{ + Meta: &DetectionAnalysisProblemMeta{Analysis: ReplicaSemiSyncMustNotBeSet}, + AfterAnalyses: []AnalysisCode{PrimarySemiSyncMustNotBeSet}, + }, + b: &DetectionAnalysisProblem{ + Meta: &DetectionAnalysisProblemMeta{Analysis: PrimarySemiSyncMustNotBeSet}, + }, + expected: 1, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From d9e60d2d2e4fb225f63da2dab66b317b7549bcbe Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 19:13:23 -0400 Subject: [PATCH 094/112] [release-22.0] vtgate: set ServerStatusAutocommit in handshake status flags (#19628) (#19645) Signed-off-by: Liz van Dijk Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 --- go/vt/vtgate/plugin_mysql_server.go | 4 ++++ go/vt/vtgate/plugin_mysql_server_test.go | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/go/vt/vtgate/plugin_mysql_server.go b/go/vt/vtgate/plugin_mysql_server.go index 265d8b7c9cb..8e102b6689b 100644 --- a/go/vt/vtgate/plugin_mysql_server.go +++ b/go/vt/vtgate/plugin_mysql_server.go @@ -128,6 +128,10 @@ func newVtgateHandler(vtg *VTGate) *vtgateHandler { } func (vh *vtgateHandler) NewConnection(c *mysql.Conn) { + // Match VTGate's default session state (Autocommit: true) so the + // handshake packet reports correct status flags to the client. + c.StatusFlags |= mysql.ServerStatusAutocommit + vh.mu.Lock() defer vh.mu.Unlock() vh.connections[c.ConnectionID] = c diff --git a/go/vt/vtgate/plugin_mysql_server_test.go b/go/vt/vtgate/plugin_mysql_server_test.go index 1eac6b350ae..7b13ce2d7a6 100644 --- a/go/vt/vtgate/plugin_mysql_server_test.go +++ b/go/vt/vtgate/plugin_mysql_server_test.go @@ -198,6 +198,20 @@ func TestConnectionRespectsExistingUnixSocket(t *testing.T) { } } +func TestNewConnectionSetsAutocommitStatusFlag(t *testing.T) { + vh := &vtgateHandler{ + connections: make(map[uint32]*mysql.Conn), + } + + c := &mysql.Conn{} + assert.Zero(t, c.StatusFlags, "StatusFlags should be zero before NewConnection") + + vh.NewConnection(c) + + assert.True(t, c.StatusFlags&mysql.ServerStatusAutocommit != 0, + "NewConnection should set ServerStatusAutocommit flag to match VTGate's default session state") +} + var newSpanOK = func(ctx context.Context, label string) (trace.Span, context.Context) { return trace.NoopSpan{}, context.Background() } From 8b5a8764701704ef1d5dcff5c13fc3736bc730a2 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Fri, 20 Mar 2026 11:13:54 +0000 Subject: [PATCH 095/112] [release-22.0] workflow: finish switch traffic after post-journal cancel (#19672) (#19681) Signed-off-by: Nick Van Wiggeren Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- go/vt/vtctl/workflow/framework_test.go | 17 ++- go/vt/vtctl/workflow/server.go | 46 +++++-- go/vt/vtctl/workflow/server_test.go | 158 +++++++++++++++++++++++++ 3 files changed, 209 insertions(+), 12 deletions(-) diff --git a/go/vt/vtctl/workflow/framework_test.go b/go/vt/vtctl/workflow/framework_test.go index 0575965c433..a5f3f8b5410 100644 --- a/go/vt/vtctl/workflow/framework_test.go +++ b/go/vt/vtctl/workflow/framework_test.go @@ -72,9 +72,11 @@ type testKeyspace struct { } type queryResult struct { - query string - result *querypb.QueryResult - err error + query string + result *querypb.QueryResult + err error + beforeReturnHook func(context.Context, *topodatapb.Tablet, string) + returnContextErr bool } func TestMain(m *testing.M) { @@ -493,7 +495,16 @@ func (tmc *testTMClient) VReplicationExec(ctx context.Context, tablet *topodatap if !matched { return nil, fmt.Errorf("tablet %v:\nunexpected query\n%s\nwant:\n%s", tablet, query, qrs[0].query) } + if qrs[0].beforeReturnHook != nil { + qrs[0].beforeReturnHook(ctx, tablet, query) + } tmc.vrQueries[int(tablet.Alias.Uid)] = qrs[1:] + if qrs[0].returnContextErr && ctx.Err() != nil { + return nil, ctx.Err() + } + if strings.Contains(query, "set message = 'FROZEN'") { + tmc.frozen.Store(true) + } return qrs[0].result, qrs[0].err } diff --git a/go/vt/vtctl/workflow/server.go b/go/vt/vtctl/workflow/server.go index 8d8ade19b83..511bce8c269 100644 --- a/go/vt/vtctl/workflow/server.go +++ b/go/vt/vtctl/workflow/server.go @@ -535,6 +535,17 @@ func (s *Server) getWorkflowState(ctx context.Context, targetKeyspace, workflowN return ts, state, nil } +func validateMoveTablesSourceKeyspace(ts *trafficSwitcher) error { + if ts.workflowType == binlogdatapb.VReplicationWorkflowType_MoveTables && + ts.externalCluster == "" && + ts.sourceKeyspace == ts.targetKeyspace { + return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, + "workflow %s.%s is invalid: MoveTables source keyspace matches target keyspace (%s)", + ts.targetKeyspace, ts.workflow, ts.targetKeyspace) + } + return nil +} + // LookupVindexComplete checks if the lookup vindex has been externalized, // and if the vindex has an owner, it deletes the workflow. func (s *Server) LookupVindexComplete(ctx context.Context, req *vtctldatapb.LookupVindexCompleteRequest) (*vtctldatapb.LookupVindexCompleteResponse, error) { @@ -2547,6 +2558,9 @@ func (s *Server) WorkflowSwitchTraffic(ctx context.Context, req *vtctldatapb.Wor if err != nil { return nil, err } + if err := validateMoveTablesSourceKeyspace(ts); err != nil { + return nil, err + } if startState.WorkflowType == TypeMigrate { return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "invalid action for Migrate workflow: SwitchTraffic") @@ -2893,9 +2907,14 @@ func (s *Server) switchWrites(ctx context.Context, req *vtctldatapb.WorkflowSwit // We need to hold the keyspace locks longer than waitTimeout*X -- where X // is the number of sub-steps where the waitTimeout value is used: stopping - // existing streams, waiting for replication to catch up, and initializing - // the target sequences -- to be sure the lock is not lost. - ksLockTTL := waitTimeout * 3 + // existing streams, waiting for replication to catch up, initializing the + // target sequences, and completing the detached post-journal tail -- to be + // sure the lock is not lost. + postJournalTimeout := max(waitTimeout, 30*time.Second) + ksLockTTL := waitTimeout*3 + postJournalTimeout + startPostJournalCtx := func(ctx context.Context) (context.Context, context.CancelFunc) { + return context.WithTimeout(context.WithoutCancel(ctx), postJournalTimeout) + } // Need to lock both source and target keyspaces. ctx, sourceUnlock, lockErr := sw.lockKeyspace(ctx, ts.SourceKeyspaceName(), "SwitchWrites", topo.WithTTL(ksLockTTL)) @@ -3083,21 +3102,30 @@ func (s *Server) switchWrites(ctx context.Context, req *vtctldatapb.WorkflowSwit return handleError(fmt.Sprintf("failed to initialize the sequences used in the %s keyspace", ts.TargetKeyspaceName()), err) } } + + // This is the point of no return. Once a journal is created, + // traffic can be redirected to target shards. + if err := confirmKeyspaceLocksHeld(); err != nil { + return handleError("locks were lost", err) + } + postJournalCtx, postJournalCancel := startPostJournalCtx(ctx) + defer postJournalCancel() + ctx = postJournalCtx } else { if cancel { return handleError("invalid cancel", vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "traffic switching has reached the point of no return, cannot cancel")) } + postJournalCtx, postJournalCancel := startPostJournalCtx(ctx) + defer postJournalCancel() + ctx = postJournalCtx ts.Logger().Infof("Journals were found. Completing the left over steps.") // Need to gather positions in case all journals were not created. if err := ts.gatherPositions(ctx); err != nil { return handleError("failed to gather replication positions", err) } - } - - // This is the point of no return. Once a journal is created, - // traffic can be redirected to target shards. - if err := confirmKeyspaceLocksHeld(); err != nil { - return handleError("locks were lost", err) + if err := confirmKeyspaceLocksHeld(); err != nil { + return handleError("locks were lost", err) + } } if err := sw.createJournals(ctx, sourceWorkflows); err != nil { return handleError("failed to create the journal", err) diff --git a/go/vt/vtctl/workflow/server_test.go b/go/vt/vtctl/workflow/server_test.go index a3c7a7c02bb..855a4c46640 100644 --- a/go/vt/vtctl/workflow/server_test.go +++ b/go/vt/vtctl/workflow/server_test.go @@ -1608,6 +1608,164 @@ func TestMoveTablesTrafficSwitching(t *testing.T) { } } +func TestMoveTablesSwitchWritesCompletesAfterCancelOnFreeze(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + const ( + workflowName = "wf1" + tableName = "t1" + sourceKeyspaceName = "sourceks" + targetKeyspaceName = "targetks" + ) + + env := newTestEnv(t, ctx, defaultCellName, &testKeyspace{ + KeyspaceName: sourceKeyspaceName, + ShardNames: []string{"0"}, + }, &testKeyspace{ + KeyspaceName: targetKeyspaceName, + ShardNames: []string{"0"}, + }) + defer env.close() + + env.tmc.schema = map[string]*tabletmanagerdatapb.SchemaDefinition{ + tableName: { + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{ + Name: tableName, + Schema: fmt.Sprintf("CREATE TABLE %s (id BIGINT, name VARCHAR(64), PRIMARY KEY (id))", tableName), + }}, + }, + } + + journalQR := &queryResult{ + query: "/select val from _vt.resharding_journal.*", + result: &querypb.QueryResult{}, + } + lockTableQR := &queryResult{ + query: fmt.Sprintf("LOCK TABLES `%s` READ", tableName), + result: &querypb.QueryResult{}, + } + cutoverQR := &queryResult{ + query: "/update _vt.vreplication set state='Stopped', message='stopped for cutover' where id=.*", + result: &querypb.QueryResult{}, + } + deleteReverseWFQR := &queryResult{ + query: fmt.Sprintf("delete from _vt.vreplication where db_name = 'vt_%s' and workflow = '%s'", sourceKeyspaceName, ReverseWorkflowName(workflowName)), + result: &querypb.QueryResult{}, + } + createReverseWFQR := &queryResult{ + query: "/insert into _vt.vreplication.*_reverse.*", + result: &querypb.QueryResult{}, + } + createJournalQR := &queryResult{ + query: "/insert into _vt.resharding_journal.*", + result: &querypb.QueryResult{}, + } + freezeWFQR := &queryResult{ + query: fmt.Sprintf("update _vt.vreplication set message = 'FROZEN' where db_name='vt_%s' and workflow='%s'", targetKeyspaceName, workflowName), + beforeReturnHook: func(context.Context, *topodatapb.Tablet, string) { + cancel() + }, + returnContextErr: true, + } + + env.tmc.expectVRQueryResultOnKeyspaceTablets(targetKeyspaceName, cutoverQR) + env.tmc.expectVRQueryResultOnKeyspaceTablets(sourceKeyspaceName, journalQR) + env.tmc.expectVRQueryResultOnKeyspaceTablets(sourceKeyspaceName, lockTableQR) + env.tmc.expectVRQueryResultOnKeyspaceTablets(sourceKeyspaceName, lockTableQR) + env.tmc.expectVRQueryResultOnKeyspaceTablets(sourceKeyspaceName, deleteReverseWFQR) + env.tmc.expectVRQueryResultOnKeyspaceTablets(sourceKeyspaceName, createReverseWFQR) + env.tmc.expectVRQueryResultOnKeyspaceTablets(sourceKeyspaceName, createJournalQR) + env.tmc.expectVRQueryResultOnKeyspaceTablets(targetKeyspaceName, freezeWFQR) + + ts, _, err := env.ws.getWorkflowState(ctx, targetKeyspaceName, workflowName) + require.NoError(t, err) + + _, _, err = env.ws.switchWrites(ctx, &vtctldatapb.WorkflowSwitchTrafficRequest{ + Keyspace: targetKeyspaceName, + Workflow: workflowName, + }, ts, time.Second, false) + require.NoError(t, err) + + rules, err := topotools.GetRoutingRules(context.Background(), env.ts) + require.NoError(t, err) + require.Equal(t, []string{targetKeyspaceName + "." + tableName}, rules[tableName]) + require.Equal(t, []string{targetKeyspaceName + "." + tableName}, rules[sourceKeyspaceName+"."+tableName]) + + sourceShard, err := env.ts.GetShard(context.Background(), sourceKeyspaceName, "0") + require.NoError(t, err) + require.Len(t, sourceShard.TabletControls, 1) + require.Equal(t, []string{tableName}, sourceShard.TabletControls[0].DeniedTables) + + targetShard, err := env.ts.GetShard(context.Background(), targetKeyspaceName, "0") + require.NoError(t, err) + require.Empty(t, targetShard.TabletControls) + + tsAfter, stateAfter, err := env.ws.getWorkflowState(context.Background(), targetKeyspaceName, workflowName) + require.NoError(t, err) + require.True(t, stateAfter.WritesSwitched, "expected writes to remain switched after the original context was canceled") + require.True(t, tsAfter.frozen, "expected the target workflow to be frozen even though the original context was canceled") +} + +func TestWorkflowSwitchTrafficFailsForInvalidMoveTablesSourceKeyspace(t *testing.T) { + ctx := context.Background() + + const ( + workflowName = "wf1" + tableName = "t1" + sourceKeyspaceName = "sourceks" + targetKeyspaceName = "targetks" + ) + + env := newTestEnv(t, ctx, defaultCellName, &testKeyspace{ + KeyspaceName: sourceKeyspaceName, + ShardNames: []string{"0"}, + }, &testKeyspace{ + KeyspaceName: targetKeyspaceName, + ShardNames: []string{"0"}, + }) + defer env.close() + + env.tmc.schema = map[string]*tabletmanagerdatapb.SchemaDefinition{ + tableName: { + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{ + Name: tableName, + Schema: fmt.Sprintf("CREATE TABLE %s (id BIGINT, name VARCHAR(64), PRIMARY KEY (id))", tableName), + }}, + }, + } + + env.tmc.expectReadVReplicationWorkflowRequestOnTargetTablets(&readVReplicationWorkflowRequestResponse{ + req: &tabletmanagerdatapb.ReadVReplicationWorkflowRequest{ + Workflow: workflowName, + }, + res: &tabletmanagerdatapb.ReadVReplicationWorkflowResponse{ + Workflow: workflowName, + WorkflowType: binlogdatapb.VReplicationWorkflowType_MoveTables, + Streams: []*tabletmanagerdatapb.ReadVReplicationWorkflowResponse_Stream{{ + Id: 1, + Bls: &binlogdatapb.BinlogSource{ + Keyspace: targetKeyspaceName, + Shard: "0", + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: tableName, + }}, + }, + }, + }}, + }, + }) + + _, err := env.ws.WorkflowSwitchTraffic(ctx, &vtctldatapb.WorkflowSwitchTrafficRequest{ + Keyspace: targetKeyspaceName, + Workflow: workflowName, + TabletTypes: []topodatapb.TabletType{topodatapb.TabletType_PRIMARY}, + Direction: int32(DirectionForward), + }) + require.EqualError(t, err, fmt.Sprintf("workflow %s.%s is invalid: MoveTables source keyspace matches target keyspace (%s)", targetKeyspaceName, workflowName, targetKeyspaceName)) +} + func TestMoveTablesTrafficSwitchingDryRun(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() From 3e94a98ac7de96f8884c5662c82413f35394cad6 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 16:54:47 +0100 Subject: [PATCH 096/112] [release-22.0] OnlineDDL: always close lock connection (#19586) (#19720) Signed-off-by: Tim Vaillancourt Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Tim Vaillancourt --- go/vt/vttablet/onlineddl/executor.go | 98 +++++++++++++++++++++------- 1 file changed, 75 insertions(+), 23 deletions(-) diff --git a/go/vt/vttablet/onlineddl/executor.go b/go/vt/vttablet/onlineddl/executor.go index c8f9c261aff..7c9fa4aaf65 100644 --- a/go/vt/vttablet/onlineddl/executor.go +++ b/go/vt/vttablet/onlineddl/executor.go @@ -74,18 +74,18 @@ var ( ErrMigrationNotFound = errors.New("migration not found") ) +// fixCompletedTimestampDone fixes a nil `completed_timestamp` columns, see +// https://github.com/vitessio/vitess/issues/13927 +// The fix is in release-18.0 +// TODO: remove in release-19.0 +var fixCompletedTimestampDone bool + var ( - // fixCompletedTimestampDone fixes a nil `completed_timestamp` columns, see - // https://github.com/vitessio/vitess/issues/13927 - // The fix is in release-18.0 - // TODO: remove in release-19.0 - fixCompletedTimestampDone bool + emptyResult = &sqltypes.Result{} + acceptableDropTableIfExistsErrorCodes = []sqlerror.ErrorCode{sqlerror.ERCantFindFile, sqlerror.ERNoSuchTable} + copyAlgorithm = sqlparser.AlgorithmValue(sqlparser.CopyStr) ) -var emptyResult = &sqltypes.Result{} -var acceptableDropTableIfExistsErrorCodes = []sqlerror.ErrorCode{sqlerror.ERCantFindFile, sqlerror.ERNoSuchTable} -var copyAlgorithm = sqlparser.AlgorithmValue(sqlparser.CopyStr) - var ( migrationCheckInterval = 1 * time.Minute retainOnlineDDLTables = 24 * time.Hour @@ -498,7 +498,6 @@ func (e *Executor) executeDirectly(ctx context.Context, onlineDDL *schema.Online defer conn.ExecuteFetch("SET foreign_key_checks=@vt_onlineddl_foreign_key_checks", 0, false) } _, err = conn.ExecuteFetch(onlineDDL.SQL, 0, false) - if err != nil { // let's see if this error is actually acceptable if merr, ok := err.(*sqlerror.SQLError); ok { @@ -876,11 +875,26 @@ func (e *Executor) cutOverVReplMigration(ctx context.Context, s *VReplStream, sh e.updateMigrationStage(ctx, onlineDDL.UUID, "post-sentry pos reached") } + renameWasSuccessful := false lockConn, err := e.pool.Get(ctx, nil) if err != nil { return vterrors.Wrapf(err, "failed getting locking connection") } defer lockConn.Recycle() + defer func() { + // Always attempt UNLOCK TABLES first, as it releases locks immediately on this + // connection. Then kill the connection as a fallback to guarantee any held locks + // are released, even if UNLOCK TABLES were to fail. + unlockCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if _, err := lockConn.Conn.Exec(unlockCtx, sqlUnlockTables, 1, false); err != nil { + log.Warningf("Failed to UNLOCK TABLES in OnlineDDL migration %s: %v", onlineDDL.UUID, err) + } + if err := lockConn.Conn.Kill("closing lock tables connection", 0); err != nil { + log.Warningf("Failed to kill lock tables connection in OnlineDDL migration %s: %v", onlineDDL.UUID, err) + } + }() + // Set large enough `@@lock_wait_timeout` so that it does not interfere with the cut-over operation. // The code will ensure everything that needs to be terminated by `onlineDDL.CutOverThreshold` will be terminated. lockConnRestoreLockWaitTimeout, err := e.initConnectionLockWaitTimeout(ctx, lockConn.Conn, 5*onlineDDL.CutOverThreshold) @@ -888,10 +902,8 @@ func (e *Executor) cutOverVReplMigration(ctx context.Context, s *VReplStream, sh return vterrors.Wrapf(err, "failed setting lock_wait_timeout on locking connection") } defer lockConnRestoreLockWaitTimeout() - defer lockConn.Conn.Exec(ctx, sqlUnlockTables, 1, false) renameCompleteChan := make(chan error) - renameWasSuccessful := false renameConn, err := e.pool.Get(ctx, nil) if err != nil { return vterrors.Wrapf(err, "failed getting rename connection") @@ -1191,20 +1203,61 @@ func (e *Executor) initMigrationSQLMode(ctx context.Context, onlineDDL *schema.O return deferFunc, nil } -// initConnectionLockWaitTimeout sets the given lock_wait_timeout for the given connection, with a deferred value restoration function -func (e *Executor) initConnectionLockWaitTimeout(ctx context.Context, conn *connpool.Conn, lockWaitTimeout time.Duration) (deferFunc func(), err error) { +// initConnectionSessionTimeout saves the current value of the given session variable, sets it to the given duration, +// and returns a deferred restore function. +func (e *Executor) initConnectionSessionTimeout(ctx context.Context, conn *connpool.Conn, variable string, timeout time.Duration) (deferFunc func(), err error) { deferFunc = func() {} - if _, err := conn.Exec(ctx, `set @lock_wait_timeout=@@session.lock_wait_timeout`, 0, false); err != nil { - return deferFunc, vterrors.Errorf(vtrpcpb.Code_UNKNOWN, "could not read lock_wait_timeout: %v", err) + saveQuery, err := sqlparser.ParseAndBind( + fmt.Sprintf("set @%s=@@session.%s", variable, variable), + ) + if err != nil { + return deferFunc, err + } + if _, err := conn.Exec(ctx, saveQuery, 0, false); err != nil { + return deferFunc, vterrors.Wrapf(err, "could not read %s", variable) + } + setQuery, err := sqlparser.ParseAndBind( + fmt.Sprintf("set @@session.%s=%%a", variable), + sqltypes.Int64BindVariable(int64(timeout.Seconds())), + ) + if err != nil { + return deferFunc, err + } + if _, err := conn.Exec(ctx, setQuery, 0, false); err != nil { + return deferFunc, err + } + restoreQuery, err := sqlparser.ParseAndBind( + fmt.Sprintf("set @@session.%s=@%s", variable, variable), + ) + if err != nil { + return deferFunc, err + } + deferFunc = func() { + conn.Exec(ctx, restoreQuery, 0, false) + } + return deferFunc, nil +} + +// initConnectionLockWaitTimeout sets the given lock_wait_timeout for the given connection, with a deferred value restoration function. +func (e *Executor) initConnectionLockWaitTimeout(ctx context.Context, conn *connpool.Conn, timeout time.Duration) (func(), error) { + return e.initConnectionSessionTimeout(ctx, conn, "lock_wait_timeout", timeout) +} + +// initDBConnectionLockWaitTimeout sets the given lock_wait_timeout for the given direct connection, with a deferred value restoration function. +func (e *Executor) initDBConnectionLockWaitTimeout(conn *dbconnpool.DBConnection, lockWaitTimeout time.Duration) (deferFunc func(), err error) { + deferFunc = func() {} + + if _, err := conn.ExecuteFetch("set @lock_wait_timeout=@@session.lock_wait_timeout", 0, false); err != nil { + return deferFunc, vterrors.Wrap(err, "could not read lock_wait_timeout") } timeoutSeconds := int64(lockWaitTimeout.Seconds()) setQuery := fmt.Sprintf("set @@session.lock_wait_timeout=%d", timeoutSeconds) - if _, err := conn.Exec(ctx, setQuery, 0, false); err != nil { + if _, err := conn.ExecuteFetch(setQuery, 0, false); err != nil { return deferFunc, err } deferFunc = func() { - conn.Exec(ctx, "set @@session.lock_wait_timeout=@lock_wait_timeout", 0, false) + conn.ExecuteFetch("set @@session.lock_wait_timeout=@lock_wait_timeout", 0, false) } return deferFunc, nil } @@ -1463,7 +1516,6 @@ func (e *Executor) ExecuteWithVReplication(ctx context.Context, onlineDDL *schem } func (e *Executor) readMigration(ctx context.Context, uuid string) (onlineDDL *schema.OnlineDDL, row sqltypes.RowNamedValues, err error) { - query, err := sqlparser.ParseAndBind(sqlSelectMigration, sqltypes.StringBindVariable(uuid), ) @@ -2100,7 +2152,6 @@ func (e *Executor) executeRevert(ctx context.Context, onlineDDL *schema.OnlineDD // - empty, in which case the migration is noop and implicitly successful, or // - non-empty, in which case the migration turns to be an ALTER func (e *Executor) evaluateDeclarativeDiff(ctx context.Context, onlineDDL *schema.OnlineDDL) (diff schemadiff.EntityDiff, err error) { - // Modify the CREATE TABLE statement to indicate a different, made up table name, known as the "comparison table" ddlStmt, _, err := schema.ParseOnlineDDLStatement(onlineDDL.SQL, e.env.Environment().Parser()) if err != nil { @@ -3694,7 +3745,8 @@ func (e *Executor) updateSchemaAnalysis(ctx context.Context, uuid string, addedUniqueKeys, removedUniqueKeys int, removedUniqueKeyNames string, removedForeignKeyNames string, droppedNoDefaultColumnNames string, expandedColumnNames string, - revertibleNotes []string) error { + revertibleNotes []string, +) error { notes := strings.Join(revertibleNotes, "\n") query, err := sqlparser.ParseAndBind(sqlUpdateSchemaAnalysis, sqltypes.Int64BindVariable(int64(addedUniqueKeys)), @@ -4417,7 +4469,6 @@ func (e *Executor) SubmitMigration( ) if err != nil { return nil, vterrors.Wrapf(err, "submitting migration %v", onlineDDL.UUID) - } log.Infof("SubmitMigration: migration %s submitted", onlineDDL.UUID) @@ -4486,7 +4537,8 @@ func (e *Executor) ShowMigrationLogs(ctx context.Context, stmt *sqlparser.ShowMi // onSchemaMigrationStatus is called when a status is set/changed for a running migration func (e *Executor) onSchemaMigrationStatus(ctx context.Context, - uuid string, status schema.OnlineDDLStatus, dryRun bool, progressPct float64, etaSeconds int64, rowsCopied int64, hint string) (err error) { + uuid string, status schema.OnlineDDLStatus, dryRun bool, progressPct float64, etaSeconds int64, rowsCopied int64, hint string, +) (err error) { if dryRun && status != schema.OnlineDDLStatusFailed { // We don't consider dry-run reports unless there's a failure return nil From ee1740799c7db448851fadc658894fdf0565c416 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 19:51:31 +0100 Subject: [PATCH 097/112] [release-22.0] `ci`: skip Code Coverage CI on backports (#19726) (#19736) Signed-off-by: Tim Vaillancourt Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- .github/workflows/codecov.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index c31570d461f..58b39704e7e 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -17,6 +17,7 @@ permissions: read-all jobs: test: + if: github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'Backport') name: Code Coverage runs-on: oracle-vm-8cpu-32gb-x86-64 From 59d687366671acb6842cad883a684a350ce7f75d Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Sat, 28 Mar 2026 10:46:59 +0100 Subject: [PATCH 098/112] [release-22.0] VTGate: fix warming reads timeout context (#19674) (#19727) Signed-off-by: Tim Vaillancourt Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Tim Vaillancourt --- go/vt/vtgate/engine/fake_vcursor_test.go | 21 +- go/vt/vtgate/engine/primitive.go | 9 +- go/vt/vtgate/engine/route.go | 23 +- .../vtgate/engine/route_warming_reads_test.go | 291 ++++++++++++++++++ go/vt/vtgate/executorcontext/vcursor_impl.go | 22 +- 5 files changed, 342 insertions(+), 24 deletions(-) create mode 100644 go/vt/vtgate/engine/route_warming_reads_test.go diff --git a/go/vt/vtgate/engine/fake_vcursor_test.go b/go/vt/vtgate/engine/fake_vcursor_test.go index df7093a773f..994e543c61d 100644 --- a/go/vt/vtgate/engine/fake_vcursor_test.go +++ b/go/vt/vtgate/engine/fake_vcursor_test.go @@ -120,6 +120,10 @@ func (t *noopVCursor) CloneForReplicaWarming(ctx context.Context) VCursor { panic("implement me") } +func (t *noopVCursor) WarmingReadsContext(ctx context.Context) (context.Context, context.CancelFunc) { + panic("implement me") +} + func (t *noopVCursor) CloneForMirroring(ctx context.Context) VCursor { panic("implement me") } @@ -410,6 +414,7 @@ func (t *noopVCursor) DisableLogging() {} func (t *noopVCursor) GetVExplainLogs() []ExecuteEntry { return nil } + func (t *noopVCursor) GetLogs() ([]ExecuteEntry, error) { return nil, nil } @@ -463,10 +468,11 @@ type loggingVCursor struct { parser *sqlparser.Parser - onMirrorClonesFn func(context.Context) VCursor - onExecuteMultiShardFn func(context.Context, Primitive, []*srvtopo.ResolvedShard, []*querypb.BoundQuery, bool, bool) - onStreamExecuteMultiFn func(context.Context, Primitive, string, []*srvtopo.ResolvedShard, []map[string]*querypb.BindVariable, bool, bool, func(*sqltypes.Result) error) - onRecordMirrorStatsFn func(time.Duration, time.Duration, error) + onMirrorClonesFn func(context.Context) VCursor + onExecuteMultiShardFn func(context.Context, Primitive, []*srvtopo.ResolvedShard, []*querypb.BoundQuery, bool, bool) + onStreamExecuteMultiFn func(context.Context, Primitive, string, []*srvtopo.ResolvedShard, []map[string]*querypb.BindVariable, bool, bool, func(*sqltypes.Result) error) + onRecordMirrorStatsFn func(time.Duration, time.Duration, error) + onResolveDestinationsFn func(context.Context) } func (f *loggingVCursor) HasCreatedTempTable() { @@ -586,6 +592,10 @@ func (f *loggingVCursor) CloneForReplicaWarming(ctx context.Context) VCursor { return f } +func (f *loggingVCursor) WarmingReadsContext(ctx context.Context) (context.Context, context.CancelFunc) { + return ctx, func() {} +} + func (f *loggingVCursor) CloneForMirroring(ctx context.Context) VCursor { if f.onMirrorClonesFn != nil { return f.onMirrorClonesFn(ctx) @@ -649,6 +659,9 @@ func (f *loggingVCursor) StreamExecuteMulti(ctx context.Context, primitive Primi } func (f *loggingVCursor) ResolveDestinations(ctx context.Context, keyspace string, ids []*querypb.Value, destinations []key.ShardDestination) ([]*srvtopo.ResolvedShard, [][]*querypb.Value, error) { + if f.onResolveDestinationsFn != nil { + f.onResolveDestinationsFn(ctx) + } f.log = append(f.log, fmt.Sprintf("ResolveDestinations %v %v %v", keyspace, ids, key.DestinationsString(destinations))) if f.shardErr != nil { return nil, nil, f.shardErr diff --git a/go/vt/vtgate/engine/primitive.go b/go/vt/vtgate/engine/primitive.go index be65bcde831..b02be414d46 100644 --- a/go/vt/vtgate/engine/primitive.go +++ b/go/vt/vtgate/engine/primitive.go @@ -129,9 +129,16 @@ type ( // GetWarmingReadsChannel returns the channel for executing warming reads against replicas GetWarmingReadsChannel() chan bool - // CloneForReplicaWarming clones the VCursor for re-use in warming queries to replicas + // CloneForReplicaWarming clones the VCursor for re-use in warming queries to replicas. + // The clone must be created before launching the warming goroutine to avoid + // concurrent access to the original VCursor. Use WarmingReadsContext on the + // clone to obtain a timeout-bounded context for the warming query. CloneForReplicaWarming(ctx context.Context) VCursor + // WarmingReadsContext returns a timeout-bounded context for a warming query + // and a cancel function that must be called when the warming query completes. + WarmingReadsContext(ctx context.Context) (context.Context, context.CancelFunc) + // CloneForMirroring clones the VCursor for re-use in mirroring queries to other keyspaces CloneForMirroring(ctx context.Context) VCursor // diff --git a/go/vt/vtgate/engine/route.go b/go/vt/vtgate/engine/route.go index a43299961e6..dfa79b196b9 100644 --- a/go/vt/vtgate/engine/route.go +++ b/go/vt/vtgate/engine/route.go @@ -41,12 +41,10 @@ import ( var _ Primitive = (*Route)(nil) -var ( - replicaWarmingReadsMirrored = stats.NewCountersWithMultiLabels( - "ReplicaWarmingReadsMirrored", - "Number of reads mirrored to replicas to warm their bufferpools", - []string{"Keyspace"}) -) +var replicaWarmingReadsMirrored = stats.NewCountersWithMultiLabels( + "ReplicaWarmingReadsMirrored", + "Number of reads mirrored to replicas to warm their bufferpools", + []string{"Keyspace"}) // Route represents the instructions to route a read query to // one or many vttablets. @@ -106,9 +104,7 @@ func NewRoute(opcode Opcode, keyspace *vindexes.Keyspace, query, fieldQuery stri } } -var ( - partialSuccessScatterQueries = stats.NewCounter("PartialSuccessScatterQueries", "Count of partially successful scatter queries") -) +var partialSuccessScatterQueries = stats.NewCounter("PartialSuccessScatterQueries", "Count of partially successful scatter queries") // RouteType returns a description of the query routing type used by the primitive func (route *Route) RouteType() string { @@ -531,22 +527,25 @@ func (route *Route) executeWarmingReplicaRead(ctx context.Context, vcursor VCurs return } - replicaVCursor := vcursor.CloneForReplicaWarming(ctx) warmingReadsChannel := vcursor.GetWarmingReadsChannel() select { // if there's no more room in the channel, drop the warming read case warmingReadsChannel <- true: + replicaVCursor := vcursor.CloneForReplicaWarming(ctx) go func(replicaVCursor VCursor) { + warmingCtx, cancel := replicaVCursor.WarmingReadsContext(ctx) + // Defers run LIFO: channel slot is released first, then context is canceled. + defer cancel() defer func() { <-warmingReadsChannel }() - rss, _, err := route.findRoute(ctx, replicaVCursor, bindVars) + rss, _, err := route.findRoute(warmingCtx, replicaVCursor, bindVars) if err != nil { return } - _, errs := replicaVCursor.ExecuteMultiShard(ctx, route, rss, queries, false /*rollbackOnError*/, false /*canAutocommit*/, route.FetchLastInsertID) + _, errs := replicaVCursor.ExecuteMultiShard(warmingCtx, route, rss, queries, false /*rollbackOnError*/, false /*canAutocommit*/, route.FetchLastInsertID) if len(errs) > 0 { log.Warningf("Failed to execute warming replica read: %v", errs) } else { diff --git a/go/vt/vtgate/engine/route_warming_reads_test.go b/go/vt/vtgate/engine/route_warming_reads_test.go new file mode 100644 index 00000000000..ce3202ec005 --- /dev/null +++ b/go/vt/vtgate/engine/route_warming_reads_test.go @@ -0,0 +1,291 @@ +/* +Copyright 2026 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package engine + +import ( + "context" + "sync/atomic" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/srvtopo" + "vitess.io/vitess/go/vt/vtgate/evalengine" + "vitess.io/vitess/go/vt/vtgate/vindexes" + + querypb "vitess.io/vitess/go/vt/proto/query" +) + +type warmingReadsVCursor struct { + *loggingVCursor + warmingReadsPercent int + warmingReadsChannel chan bool + warmingReadsTimeout time.Duration + warmingReadsExecuteFunc func(context.Context, Primitive, []*srvtopo.ResolvedShard, []*querypb.BoundQuery, bool, bool) +} + +func (vc *warmingReadsVCursor) GetWarmingReadsPercent() int { + return vc.warmingReadsPercent +} + +func (vc *warmingReadsVCursor) GetWarmingReadsChannel() chan bool { + return vc.warmingReadsChannel +} + +func (vc *warmingReadsVCursor) CloneForReplicaWarming(ctx context.Context) VCursor { + clonedLogging := &loggingVCursor{ + shards: vc.shards, + results: vc.results, + onResolveDestinationsFn: vc.onResolveDestinationsFn, + } + clone := &warmingReadsVCursor{ + loggingVCursor: clonedLogging, + warmingReadsPercent: vc.warmingReadsPercent, + warmingReadsChannel: vc.warmingReadsChannel, + warmingReadsTimeout: vc.warmingReadsTimeout, + warmingReadsExecuteFunc: vc.warmingReadsExecuteFunc, + } + clone.onExecuteMultiShardFn = vc.warmingReadsExecuteFunc + return clone +} + +func (vc *warmingReadsVCursor) WarmingReadsContext(ctx context.Context) (context.Context, context.CancelFunc) { + return context.WithTimeout(context.Background(), vc.warmingReadsTimeout) +} + +func TestWarmingReadsSkipsForUpdate(t *testing.T) { + vindex, _ := vindexes.CreateVindex("hash", "", nil) + testCases := []struct { + name string + query string + expectedWarmingQuery string + }{ + { + name: "SELECT FOR UPDATE", + query: "SELECT * FROM users WHERE id = 1 FOR UPDATE", + expectedWarmingQuery: "SELECT * FROM users WHERE id = 1 FOR UPDATE", + }, + { + name: "SELECT FOR UPDATE mixed case", + query: "SELECT * FROM users WHERE id = 1 FoR UpDaTe", + expectedWarmingQuery: "SELECT * FROM users WHERE id = 1 FoR UpDaTe", + }, + { + name: "SELECT FOR UPDATE with extra spaces", + query: "SELECT * FROM users WHERE id = 1 FOR UPDATE", + expectedWarmingQuery: "SELECT * FROM users WHERE id = 1 FOR UPDATE", + }, + { + name: "SELECT FOR UPDATE with comment", + query: "SELECT * FROM users WHERE id = 1 FOR /* comment */ UPDATE", + expectedWarmingQuery: "SELECT * FROM users WHERE id = 1 FOR /* comment */ UPDATE", + }, + { + name: "SELECT FOR UPDATE NOWAIT", + query: "SELECT * FROM users WHERE id = 1 FOR UPDATE NOWAIT", + expectedWarmingQuery: "SELECT * FROM users WHERE id = 1 FOR UPDATE NOWAIT", + }, + { + name: "SELECT FOR UPDATE SKIP LOCKED", + query: "SELECT * FROM users WHERE id = 1 FOR UPDATE SKIP LOCKED", + expectedWarmingQuery: "SELECT * FROM users WHERE id = 1 FOR UPDATE SKIP LOCKED", + }, + { + name: "UNION FOR UPDATE", + query: "SELECT * FROM users WHERE id = 1 UNION SELECT * FROM users WHERE id = 2 FOR UPDATE", + expectedWarmingQuery: "SELECT * FROM users WHERE id = 1 UNION SELECT * FROM users WHERE id = 2 FOR UPDATE", + }, + { + name: "Regular SELECT", + query: "SELECT * FROM users WHERE id = 1", + expectedWarmingQuery: "SELECT * FROM users WHERE id = 1", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + route := NewRoute( + EqualUnique, + &vindexes.Keyspace{ + Name: "ks", + Sharded: true, + }, + tc.query, + "dummy_select_field", + ) + route.Vindex = vindex.(vindexes.SingleColumn) + route.Values = []evalengine.Expr{ + evalengine.NewLiteralInt(1), + } + + var warmingReadExecuted atomic.Bool + var capturedQuery string + var capturedCtxHasDeadline atomic.Bool + var capturedCtxErr atomic.Pointer[error] + var resolveDestCtxHasDeadline atomic.Bool + // done is closed by the test to unblock the warming read goroutine + // after context assertions have been made. + done := make(chan struct{}) + vc := &warmingReadsVCursor{ + loggingVCursor: &loggingVCursor{ + shards: []string{"-20", "20-"}, + results: []*sqltypes.Result{defaultSelectResult}, + onResolveDestinationsFn: func(ctx context.Context) { + _, hasDeadline := ctx.Deadline() + resolveDestCtxHasDeadline.Store(hasDeadline) + }, + }, + warmingReadsPercent: 100, + warmingReadsChannel: make(chan bool, 1), + warmingReadsTimeout: 5 * time.Second, + } + vc.warmingReadsExecuteFunc = func(ctx context.Context, primitive Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, rollbackOnError, canAutocommit bool) { + if len(queries) > 0 { + capturedQuery = queries[0].Sql + } + _, hasDeadline := ctx.Deadline() + capturedCtxHasDeadline.Store(hasDeadline) + ctxErr := ctx.Err() + capturedCtxErr.Store(&ctxErr) + warmingReadExecuted.Store(true) + // Block until the test has checked our context assertions, + // preventing defer cancel() from running. + select { + case <-done: + case <-t.Context().Done(): + } + } + + // Use a cancelable parent context to verify the warming read + // context is independent of the parent request context. + parentCtx, parentCancel := context.WithCancel(t.Context()) + _, err := route.TryExecute(parentCtx, vc, map[string]*querypb.BindVariable{}, false) + require.NoError(t, err) + + // Cancel the parent context to simulate the primary request completing. + parentCancel() + + require.Eventually(t, func() bool { + return warmingReadExecuted.Load() + }, time.Second, 10*time.Millisecond, "warming read should be executed") + + require.Equal(t, tc.expectedWarmingQuery, capturedQuery, "warming read query should match expected") + require.True(t, capturedCtxHasDeadline.Load(), "warming read context should have a deadline from the timeout") + + // The warming read context should still be active even though the + // parent request context was canceled. + require.NoError(t, *capturedCtxErr.Load(), "warming read context should not be canceled when parent context is canceled") + + // Verify findRoute received the warming context (with deadline), not the parent context. + require.True(t, resolveDestCtxHasDeadline.Load(), "ResolveDestinations should receive a context with deadline from the warming timeout") + + // Unblock the warming read goroutine. + close(done) + }) + } +} + +func TestWarmingReadsDroppedWhenChannelFull(t *testing.T) { + vindex, _ := vindexes.CreateVindex("hash", "", nil) + route := NewRoute( + EqualUnique, + &vindexes.Keyspace{ + Name: "ks", + Sharded: true, + }, + "SELECT * FROM users WHERE id = 1", + "dummy_select_field", + ) + route.Vindex = vindex.(vindexes.SingleColumn) + route.Values = []evalengine.Expr{ + evalengine.NewLiteralInt(1), + } + + var warmingReadExecuted atomic.Bool + vc := &warmingReadsVCursor{ + loggingVCursor: &loggingVCursor{ + shards: []string{"-20", "20-"}, + results: []*sqltypes.Result{defaultSelectResult}, + }, + warmingReadsPercent: 100, + warmingReadsChannel: make(chan bool, 1), + warmingReadsTimeout: 5 * time.Second, + } + vc.warmingReadsExecuteFunc = func(ctx context.Context, primitive Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, rollbackOnError, canAutocommit bool) { + warmingReadExecuted.Store(true) + } + + // Pre-fill the channel to simulate a full pool. + vc.warmingReadsChannel <- true + + _, err := route.TryExecute(t.Context(), vc, map[string]*querypb.BindVariable{}, false) + require.NoError(t, err) + + // Verify over a short window that no warming read is executed while the channel is full. + require.Never(t, func() bool { + return warmingReadExecuted.Load() + }, 100*time.Millisecond, 5*time.Millisecond, "warming read should not execute when the channel is full") + // Drain the channel. + <-vc.warmingReadsChannel +} + +func TestWarmingReadsContextTimeout(t *testing.T) { + vindex, _ := vindexes.CreateVindex("hash", "", nil) + route := NewRoute( + EqualUnique, + &vindexes.Keyspace{ + Name: "ks", + Sharded: true, + }, + "SELECT * FROM users WHERE id = 1", + "dummy_select_field", + ) + route.Vindex = vindex.(vindexes.SingleColumn) + route.Values = []evalengine.Expr{ + evalengine.NewLiteralInt(1), + } + + var capturedCtxErr atomic.Pointer[error] + var warmingReadExecuted atomic.Bool + vc := &warmingReadsVCursor{ + loggingVCursor: &loggingVCursor{ + shards: []string{"-20", "20-"}, + results: []*sqltypes.Result{defaultSelectResult}, + }, + warmingReadsPercent: 100, + warmingReadsChannel: make(chan bool, 1), + warmingReadsTimeout: 1 * time.Millisecond, + } + vc.warmingReadsExecuteFunc = func(ctx context.Context, primitive Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, rollbackOnError, canAutocommit bool) { + // Block until the warming context times out. + <-ctx.Done() + ctxErr := ctx.Err() + capturedCtxErr.Store(&ctxErr) + warmingReadExecuted.Store(true) + } + + _, err := route.TryExecute(t.Context(), vc, map[string]*querypb.BindVariable{}, false) + require.NoError(t, err) + + require.Eventually(t, func() bool { + return warmingReadExecuted.Load() + }, time.Second, 10*time.Millisecond, "warming read should have been executed and timed out") + + require.ErrorIs(t, *capturedCtxErr.Load(), context.DeadlineExceeded, "warming read context should have timed out") +} diff --git a/go/vt/vtgate/executorcontext/vcursor_impl.go b/go/vt/vtgate/executorcontext/vcursor_impl.go index 0b3ab09b8cc..806926234dd 100644 --- a/go/vt/vtgate/executorcontext/vcursor_impl.go +++ b/go/vt/vtgate/executorcontext/vcursor_impl.go @@ -286,12 +286,6 @@ func (vc *VCursorImpl) CloneForMirroring(ctx context.Context) engine.VCursor { } func (vc *VCursorImpl) CloneForReplicaWarming(ctx context.Context) engine.VCursor { - callerId := callerid.EffectiveCallerIDFromContext(ctx) - immediateCallerId := callerid.ImmediateCallerIDFromContext(ctx) - - timedCtx, _ := context.WithTimeout(context.Background(), vc.config.WarmingReadsTimeout) // nolint - clonedCtx := callerid.NewContext(timedCtx, callerId, immediateCallerId) - v := &VCursorImpl{ config: vc.config, SafeSession: NewAutocommitSession(vc.SafeSession.Session), @@ -302,7 +296,7 @@ func (vc *VCursorImpl) CloneForReplicaWarming(ctx context.Context) engine.VCurso executor: vc.executor, resolver: vc.resolver, topoServer: vc.topoServer, - logStats: &logstats.LogStats{Ctx: clonedCtx}, + logStats: &logstats.LogStats{}, ignoreMaxMemoryRows: vc.ignoreMaxMemoryRows, vschema: vc.vschema, @@ -317,6 +311,19 @@ func (vc *VCursorImpl) CloneForReplicaWarming(ctx context.Context) engine.VCurso return v } +func (vc *VCursorImpl) WarmingReadsContext(ctx context.Context) (context.Context, context.CancelFunc) { + callerId := callerid.EffectiveCallerIDFromContext(ctx) + immediateCallerId := callerid.ImmediateCallerIDFromContext(ctx) + + baseCtx := context.WithoutCancel(ctx) + timedCtx, cancel := context.WithTimeout(baseCtx, vc.config.WarmingReadsTimeout) + clonedCtx := callerid.NewContext(timedCtx, callerId, immediateCallerId) + + vc.logStats = &logstats.LogStats{Ctx: clonedCtx} + + return clonedCtx, cancel +} + func (vc *VCursorImpl) cloneWithAutocommitSession() *VCursorImpl { safeSession := vc.SafeSession.NewAutocommitSession() return &VCursorImpl{ @@ -1311,6 +1318,7 @@ func (vc *VCursorImpl) AddAdvisoryLock(name string) { func (vc *VCursorImpl) GetBindVars() map[string]*querypb.BindVariable { return vc.bindVars } + func (vc *VCursorImpl) SetBindVars(m map[string]*querypb.BindVariable) { vc.bindVars = m } From 8e90f6863a81ec87889e2d33231f8534afc2a6a6 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Sun, 29 Mar 2026 12:50:51 +0000 Subject: [PATCH 099/112] [release-22.0] tabletmanager: handle nil Cnf in MysqlHostMetrics to prevent panic (#19752) (#19753) Signed-off-by: Tetsuro Ohyama Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- go/vt/vttablet/tabletmanager/rpc_query.go | 3 +++ go/vt/vttablet/tabletmanager/rpc_query_test.go | 14 ++++++++++++++ .../throttle/base/self_metric_mysqld.go | 3 +++ 3 files changed, 20 insertions(+) diff --git a/go/vt/vttablet/tabletmanager/rpc_query.go b/go/vt/vttablet/tabletmanager/rpc_query.go index b0da7d9d71f..aa4fa1f130b 100644 --- a/go/vt/vttablet/tabletmanager/rpc_query.go +++ b/go/vt/vttablet/tabletmanager/rpc_query.go @@ -277,6 +277,9 @@ func (tm *TabletManager) ExecuteFetchAsApp(ctx context.Context, req *tabletmanag // MysqlHostMetrics gets system metrics from mysqlctl[d] func (tm *TabletManager) MysqlHostMetrics(ctx context.Context, req *tabletmanagerdatapb.MysqlHostMetricsRequest) (*tabletmanagerdatapb.MysqlHostMetricsResponse, error) { + if tm.Cnf == nil { + return &tabletmanagerdatapb.MysqlHostMetricsResponse{}, nil + } mysqlResp, err := tm.MysqlDaemon.HostMetrics(ctx, tm.Cnf) if err != nil { return nil, err diff --git a/go/vt/vttablet/tabletmanager/rpc_query_test.go b/go/vt/vttablet/tabletmanager/rpc_query_test.go index e30f63b362b..f7d11fa5a12 100644 --- a/go/vt/vttablet/tabletmanager/rpc_query_test.go +++ b/go/vt/vttablet/tabletmanager/rpc_query_test.go @@ -114,6 +114,20 @@ func TestAnalyzeExecuteFetchAsDbaMultiQuery(t *testing.T) { } } +func TestTabletManager_MysqlHostMetricsNilCnf(t *testing.T) { + ctx := context.Background() + // When using external MySQL (e.g. Cloud SQL, RDS), Cnf is nil because + // vttablet skips loading my.cnf when connection parameters are specified. + // MysqlHostMetrics should return an empty response instead of panicking. + tm := &TabletManager{ + Cnf: nil, + } + resp, err := tm.MysqlHostMetrics(ctx, &tabletmanagerdatapb.MysqlHostMetricsRequest{}) + require.NoError(t, err) + require.NotNil(t, resp) + assert.Nil(t, resp.HostMetrics) +} + func TestTabletManager_ExecuteFetchAsDba(t *testing.T) { ctx := context.Background() cp := mysql.ConnParams{} diff --git a/go/vt/vttablet/tabletserver/throttle/base/self_metric_mysqld.go b/go/vt/vttablet/tabletserver/throttle/base/self_metric_mysqld.go index 321837d86b4..e0faa6cd6d5 100644 --- a/go/vt/vttablet/tabletserver/throttle/base/self_metric_mysqld.go +++ b/go/vt/vttablet/tabletserver/throttle/base/self_metric_mysqld.go @@ -92,6 +92,9 @@ func getMysqlHostMetric(ctx context.Context, params *SelfMetricReadParams, mysql if resp == nil { return metric.WithError(ErrNoResultYet) } + if resp.HostMetrics == nil || resp.HostMetrics.Metrics == nil { + return metric.WithError(ErrNoSuchMetric) + } mysqlMetric := resp.HostMetrics.Metrics[mysqlHostMetricName] if mysqlMetric == nil { return metric.WithError(ErrNoSuchMetric) From 686495ced875cce8ecde09f6b79702de2a0250e0 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 11:32:09 +0200 Subject: [PATCH 100/112] [release-22.0] `ci`: only cache `action/setup-go` action on `main` (#19634) (#19637) Signed-off-by: Tim Vaillancourt Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Tim Vaillancourt Co-authored-by: Claude Opus 4.6 --- .github/workflows/check_make_vtadmin_authz_testgen.yml | 1 + .github/workflows/check_make_vtadmin_web_proto.yml | 1 + .github/workflows/cluster_endtoend.yml | 1 + .github/workflows/codecov.yml | 1 + .github/workflows/codeql_analysis.yml | 1 + .github/workflows/docker_ci.yml | 1 + .github/workflows/e2e_race.yml | 1 + .github/workflows/endtoend.yml | 1 + .github/workflows/local_example.yml | 1 + .github/workflows/region_example.yml | 1 + .github/workflows/static_checks_etc.yml | 1 + .github/workflows/unit_test.yml | 1 + .github/workflows/update_golang_dependencies.yml | 1 + .github/workflows/update_golang_version.yml | 1 + .github/workflows/vitess_tester_vtgate.yml | 1 + .github/workflows/vtop_example.yml | 1 + 16 files changed, 16 insertions(+) diff --git a/.github/workflows/check_make_vtadmin_authz_testgen.yml b/.github/workflows/check_make_vtadmin_authz_testgen.yml index 5b2c65dee94..7a7fd3336f2 100644 --- a/.github/workflows/check_make_vtadmin_authz_testgen.yml +++ b/.github/workflows/check_make_vtadmin_authz_testgen.yml @@ -52,6 +52,7 @@ jobs: if: steps.changes.outputs.vtadmin_changes == 'true' with: go-version-file: go.mod + cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }} - name: Get dependencies if: steps.changes.outputs.vtadmin_changes == 'true' diff --git a/.github/workflows/check_make_vtadmin_web_proto.yml b/.github/workflows/check_make_vtadmin_web_proto.yml index d1f159e43de..b3fa70683ad 100644 --- a/.github/workflows/check_make_vtadmin_web_proto.yml +++ b/.github/workflows/check_make_vtadmin_web_proto.yml @@ -53,6 +53,7 @@ jobs: if: steps.changes.outputs.proto_changes == 'true' with: go-version-file: go.mod + cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }} - name: Setup Node if: steps.changes.outputs.proto_changes == 'true' diff --git a/.github/workflows/cluster_endtoend.yml b/.github/workflows/cluster_endtoend.yml index 6109a9a2e77..1d7d385e656 100644 --- a/.github/workflows/cluster_endtoend.yml +++ b/.github/workflows/cluster_endtoend.yml @@ -130,6 +130,7 @@ jobs: uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: go-version-file: go.mod + cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }} - name: Set up python if: steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 58b39704e7e..4bd18ad2a68 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -56,6 +56,7 @@ jobs: uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: go-version-file: go.mod + cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }} - name: Detect changed Go packages if: steps.mode.outputs.is_full_run != 'true' && steps.changes.outputs.changed_files == 'true' diff --git a/.github/workflows/codeql_analysis.yml b/.github/workflows/codeql_analysis.yml index 842bcaf6026..0ed7fb32280 100644 --- a/.github/workflows/codeql_analysis.yml +++ b/.github/workflows/codeql_analysis.yml @@ -35,6 +35,7 @@ jobs: uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: go-version-file: go.mod + cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }} - name: Tune the OS uses: ./.github/actions/tune-os diff --git a/.github/workflows/docker_ci.yml b/.github/workflows/docker_ci.yml index a901660a02f..2cb181df5ef 100644 --- a/.github/workflows/docker_ci.yml +++ b/.github/workflows/docker_ci.yml @@ -79,6 +79,7 @@ jobs: uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: go-version-file: go.mod + cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }} - name: Tune the OS if: steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/e2e_race.yml b/.github/workflows/e2e_race.yml index ec934225c73..3d1270407e7 100644 --- a/.github/workflows/e2e_race.yml +++ b/.github/workflows/e2e_race.yml @@ -50,6 +50,7 @@ jobs: uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: go-version-file: go.mod + cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }} - name: Tune the OS if: steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/endtoend.yml b/.github/workflows/endtoend.yml index 6543990abd4..896da9babb5 100644 --- a/.github/workflows/endtoend.yml +++ b/.github/workflows/endtoend.yml @@ -50,6 +50,7 @@ jobs: uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: go-version-file: go.mod + cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }} - name: Tune the OS if: steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/local_example.yml b/.github/workflows/local_example.yml index 87311ffec6a..4959c81ea9d 100644 --- a/.github/workflows/local_example.yml +++ b/.github/workflows/local_example.yml @@ -65,6 +65,7 @@ jobs: uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: go-version-file: go.mod + cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }} - name: Tune the OS if: steps.changes.outputs.examples == 'true' diff --git a/.github/workflows/region_example.yml b/.github/workflows/region_example.yml index 210f917d808..b41c86084bf 100644 --- a/.github/workflows/region_example.yml +++ b/.github/workflows/region_example.yml @@ -65,6 +65,7 @@ jobs: uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: go-version-file: go.mod + cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }} - name: Tune the OS if: steps.changes.outputs.examples == 'true' diff --git a/.github/workflows/static_checks_etc.yml b/.github/workflows/static_checks_etc.yml index 642d769c6e1..e171c3078ba 100644 --- a/.github/workflows/static_checks_etc.yml +++ b/.github/workflows/static_checks_etc.yml @@ -121,6 +121,7 @@ jobs: uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: go-version-file: go.mod + cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }} - name: Tune the OS if: steps.changes.outputs.go_files == 'true' diff --git a/.github/workflows/unit_test.yml b/.github/workflows/unit_test.yml index dbbd998d5bc..467e7625b4c 100644 --- a/.github/workflows/unit_test.yml +++ b/.github/workflows/unit_test.yml @@ -111,6 +111,7 @@ jobs: uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 with: go-version-file: go.mod + cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }} - name: Set up python if: steps.changes.outputs.unit_tests == 'true' diff --git a/.github/workflows/update_golang_dependencies.yml b/.github/workflows/update_golang_dependencies.yml index c305f7eb904..17048750b88 100644 --- a/.github/workflows/update_golang_dependencies.yml +++ b/.github/workflows/update_golang_dependencies.yml @@ -26,6 +26,7 @@ jobs: uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: go-version-file: go.mod + cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }} - name: Upgrade the Golang Dependencies id: detect-and-update diff --git a/.github/workflows/update_golang_version.yml b/.github/workflows/update_golang_version.yml index 4a186fce1ba..99436915d24 100644 --- a/.github/workflows/update_golang_version.yml +++ b/.github/workflows/update_golang_version.yml @@ -28,6 +28,7 @@ jobs: uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: go-version-file: go.mod + cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }} - name: Detect new version and update codebase env: diff --git a/.github/workflows/vitess_tester_vtgate.yml b/.github/workflows/vitess_tester_vtgate.yml index 638dc534237..dc408eb156a 100644 --- a/.github/workflows/vitess_tester_vtgate.yml +++ b/.github/workflows/vitess_tester_vtgate.yml @@ -63,6 +63,7 @@ jobs: uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: go-version-file: go.mod + cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }} - name: Set up python if: steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/vtop_example.yml b/.github/workflows/vtop_example.yml index 84ac24daa23..78987fae545 100644 --- a/.github/workflows/vtop_example.yml +++ b/.github/workflows/vtop_example.yml @@ -55,6 +55,7 @@ jobs: uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: go-version-file: go.mod + cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }} - name: Tune the OS if: steps.changes.outputs.end_to_end == 'true' From 94b51e085ba297dd98170c7529a10d7ef018d5ef Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 11:55:32 +0200 Subject: [PATCH 101/112] [release-22.0] ci: use `bash -e {0}` in composite actions (#19707) (#19709) Signed-off-by: Nick Van Wiggeren Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Nick Van Wiggeren --- .github/actions/setup-mysql/action.yml | 2 +- .github/actions/tune-os/action.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/setup-mysql/action.yml b/.github/actions/setup-mysql/action.yml index 921e7733770..2698bd7e025 100644 --- a/.github/actions/setup-mysql/action.yml +++ b/.github/actions/setup-mysql/action.yml @@ -8,7 +8,7 @@ runs: using: "composite" steps: - name: Setup MySQL - shell: bash + shell: bash -e {0} run: | export DEBIAN_FRONTEND="noninteractive" sudo apt-get update diff --git a/.github/actions/tune-os/action.yml b/.github/actions/tune-os/action.yml index 618e3bfedd2..d3522c38d8a 100644 --- a/.github/actions/tune-os/action.yml +++ b/.github/actions/tune-os/action.yml @@ -4,7 +4,7 @@ runs: using: "composite" steps: - name: Tune the OS - shell: bash + shell: bash -e {0} run: | # Install eatmydata and ensure it's used for every operation sudo apt-get update && sudo apt-get install -y eatmydata From cd9c91d18951614fbb6d1c2b17a073cf3af8f3ff Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 15:21:00 +0200 Subject: [PATCH 102/112] [release-22.0] OnlineDDL: set `wait_timeout` on cutover connections (#19630) (#19760) Signed-off-by: Tim Vaillancourt Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Tim Vaillancourt --- .../scheduler/onlineddl_scheduler_test.go | 120 +++++++++++++++++- go/vt/vttablet/onlineddl/executor.go | 35 +++-- 2 files changed, 139 insertions(+), 16 deletions(-) diff --git a/go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go b/go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go index 84ffbe20f5e..9f3adcf887c 100644 --- a/go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go +++ b/go/test/endtoend/onlineddl/scheduler/onlineddl_scheduler_test.go @@ -23,6 +23,7 @@ import ( "math/rand/v2" "os" "path" + "strconv" "strings" "sync" "testing" @@ -242,7 +243,7 @@ func TestMain(m *testing.M) { defer clusterInstance.Teardown() if _, err := os.Stat(schemaChangeDirectory); os.IsNotExist(err) { - _ = os.Mkdir(schemaChangeDirectory, 0700) + _ = os.Mkdir(schemaChangeDirectory, 0o700) } clusterInstance.VtctldExtraArgs = []string{ @@ -294,11 +295,9 @@ func TestMain(m *testing.M) { } else { os.Exit(exitcode) } - } func TestSchedulerSchemaChanges(t *testing.T) { - throttler.EnableLagThrottlerAndWaitForStatus(t, clusterInstance) t.Run("scheduler", testScheduler) @@ -792,6 +791,117 @@ func testScheduler(t *testing.T) { }) }) } + + t.Run("low wait_timeout", func(t *testing.T) { + // Validate that OnlineDDL cutover increases wait_timeout on its connections + // when the server has a low wait_timeout configured. Without this protection, + // MySQL would kill cutover connections mid-operation, potentially causing + // data corruption. + ctx, cancel := context.WithTimeout(t.Context(), extendedWaitTime*5) + defer cancel() + + // Read the original wait_timeout. + rs, err := primaryTablet.VttabletProcess.QueryTabletWithDB("select @@global.wait_timeout as wait_timeout", "performance_schema") + require.NoError(t, err) + row := rs.Named().Row() + require.NotNil(t, row) + originalWaitTimeout := row.AsInt64("wait_timeout", 0) + require.NotZero(t, originalWaitTimeout) + + // Ensure the table exists (may not if running this subtest in isolation). + t.Run("ensure table exists", func(t *testing.T) { + uuid := testOnlineDDLStatement(t, createParams(createT1IfNotExistsStatement, ddlStrategy, "vtgate", "", "", false)) + onlineddl.CheckMigrationStatus(t, &vtParams, shards, uuid, schema.OnlineDDLStatusComplete) + }) + + t1uuid = testOnlineDDLStatement(t, createParams(trivialAlterT1Statement, ddlStrategy+" --postpone-completion", "vtgate", "", "", true)) // skip wait + + t.Run("wait for t1 running", func(t *testing.T) { + status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, t1uuid, normalWaitTime, schema.OnlineDDLStatusRunning) + fmt.Printf("# Migration status (for debug purposes): <%s>\n", status) + }) + t.Run("wait for t1 ready to complete", func(t *testing.T) { + waitForReadyToComplete(t, t1uuid, true) + }) + + // Set a dangerously low wait_timeout AFTER the migration is running and + // ready to complete. This way VReplication and other connections survive + // setup, but new connections (the cutover connections) inherit the low value. + t.Run("set low wait_timeout", func(t *testing.T) { + _, err = primaryTablet.VttabletProcess.QueryTabletWithDB("set global wait_timeout=5", "performance_schema") + require.NoError(t, err) + }) + defer primaryTablet.VttabletProcess.QueryTabletWithDB(fmt.Sprintf("set global wait_timeout=%d", originalWaitTimeout), "performance_schema") + + // Hold a WRITE lock on the table to stall the cutover's RENAME TABLE. + lockConn, err := primaryTablet.VttabletProcess.TabletConn(keyspaceName, true) + require.NoError(t, err) + defer lockConn.Close() + // Ensure our lock connection itself won't be killed. + _, err = lockConn.ExecuteFetch("set @@session.wait_timeout=28800", 0, false) + require.NoError(t, err) + + t.Run("lock table to stall cutover", func(t *testing.T) { + _, err := lockConn.ExecuteFetch("lock tables t1_test write", 0, false) + require.NoError(t, err) + }) + defer lockConn.ExecuteFetch("unlock tables", 0, false) + + t.Run("injecting heartbeats asynchronously", func(t *testing.T) { + go func() { + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + for { + throttler.CheckThrottler(&clusterInstance.VtctldClientProcess, primaryTablet, throttlerapp.OnlineDDLName, nil) + select { + case <-ticker.C: + case <-ctx.Done(): + return + } + } + }() + }) + + t.Run("complete migration", func(t *testing.T) { + onlineddl.CheckCompleteMigration(t, &vtParams, shards, t1uuid, true) + }) + + t.Run("validate cutover connections have increased wait_timeout", func(t *testing.T) { + // Wait for the cutover to be in-progress. The LOCK TABLES will be blocked by + // our held WRITE lock, so the lock connection should be visible in the + // processlist with state "Waiting for table metadata lock". + query := ` + SELECT v.VARIABLE_VALUE as wait_timeout + FROM performance_schema.threads t + JOIN performance_schema.variables_by_thread v ON v.THREAD_ID = t.THREAD_ID + WHERE v.VARIABLE_NAME = 'wait_timeout' + AND t.PROCESSLIST_STATE = 'Waiting for table metadata lock' + AND t.PROCESSLIST_INFO LIKE 'LOCK TABLES%' + ` + assert.Eventually(t, func() bool { + rs, err := primaryTablet.VttabletProcess.QueryTabletWithDB(query, "performance_schema") + if err != nil { + return false + } + for _, row := range rs.Named().Rows { + waitTimeout, _ := strconv.ParseInt(row.AsString("wait_timeout", "0"), 10, 64) + if waitTimeout == 31536000 { + // Validated! Release the lock so the cutover can proceed. + lockConn.ExecuteFetch("unlock tables", 0, false) + return true + } + } + return false + }, normalWaitTime, time.Second, "expected cutover connection to have wait_timeout == 31536000") + }) + + t.Run("expect completion", func(t *testing.T) { + status := onlineddl.WaitForMigrationStatus(t, &vtParams, shards, t1uuid, normalWaitTime, schema.OnlineDDLStatusComplete, schema.OnlineDDLStatusFailed) + fmt.Printf("# Migration status (for debug purposes): <%s>\n", status) + onlineddl.CheckMigrationStatus(t, &vtParams, shards, t1uuid, schema.OnlineDDLStatusComplete) + }) + }) + t.Run("ALTER both tables non-concurrent", func(t *testing.T) { t1uuid = testOnlineDDLStatement(t, createParams(trivialAlterT1Statement, ddlStrategy, "vtgate", "", "", true)) // skip wait t2uuid = testOnlineDDLStatement(t, createParams(trivialAlterT2Statement, ddlStrategy, "vtgate", "", "", true)) // skip wait @@ -1964,6 +2074,7 @@ DROP TABLE IF EXISTS stress_test onlineddl.CheckMigrationStatus(t, &vtParams, shards, revertUUID, schema.OnlineDDLStatusCancelled) }) } + func testDeclarative(t *testing.T) { shards = clusterInstance.Keyspaces[0].Shards require.Equal(t, 1, len(shards)) @@ -2636,7 +2747,6 @@ func testDeclarative(t *testing.T) { } func testForeignKeys(t *testing.T) { - var ( createStatements = []string{ ` @@ -2685,7 +2795,7 @@ func testForeignKeys(t *testing.T) { expectCountUUIDs int onlyIfFKOnlineDDLPossible bool } - var testCases = []testCase{ + testCases := []testCase{ { name: "modify parent, not allowed", sql: "alter table parent_table engine=innodb", diff --git a/go/vt/vttablet/onlineddl/executor.go b/go/vt/vttablet/onlineddl/executor.go index 7c9fa4aaf65..fba86a6f2e2 100644 --- a/go/vt/vttablet/onlineddl/executor.go +++ b/go/vt/vttablet/onlineddl/executor.go @@ -96,9 +96,10 @@ var ( ) const ( - defaultCutOverThreshold = 10 * time.Second - minCutOverThreshold = 5 * time.Second - maxCutOverThreshold = 30 * time.Second + defaultCutOverThreshold = 10 * time.Second + minCutOverThreshold = 5 * time.Second + maxCutOverThreshold = 30 * time.Second + waitTimeoutDuringCutOver = 365 * 24 * time.Hour // maximum MySQL wait_timeout ) func init() { @@ -891,7 +892,7 @@ func (e *Executor) cutOverVReplMigration(ctx context.Context, s *VReplStream, sh log.Warningf("Failed to UNLOCK TABLES in OnlineDDL migration %s: %v", onlineDDL.UUID, err) } if err := lockConn.Conn.Kill("closing lock tables connection", 0); err != nil { - log.Warningf("Failed to kill lock tables connection in OnlineDDL migration %s: %v", onlineDDL.UUID, err) + log.Errorf("Failed to kill lock tables connection in OnlineDDL migration %s: %v", onlineDDL.UUID, err) } }() @@ -902,18 +903,17 @@ func (e *Executor) cutOverVReplMigration(ctx context.Context, s *VReplStream, sh return vterrors.Wrapf(err, "failed setting lock_wait_timeout on locking connection") } defer lockConnRestoreLockWaitTimeout() + lockConnRestoreWaitTimeout, err := e.initConnectionSessionTimeout(ctx, lockConn.Conn, "wait_timeout", waitTimeoutDuringCutOver) + if err != nil { + return vterrors.Wrapf(err, "failed ensuring wait_timeout on locking connection") + } + defer lockConnRestoreWaitTimeout() renameCompleteChan := make(chan error) renameConn, err := e.pool.Get(ctx, nil) if err != nil { return vterrors.Wrapf(err, "failed getting rename connection") } - // Set large enough `@@lock_wait_timeout` so that it does not interfere with the cut-over operation. - // The code will ensure everything that needs to be terminated by `onlineDDL.CutOverThreshold` will be terminated. - renameConnRestoreLockWaitTimeout, err := e.initConnectionLockWaitTimeout(ctx, renameConn.Conn, 5*onlineDDL.CutOverThreshold*4) - if err != nil { - return vterrors.Wrapf(err, "failed setting lock_wait_timeout on rename connection") - } defer renameConn.Recycle() defer func() { if !renameWasSuccessful { @@ -923,7 +923,18 @@ func (e *Executor) cutOverVReplMigration(ctx context.Context, s *VReplStream, sh } } }() + // Set large enough `@@lock_wait_timeout` so that it does not interfere with the cut-over operation. + // The code will ensure everything that needs to be terminated by `onlineDDL.CutOverThreshold` will be terminated. + renameConnRestoreLockWaitTimeout, err := e.initConnectionLockWaitTimeout(ctx, renameConn.Conn, 2*onlineDDL.CutOverThreshold) + if err != nil { + return vterrors.Wrapf(err, "failed setting lock_wait_timeout on rename connection") + } defer renameConnRestoreLockWaitTimeout() + renameConnRestoreWaitTimeout, err := e.initConnectionSessionTimeout(ctx, renameConn.Conn, "wait_timeout", waitTimeoutDuringCutOver) + if err != nil { + return vterrors.Wrapf(err, "failed ensuring wait_timeout on rename connection") + } + defer renameConnRestoreWaitTimeout() // See if backend MySQL server supports 'rename_table_preserve_foreign_key' variable preserveFKSupported, err := e.isPreserveForeignKeySupported(ctx) @@ -1234,7 +1245,9 @@ func (e *Executor) initConnectionSessionTimeout(ctx context.Context, conn *connp return deferFunc, err } deferFunc = func() { - conn.Exec(ctx, restoreQuery, 0, false) + restoreCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + conn.Exec(restoreCtx, restoreQuery, 0, false) } return deferFunc, nil } From 60f438bbaf2b5f82a79293ee71581ee361c6e731 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 15:22:37 +0200 Subject: [PATCH 103/112] [release-22.0] sqlparser: enforce bare `*` restriction in grammar (#19585) (#19718) Signed-off-by: Arthur Schreiber Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Arthur Schreiber --- go/vt/sqlparser/parse_test.go | 4 +- go/vt/sqlparser/sql.go | 14556 ++++++++-------- go/vt/sqlparser/sql.y | 28 +- .../planbuilder/testdata/dml_cases.json | 2 +- .../testdata/unknown_schema_cases.json | 2 +- .../vreplication/replicator_plan_test.go | 2 +- .../vstreamer/planbuilder_test.go | 2 +- 7 files changed, 7372 insertions(+), 7224 deletions(-) diff --git a/go/vt/sqlparser/parse_test.go b/go/vt/sqlparser/parse_test.go index 70bf24e140e..1e944dd5caf 100644 --- a/go/vt/sqlparser/parse_test.go +++ b/go/vt/sqlparser/parse_test.go @@ -6339,10 +6339,10 @@ var ( output: "syntax error at position 39", }, { input: "select a, * from t", - output: "syntax error: unexpected '*' at position 12", + output: "syntax error at position 12", }, { input: "select *, * from t", - output: "syntax error: unexpected '*' at position 12", + output: "syntax error at position 12", }} ) diff --git a/go/vt/sqlparser/sql.go b/go/vt/sqlparser/sql.go index dcea38cb51e..e8a5a05519f 100644 --- a/go/vt/sqlparser/sql.go +++ b/go/vt/sqlparser/sql.go @@ -1615,179 +1615,179 @@ var yyExca = [...]int{ 16, 110, -2, 6, -1, 57, - 1, 225, - 787, 225, - -2, 233, + 1, 227, + 787, 227, + -2, 235, -1, 58, - 148, 233, - 192, 233, - 376, 233, - -2, 593, + 148, 235, + 192, 235, + 376, 235, + -2, 595, -1, 66, - 37, 855, - 265, 855, - 276, 855, - 312, 869, - 313, 869, - -2, 857, + 37, 857, + 265, 857, + 276, 857, + 312, 871, + 313, 871, + -2, 859, -1, 71, - 267, 893, - -2, 891, + 267, 895, + -2, 893, -1, 132, - 1, 226, - 787, 226, - -2, 233, + 1, 228, + 787, 228, + -2, 235, -1, 143, - 149, 478, - 270, 478, - -2, 582, + 149, 480, + 270, 480, + -2, 584, -1, 162, - 148, 233, - 192, 233, - 376, 233, - -2, 602, + 148, 235, + 192, 235, + 376, 235, + -2, 604, -1, 780, 177, 102, -2, 104, -1, 989, - 94, 1731, - -2, 1553, + 94, 1733, + -2, 1555, -1, 990, - 94, 1732, - 237, 1736, - -2, 1554, + 94, 1734, + 237, 1738, + -2, 1556, -1, 991, - 237, 1735, + 237, 1737, -2, 103, -1, 1077, - 64, 967, - -2, 980, + 64, 969, + -2, 982, -1, 1082, - 264, 1714, - -2, 1623, - -1, 1164, - 275, 1180, - 280, 1180, - -2, 489, - -1, 1252, - 1, 650, - 787, 650, - -2, 233, - -1, 1577, - 237, 1736, - -2, 1554, - -1, 1790, - 64, 968, - -2, 984, + 264, 1716, + -2, 1625, + -1, 1165, + 275, 1182, + 280, 1182, + -2, 491, + -1, 1253, + 1, 652, + 787, 652, + -2, 235, + -1, 1578, + 237, 1738, + -2, 1556, -1, 1791, - 64, 969, - -2, 985, - -1, 1868, - 148, 233, - 192, 233, - 376, 233, - -2, 528, - -1, 1945, - 149, 478, - 270, 478, - -2, 582, - -1, 1954, - 275, 1181, - 280, 1181, - -2, 490, - -1, 2402, - 237, 1740, + 64, 970, + -2, 986, + -1, 1792, + 64, 971, + -2, 987, + -1, 1871, + 148, 235, + 192, 235, + 376, 235, + -2, 530, + -1, 1948, + 149, 480, + 270, 480, + -2, 584, + -1, 1957, + 275, 1183, + 280, 1183, + -2, 492, + -1, 2405, + 237, 1742, + -2, 1736, + -1, 2406, + 237, 1738, -2, 1734, - -1, 2403, - 237, 1736, - -2, 1732, - -1, 2521, - 148, 233, - 192, 233, - 376, 233, - -2, 529, - -1, 2528, - 27, 254, - -2, 256, - -1, 3004, - 85, 160, - 95, 160, - -2, 1047, - -1, 3069, - 762, 772, - -2, 746, - -1, 3303, - 54, 1673, - -2, 1667, - -1, 3622, - 96, 1614, - -2, 1619, - -1, 4147, - 762, 772, - -2, 760, - -1, 4187, + -1, 2527, + 148, 235, + 192, 235, + 376, 235, + -2, 531, + -1, 2534, + 27, 256, + -2, 258, + -1, 3011, + 85, 162, + 95, 162, + -2, 1049, + -1, 3076, + 762, 774, + -2, 748, + -1, 3310, + 54, 1675, + -2, 1669, + -1, 3630, + 96, 1616, + -2, 1621, + -1, 4155, + 762, 774, + -2, 762, + -1, 4195, 15, 110, 16, 110, 164, 91, - -2, 881, - -1, 4244, + -2, 883, + -1, 4252, 164, 92, -2, 110, - -1, 4264, - 97, 704, - 103, 704, - 113, 704, - 194, 704, - 195, 704, - 196, 704, - 197, 704, - 198, 704, - 199, 704, - 200, 704, - 201, 704, - 202, 704, - 203, 704, - 204, 704, - 205, 704, - 206, 704, - 207, 704, - 208, 704, - 209, 704, - 210, 704, - 211, 704, - 212, 704, - 213, 704, - 214, 704, - 215, 704, - 216, 704, - 217, 704, - 218, 704, - 219, 704, - 220, 704, - 221, 704, - 222, 704, - 223, 704, - 224, 704, - 225, 704, - 226, 704, - 227, 704, - 228, 704, - 229, 704, - 230, 704, - 231, 704, - 232, 704, - 233, 704, - 234, 704, - 235, 704, - -2, 2137, - -1, 4337, + -1, 4272, + 97, 706, + 103, 706, + 113, 706, + 194, 706, + 195, 706, + 196, 706, + 197, 706, + 198, 706, + 199, 706, + 200, 706, + 201, 706, + 202, 706, + 203, 706, + 204, 706, + 205, 706, + 206, 706, + 207, 706, + 208, 706, + 209, 706, + 210, 706, + 211, 706, + 212, 706, + 213, 706, + 214, 706, + 215, 706, + 216, 706, + 217, 706, + 218, 706, + 219, 706, + 220, 706, + 221, 706, + 222, 706, + 223, 706, + 224, 706, + 225, 706, + 226, 706, + 227, 706, + 228, 706, + 229, 706, + 230, 706, + 231, 706, + 232, 706, + 233, 706, + 234, 706, + 235, 706, + -2, 2139, + -1, 4345, 162, 97, 164, 97, -2, 110, - -1, 4421, + -1, 4429, 164, 96, -2, 110, - -1, 4427, + -1, 4435, 15, 110, 16, 110, -2, 101, @@ -1795,1344 +1795,1297 @@ var yyExca = [...]int{ const yyPrivate = 57344 -const yyLast = 62444 +const yyLast = 63763 var yyAct = [...]int{ - 1005, 3786, 3787, 3785, 2196, 92, 4379, 1000, 4368, 992, - 4245, 4244, 4246, 4397, 953, 4129, 954, 812, 4385, 4384, - 4226, 3430, 4315, 4314, 2518, 4262, 4342, 2208, 3580, 1322, - 2075, 3735, 4179, 4386, 3444, 3355, 4391, 1871, 3362, 4108, - 4031, 3399, 90, 2431, 1320, 9, 2433, 2578, 3154, 3239, - 3428, 3370, 2588, 3408, 3413, 3410, 3409, 3723, 3407, 3412, - 3411, 3427, 958, 784, 3320, 1196, 3317, 46, 3828, 3316, - 3634, 3620, 2977, 3839, 3128, 3153, 129, 993, 2492, 2472, - 4106, 3656, 2489, 3304, 3314, 2964, 778, 2557, 779, 1928, - 3039, 1075, 3610, 92, 3110, 3451, 3066, 2949, 2562, 3040, - 2619, 3041, 2506, 1134, 1102, 171, 2989, 47, 2493, 2970, - 1072, 2494, 2922, 2388, 1075, 2451, 2938, 45, 2230, 2356, - 2192, 1109, 2948, 3101, 2142, 2355, 2597, 1952, 2481, 1144, - 157, 2564, 1172, 1970, 3032, 1081, 1154, 1860, 1159, 3006, - 781, 1840, 3645, 1101, 1007, 1808, 2496, 955, 1825, 3319, - 2460, 111, 1771, 1074, 2236, 1078, 1590, 112, 2167, 2156, - 107, 1515, 1498, 2070, 1959, 1141, 782, 1162, 1138, 1142, - 1165, 1160, 2553, 794, 1161, 1859, 1104, 2554, 789, 2473, - 1119, 3823, 1121, 2920, 1845, 1097, 1085, 1245, 1793, 3815, - 2244, 2231, 106, 2263, 1573, 1549, 1310, 1098, 2083, 14, - 1080, 135, 2133, 13, 12, 133, 1070, 114, 175, 134, - 1079, 3581, 140, 1944, 141, 1114, 1083, 89, 771, 1296, - 4242, 113, 1256, 1250, 1318, 1198, 99, 1594, 6, 4369, - 2590, 2591, 2592, 2590, 3724, 3396, 3057, 1599, 1215, 1216, - 1217, 1113, 1220, 1221, 1222, 1223, 714, 4163, 1226, 1227, - 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, - 1238, 1239, 1240, 1241, 1242, 1135, 136, 1089, 1201, 2634, - 3716, 774, 142, 4164, 3089, 3088, 1069, 1176, 4286, 2036, - 1827, 3118, 3119, 1244, 3790, 4158, 4159, 2428, 2429, 2149, - 3790, 1267, 2148, 2147, 3681, 2146, 772, 1087, 4, 1209, - 1090, 2145, 1128, 1129, 4, 2144, 2114, 1266, 1073, 2918, - 4137, 1071, 1175, 2687, 3054, 1823, 1151, 3300, 711, 3059, - 712, 2623, 3243, 756, 4318, 4416, 1830, 4313, 3418, 4359, - 1146, 1202, 1205, 1206, 1150, 750, 2966, 1828, 1149, 4373, - 1103, 136, 1148, 3584, 4290, 4288, 118, 119, 120, 1512, - 123, 3418, 1509, 1804, 2469, 1218, 1831, 199, 3583, 2468, - 706, 3079, 3082, 4109, 3415, 4372, 1006, 1829, 2883, 2622, - 4289, 4287, 769, 770, 2154, 3470, 4241, 4027, 4026, 1152, - 3789, 1200, 1063, 1064, 1065, 1066, 3789, 3729, 3416, 1077, - 3730, 91, 1199, 1082, 1057, 756, 101, 4159, 4328, 995, - 1058, 1009, 1010, 1011, 996, 4037, 4284, 997, 998, 136, - 999, 3416, 1068, 3747, 2980, 1500, 3736, 3422, 4223, 1116, - 1117, 2579, 2616, 4036, 1529, 3830, 1530, 1531, 1012, 1013, - 2201, 4272, 1127, 1131, 957, 1127, 1131, 957, 4267, 2621, - 3422, 3496, 2981, 2462, 750, 3352, 3353, 2513, 2514, 1528, - 1532, 4270, 2126, 2127, 1861, 4227, 1862, 1511, 2919, 3746, - 3015, 4277, 4278, 3014, 3351, 3117, 3016, 2691, 2512, 1516, - 3100, 3372, 3373, 2694, 101, 1274, 1286, 1061, 4271, 1315, - 1275, 750, 3060, 1060, 750, 91, 4130, 91, 1273, 745, - 1272, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, - 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, - 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, - 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, - 1053, 1054, 1055, 4231, 1516, 2573, 103, 730, 3853, 1287, - 1291, 1292, 1274, 2692, 3419, 91, 1280, 1275, 93, 3027, - 3448, 2079, 1249, 750, 1257, 1258, 2531, 2530, 3478, 2567, - 728, 3446, 750, 751, 1510, 2973, 2974, 3419, 101, 3175, - 101, 4344, 4345, 4346, 4347, 4348, 4349, 4350, 4351, 4352, - 4353, 4354, 4355, 2430, 3476, 3439, 1493, 1261, 1526, 2685, - 1499, 4319, 3371, 1314, 1260, 2125, 103, 1219, 3102, 1313, - 3452, 725, 764, 2129, 3374, 768, 762, 2026, 3067, 1775, - 740, 1262, 4320, 4079, 2958, 4080, 2959, 2598, 2944, 3286, - 2660, 2450, 2661, 2452, 2662, 735, 3703, 3287, 101, 1819, - 1289, 1290, 1307, 1492, 2452, 1312, 1295, 738, 1288, 2641, - 748, 1253, 3105, 3718, 3717, 1281, 2663, 3449, 749, 1293, - 2639, 1225, 2027, 1526, 2028, 1224, 1550, 2637, 3447, 1294, - 4011, 2688, 3714, 2689, 1155, 2601, 3440, 3441, 1156, 3794, - 2490, 1156, 751, 1194, 1193, 1192, 3631, 1120, 1191, 3467, - 1190, 1778, 1551, 1552, 1553, 1554, 1555, 1556, 1557, 1559, - 1558, 1560, 1561, 2638, 2080, 2642, 1189, 1188, 1187, 1182, - 1937, 1522, 1195, 3374, 1514, 4417, 2640, 3394, 715, 751, - 717, 731, 751, 753, 1139, 752, 721, 1139, 719, 723, - 732, 724, 1168, 718, 2566, 729, 1167, 4426, 720, 733, - 734, 737, 741, 742, 743, 739, 736, 2461, 727, 754, - 3055, 750, 1139, 1115, 1204, 1319, 1137, 1319, 1319, 3176, - 1167, 3242, 2071, 3623, 1203, 1857, 1248, 2648, 2644, 2646, - 2647, 2645, 2649, 2650, 2651, 2652, 1522, 3106, 2627, 2626, - 4302, 2067, 1501, 1212, 1130, 1124, 1122, 1130, 1124, 1122, - 3290, 751, 3091, 3077, 2943, 2459, 2476, 2458, 2457, 3713, - 751, 2453, 2068, 1265, 705, 4301, 4414, 1075, 1574, 1579, - 1580, 3061, 1583, 1585, 1586, 1587, 1588, 1589, 4282, 1592, - 1593, 1595, 1595, 101, 1595, 1595, 1600, 1600, 1600, 1603, - 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, - 1614, 1615, 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, - 1624, 1625, 1626, 1627, 1628, 1629, 1630, 1631, 1632, 1633, - 1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1642, 1643, - 1644, 1645, 1646, 1647, 1648, 1649, 1650, 1651, 1652, 1653, - 1654, 1655, 1656, 1657, 1658, 1659, 1660, 1661, 1662, 1663, - 1664, 1665, 1666, 1667, 1668, 1669, 1670, 1671, 1672, 1673, - 1674, 1675, 1676, 1677, 1678, 1679, 1680, 1681, 1682, 1683, - 1684, 1685, 1686, 1687, 1688, 1689, 1690, 1691, 1692, 1693, - 1694, 1695, 1696, 1697, 1698, 1699, 1700, 1701, 1702, 1703, - 1704, 1705, 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713, - 1714, 1715, 1716, 1717, 1718, 1719, 1720, 1721, 1722, 1723, - 1724, 1725, 1726, 1584, 2620, 1575, 4136, 1727, 1153, 1729, - 1730, 1731, 1732, 1733, 1308, 3058, 1827, 1567, 1568, 1569, - 1570, 1600, 1600, 1600, 1600, 1600, 1600, 1581, 1489, 751, - 1571, 1490, 1491, 3832, 3831, 4182, 1740, 1741, 1742, 1743, - 1744, 1745, 1746, 1747, 1748, 1749, 1750, 1751, 1752, 1753, - 1259, 3568, 4276, 2474, 2475, 2956, 3788, 3745, 3081, 3632, - 1858, 100, 3788, 1185, 1174, 4125, 1174, 1270, 1183, 1276, - 1277, 1278, 1279, 4229, 2038, 2037, 2039, 2040, 2041, 4142, - 1521, 1518, 1519, 1520, 1525, 1527, 1524, 1174, 1523, 3679, - 3680, 3682, 4401, 1316, 1317, 4274, 1564, 755, 1517, 1596, - 4275, 1597, 1598, 3420, 3421, 94, 3080, 1174, 1081, 1958, - 1564, 4228, 1508, 1271, 1601, 1602, 3424, 1768, 746, 1303, - 750, 1305, 3099, 1774, 4390, 3098, 3420, 3421, 1764, 2693, - 3670, 2570, 1075, 747, 1123, 1251, 1075, 1123, 3652, 3424, - 2692, 3251, 1075, 1284, 3011, 1521, 1518, 1519, 1520, 1525, - 1527, 1524, 2976, 1523, 2895, 100, 2204, 100, 1849, 2618, - 1302, 1304, 2056, 1517, 3109, 2476, 1728, 2923, 2925, 1264, - 1565, 1566, 2571, 132, 3358, 3250, 2971, 713, 1081, 1173, - 2569, 1173, 2272, 1765, 3468, 2519, 1564, 1167, 1170, 1171, - 1561, 1139, 3350, 3122, 1782, 1164, 1168, 1804, 1786, 2720, - 1532, 1211, 1173, 1297, 1074, 1544, 92, 2709, 1556, 1557, - 1559, 1558, 1560, 1561, 2572, 100, 1093, 1163, 4393, 2245, - 2084, 3270, 1173, 1822, 1311, 3359, 1186, 4150, 2568, 1531, - 1957, 1184, 2055, 1197, 4420, 1269, 2246, 3709, 1529, 1784, - 1530, 1531, 3644, 111, 3268, 1785, 126, 4422, 1081, 112, - 3361, 1931, 1532, 1765, 2463, 2138, 2064, 1766, 1734, 1735, - 1736, 1737, 1738, 1739, 1532, 1530, 1531, 1772, 46, 1863, - 3356, 1300, 4297, 3149, 1780, 1301, 4380, 1934, 1935, 1936, - 4257, 4408, 3029, 2720, 2237, 1306, 2729, 2237, 2954, 1532, - 3372, 3373, 1826, 2264, 2482, 2483, 3848, 3357, 2266, 114, - 4329, 3687, 2271, 2267, 3686, 2605, 2268, 2269, 2270, 1249, - 1243, 2265, 2273, 2274, 2275, 2276, 2277, 2278, 2279, 2280, - 2281, 3129, 1299, 3112, 1174, 127, 1950, 1967, 3111, 1966, - 1956, 4321, 1806, 3363, 2615, 2021, 4399, 2613, 1769, 4400, - 1783, 4398, 2228, 1251, 2011, 2012, 1185, 3112, 751, 1943, - 2017, 2018, 3111, 2924, 2077, 1071, 1183, 1174, 1781, 1073, - 1962, 1821, 1298, 1960, 1960, 1809, 1811, 1319, 2617, 2610, - 2003, 1283, 2474, 2475, 1252, 1247, 1972, 2243, 1973, 2085, - 1975, 1977, 1285, 1964, 1981, 1983, 1985, 1987, 1989, 2052, - 1268, 2053, 1854, 1855, 2054, 2060, 1961, 2058, 2059, 2057, - 2061, 2062, 2063, 1815, 2610, 3671, 1818, 4418, 101, 1923, - 1999, 3371, 2614, 2002, 1088, 2004, 3131, 1529, 1174, 1530, - 1531, 1804, 1529, 3374, 1530, 1531, 1816, 4193, 2170, 2242, - 1941, 1940, 1939, 3742, 1787, 3743, 1953, 4403, 4323, 1173, - 4117, 1210, 4019, 1532, 4018, 1207, 1804, 2612, 1532, 2046, - 4009, 2051, 2007, 2220, 2209, 2210, 2211, 2212, 2222, 2213, - 2214, 2215, 2227, 2223, 2216, 2217, 2224, 2225, 2226, 2218, - 2219, 2221, 1173, 1174, 3759, 3758, 4194, 1177, 1167, 1009, - 1010, 1011, 1179, 2072, 2073, 1246, 1180, 1178, 3694, 4118, - 3141, 3140, 3139, 3693, 2172, 3133, 3683, 3137, 1838, 3132, - 2044, 3130, 1529, 4419, 1530, 1531, 3135, 3397, 1181, 2173, - 1562, 1563, 2171, 1248, 1150, 3134, 3390, 1249, 1149, 1812, - 2045, 136, 1148, 198, 3037, 3036, 1814, 1813, 1532, 2160, - 2161, 2699, 2700, 1173, 3136, 3138, 2033, 3035, 1177, 1167, - 2576, 2090, 2047, 1179, 2031, 3360, 137, 1180, 1178, 1319, - 1319, 1550, 2086, 2087, 1554, 1555, 1556, 1557, 1559, 1558, - 1560, 1561, 180, 2030, 2112, 92, 2091, 198, 92, 1837, - 1819, 2043, 2029, 2098, 2099, 2100, 1262, 1551, 1552, 1553, - 1554, 1555, 1556, 1557, 1559, 1558, 1560, 1561, 1173, 2019, - 137, 2111, 2013, 2010, 1167, 1170, 1171, 2009, 1139, 4334, - 1804, 2008, 1164, 1168, 4332, 1804, 180, 2032, 3020, 1979, - 2134, 1779, 1529, 2134, 1530, 1531, 1100, 1099, 1100, 3298, - 1495, 4299, 177, 756, 1857, 178, 1529, 46, 1530, 1531, - 46, 2200, 2088, 2199, 2199, 2197, 2197, 1833, 1532, 2092, - 1804, 2094, 2095, 2096, 2097, 3676, 4138, 756, 2101, 1100, - 4357, 197, 1532, 2390, 3643, 3018, 1529, 756, 1530, 1531, - 2113, 1529, 2392, 1530, 1531, 4322, 177, 1760, 4145, 178, - 1550, 2725, 1758, 1546, 2586, 1547, 2585, 1756, 1004, 4144, - 1757, 1755, 1532, 1759, 2162, 2756, 1834, 1532, 1081, 2716, - 1548, 1562, 1563, 1545, 4121, 197, 1551, 1552, 1553, 1554, - 1555, 1556, 1557, 1559, 1558, 1560, 1561, 1550, 1764, 3121, - 2283, 1552, 1553, 1554, 1555, 1556, 1557, 1559, 1558, 1560, - 1561, 1248, 1551, 1552, 1553, 1554, 1555, 1556, 1557, 1559, - 1558, 1560, 1561, 1551, 1552, 1553, 1554, 1555, 1556, 1557, - 1559, 1558, 1560, 1561, 2766, 2584, 4120, 2583, 2175, 2724, - 2177, 2178, 2179, 2180, 2181, 2182, 2184, 2186, 2187, 2188, - 2189, 2190, 2191, 1765, 2137, 4119, 2232, 2137, 2135, 2136, - 2139, 2135, 2136, 2119, 2120, 2176, 1933, 4370, 181, 2169, - 4309, 1804, 1575, 4324, 4046, 117, 2582, 187, 2581, 4237, - 1804, 3485, 4045, 4235, 1804, 4003, 116, 2389, 115, 3364, - 2238, 4014, 2174, 3368, 4233, 1804, 1529, 3999, 1530, 1531, - 1529, 3367, 1530, 1531, 1529, 3998, 1530, 1531, 2402, 2401, - 108, 2307, 181, 1804, 2160, 2161, 2158, 2159, 1592, 2203, - 109, 187, 1532, 2400, 3847, 2299, 1532, 1766, 3845, 1529, - 1532, 1530, 1531, 1933, 1804, 3369, 1529, 3755, 1530, 1531, - 1529, 2157, 1530, 1531, 3365, 2247, 2248, 2249, 2250, 3366, - 1763, 1529, 1804, 1530, 1531, 1532, 1550, 2391, 4134, 2261, - 1762, 1804, 1532, 1528, 1804, 2282, 1532, 4092, 1804, 1529, - 1761, 1530, 1531, 3691, 2297, 3675, 4041, 1532, 2467, 2770, - 1803, 1804, 1551, 1552, 1553, 1554, 1555, 1556, 1557, 1559, - 1558, 1560, 1561, 2768, 3453, 1532, 2399, 1933, 4222, 2405, - 2406, 3450, 117, 1528, 1804, 2498, 3393, 172, 1529, 3392, - 1530, 1531, 3103, 116, 1529, 115, 1530, 1531, 3046, 111, - 1933, 4203, 4002, 110, 1529, 112, 1530, 1531, 3033, 2402, - 2487, 2941, 108, 1529, 1532, 1530, 1531, 1760, 110, 1754, - 1532, 111, 109, 2435, 2400, 110, 2528, 112, 1933, 4199, - 1532, 172, 1094, 2682, 2380, 2381, 2382, 2383, 2384, 1532, - 1095, 2447, 2168, 1550, 2674, 2708, 2673, 2500, 4090, 1804, - 3629, 2404, 2632, 1098, 2407, 2408, 2631, 2441, 1144, 2442, - 4099, 1804, 4087, 1804, 3727, 4135, 4069, 1804, 1804, 1551, - 1552, 1553, 1554, 1555, 1556, 1557, 1559, 1558, 1560, 1561, - 2471, 4022, 1804, 1804, 1099, 1100, 1144, 2455, 2423, 2939, - 2425, 1933, 4010, 2538, 2539, 2540, 2532, 1089, 2533, 2534, - 2535, 2536, 2537, 2523, 2522, 1529, 2541, 1530, 1531, 2436, - 2504, 2448, 2543, 3609, 1804, 2545, 2546, 2547, 2548, 1529, - 4006, 1530, 1531, 1529, 2115, 1530, 1531, 2081, 2454, 3602, - 1804, 1532, 2599, 3599, 1804, 3727, 1804, 2464, 2526, 110, - 2559, 1933, 3725, 2610, 1804, 1532, 3597, 1804, 3068, 1532, - 3560, 1804, 2477, 2042, 2565, 3650, 1804, 2850, 1804, 3383, - 3382, 2485, 3380, 3381, 2510, 1128, 1129, 2509, 2034, 2508, - 1529, 2525, 1530, 1531, 2524, 2024, 1529, 2020, 1530, 1531, - 3378, 3379, 2978, 2596, 3558, 1804, 1529, 2575, 1530, 1531, - 1529, 2016, 1530, 1531, 3378, 3377, 1532, 2986, 1804, 2692, - 3090, 116, 1532, 1529, 1804, 1530, 1531, 1529, 3007, 1530, - 1531, 1176, 1532, 3007, 2604, 2015, 1532, 2607, 2014, 2608, - 1835, 1960, 2560, 2556, 2549, 2551, 2552, 2574, 1309, 1532, - 1927, 3071, 3051, 1532, 3064, 3065, 2624, 2527, 173, 1528, - 2718, 1529, 3710, 1530, 1531, 185, 1175, 3038, 2202, 1804, - 2717, 2603, 2560, 2606, 2602, 1933, 1932, 2985, 2628, 2986, - 2625, 2978, 2629, 2630, 1927, 1926, 2611, 1532, 3554, 1804, - 1869, 1868, 3315, 4177, 3345, 1528, 3008, 3551, 1804, 4149, - 1933, 3008, 173, 3643, 2692, 2697, 3010, 193, 4113, 185, - 2986, 2692, 3588, 3647, 1075, 1075, 1075, 2636, 1529, 3380, - 1530, 1531, 3273, 1529, 2635, 1530, 1531, 1529, 2511, 1530, - 1531, 2850, 3549, 1804, 1585, 2753, 1585, 2752, 2986, 2610, - 2593, 3547, 1804, 2480, 1532, 1529, 2466, 1530, 1531, 1532, - 2610, 193, 2712, 1532, 1529, 1820, 1530, 1531, 3643, 3665, - 174, 179, 176, 182, 183, 184, 186, 188, 189, 190, - 191, 1532, 3545, 1804, 2426, 1076, 192, 194, 195, 196, - 1532, 3646, 2666, 2202, 2402, 2401, 3543, 1804, 2140, 1529, - 2124, 1530, 1531, 2066, 3541, 1804, 1856, 1836, 1529, 2715, - 1530, 1531, 3539, 1804, 174, 179, 176, 182, 183, 184, - 186, 188, 189, 190, 191, 1532, 1529, 1158, 1530, 1531, - 192, 194, 195, 196, 1532, 3695, 103, 1157, 101, 1529, - 4280, 1530, 1531, 3445, 3537, 1804, 4205, 2684, 3400, 3535, - 1804, 4033, 1532, 1529, 1995, 1530, 1531, 3533, 1804, 4000, - 3860, 1529, 2690, 1530, 1531, 1532, 3531, 1804, 101, 1529, - 130, 1530, 1531, 2705, 3604, 2707, 3708, 2698, 3705, 1532, - 3689, 3501, 3500, 1929, 2710, 2558, 2711, 1532, 3529, 1804, - 2704, 3402, 3696, 3697, 3698, 1532, 3043, 2701, 2702, 2703, - 2706, 1529, 3398, 1530, 1531, 2169, 1529, 1251, 1530, 1531, - 2713, 1996, 1997, 1998, 1529, 3042, 1530, 1531, 3527, 1804, - 3296, 3072, 2555, 1529, 2550, 1530, 1531, 1532, 3525, 1804, - 2544, 1529, 1532, 1530, 1531, 2542, 2049, 1955, 2676, 2677, - 1532, 1951, 1925, 2679, 128, 1529, 4034, 1530, 1531, 1532, - 2728, 2573, 2680, 3657, 3658, 3523, 1804, 1532, 2439, 3521, - 1804, 2894, 4365, 3507, 1804, 1529, 2117, 1530, 1531, 3043, - 4363, 1532, 3483, 1804, 3151, 1529, 4316, 1530, 1531, 4157, - 4074, 3660, 3628, 3627, 3626, 1529, 710, 1530, 1531, 3315, - 3291, 1532, 2667, 2926, 3337, 2882, 2735, 2915, 1804, 3338, - 3663, 1532, 2929, 3335, 3662, 2199, 3334, 2197, 3336, 2764, - 3333, 1532, 1529, 2750, 1530, 1531, 1529, 3699, 1530, 1531, - 1529, 4153, 1530, 1531, 1991, 3339, 1075, 2995, 2996, 1529, - 4035, 1530, 1531, 2118, 2913, 1804, 2470, 1832, 1532, 1091, - 4307, 2927, 1532, 2888, 1804, 2445, 1532, 2865, 1804, 3651, - 2983, 2984, 3305, 3307, 1529, 1532, 1530, 1531, 3814, 2498, - 3813, 3308, 1075, 3003, 3278, 773, 3277, 4116, 2857, 1804, - 3700, 3701, 3702, 3636, 3838, 2848, 1804, 1992, 1993, 1994, - 1532, 3635, 3840, 3600, 2930, 3639, 2932, 2846, 1804, 3302, - 1092, 1529, 1081, 1530, 1531, 2982, 2833, 1804, 2168, 2065, - 1529, 1081, 1530, 1531, 1529, 1059, 1530, 1531, 3376, 3025, - 4339, 2963, 46, 3812, 3047, 2659, 2658, 1532, 2657, 2245, - 2656, 3000, 2655, 2654, 3002, 1529, 1532, 1530, 1531, 1214, - 1532, 2947, 1529, 1772, 1530, 1531, 2246, 3001, 1108, 2917, - 1529, 2653, 1530, 1531, 1529, 2972, 1530, 1531, 2165, 2163, - 2164, 1532, 1107, 1529, 1213, 1530, 1531, 3461, 1532, 3042, - 2946, 2942, 3115, 4305, 2945, 1494, 1532, 2937, 2831, 1804, - 1532, 1826, 3076, 3028, 3030, 2961, 1765, 3031, 3078, 1532, - 137, 108, 2975, 3641, 2829, 1804, 110, 3021, 3005, 2827, - 1804, 109, 3045, 2825, 1804, 4395, 108, 3048, 3049, 2960, - 2823, 1804, 110, 2482, 2483, 3009, 109, 3295, 2670, 3012, - 115, 4240, 4029, 3087, 2821, 1804, 3375, 3019, 2999, 2425, - 2465, 2565, 3022, 1145, 4341, 1529, 4340, 1530, 1531, 2819, - 1804, 1538, 1539, 1540, 1541, 1542, 1543, 1537, 1534, 3034, - 3611, 1529, 2696, 1530, 1531, 2123, 1529, 2122, 1530, 1531, - 1529, 1532, 1530, 1531, 4098, 3044, 3566, 1529, 4097, 1530, - 1531, 2817, 1804, 4077, 117, 3562, 3052, 1532, 3846, 3844, - 3498, 1529, 1532, 1530, 1531, 116, 1532, 115, 2815, 1804, - 3843, 3825, 3084, 1532, 1943, 110, 1529, 3276, 1530, 1531, - 2813, 1804, 116, 3073, 3074, 3275, 3706, 1532, 3125, 3126, - 3640, 3638, 3403, 2811, 1804, 2594, 117, 2809, 1804, 1938, - 1106, 3083, 1532, 1529, 3824, 1530, 1531, 116, 1529, 115, - 1530, 1531, 1529, 3621, 1530, 1531, 2978, 1529, 3798, 1530, - 1531, 117, 2807, 1804, 3085, 1529, 2941, 1530, 1531, 1532, - 4366, 3104, 116, 3179, 1532, 4367, 4366, 1529, 1532, 1530, - 1531, 3107, 3142, 1532, 2754, 4367, 2437, 3123, 1850, 1842, - 1529, 1532, 1530, 1531, 1529, 4122, 1530, 1531, 2805, 1804, - 121, 122, 3674, 1532, 1550, 5, 3160, 3161, 3162, 3163, - 3164, 3165, 3166, 3167, 3168, 3169, 1532, 1, 3, 1529, - 1532, 1530, 1531, 2803, 1804, 105, 3177, 2801, 1804, 3143, - 1551, 1552, 1553, 1554, 1555, 1556, 1557, 1559, 1558, 1560, - 1561, 4186, 1067, 3127, 1497, 1532, 8, 1496, 2799, 1804, - 3678, 3144, 2794, 1804, 4269, 1529, 726, 1530, 1531, 2790, - 1804, 2427, 1770, 2788, 1804, 4317, 3124, 4265, 4266, 2781, - 1804, 2035, 2025, 3737, 3237, 2354, 4030, 3826, 3827, 3181, - 1529, 1532, 1530, 1531, 1529, 3113, 1530, 1531, 3114, 3829, - 3406, 2600, 3704, 2389, 2563, 2389, 1166, 162, 2520, 2521, - 1805, 1807, 4217, 3145, 125, 1529, 1532, 1530, 1531, 1529, - 1532, 1530, 1531, 1132, 124, 3063, 1529, 1169, 1530, 1531, - 1529, 1282, 1530, 1531, 3244, 2595, 1529, 3246, 1530, 1531, - 3255, 1532, 2498, 3728, 3026, 1532, 2779, 1804, 2529, 1875, - 1873, 1874, 1532, 1872, 1877, 3497, 1532, 3170, 1876, 3489, - 4181, 3469, 1532, 2755, 3567, 2128, 763, 4310, 2998, 757, - 3217, 200, 1864, 2391, 1843, 2391, 1893, 2121, 1208, 716, - 3384, 2633, 3322, 722, 92, 1582, 2116, 2498, 2498, 2498, - 2498, 2498, 3227, 3228, 3229, 3230, 3231, 3274, 3013, 1126, - 3245, 1118, 3247, 1529, 2500, 1530, 1531, 2498, 1096, 2438, - 2498, 3280, 1529, 3254, 1530, 1531, 1529, 2931, 1530, 1531, - 3282, 3255, 1125, 4007, 3487, 3323, 1081, 3633, 3301, 1532, - 3303, 2965, 3306, 2228, 3266, 3299, 4115, 3837, 1532, 4338, - 4204, 2077, 1532, 3023, 1839, 3219, 1078, 3221, 3344, 2500, - 2500, 2500, 2500, 2500, 3279, 3327, 3267, 3269, 3271, 3587, - 3272, 3281, 3289, 3232, 3233, 3234, 3235, 2727, 2235, 2500, - 3423, 1572, 2500, 3292, 3293, 3294, 788, 3309, 3310, 2497, - 3431, 1529, 959, 1530, 1531, 3346, 1824, 3793, 3347, 2155, - 786, 1080, 785, 783, 3436, 3328, 3435, 3432, 3331, 3329, - 3330, 1079, 3332, 2933, 3340, 111, 2911, 1532, 3388, 3389, - 2979, 112, 1536, 3348, 2910, 1535, 994, 2921, 3326, 1851, - 2990, 3312, 2906, 2988, 2987, 2668, 3354, 2505, 3318, 3659, - 3655, 2905, 4261, 3318, 2499, 1880, 2495, 2940, 945, 3385, - 944, 3387, 3386, 795, 2220, 2209, 2210, 2211, 2212, 2222, - 2213, 2214, 2215, 2227, 2223, 2216, 2217, 2224, 2225, 2226, - 2218, 2219, 2221, 1529, 787, 1530, 1531, 777, 3404, 2565, - 3425, 1529, 1008, 1530, 1531, 943, 942, 3433, 3434, 1529, - 3442, 1530, 1531, 2904, 2955, 1817, 4306, 2903, 1529, 1532, - 1530, 1531, 3297, 2957, 3024, 2902, 3285, 1532, 1513, 3457, - 3454, 1789, 3456, 2901, 1792, 1532, 2446, 1810, 2892, 3466, - 3464, 4140, 2695, 3495, 1532, 3405, 1788, 4147, 3414, 3471, - 3472, 3474, 3473, 3722, 3395, 3475, 3069, 3477, 2587, 3479, - 1894, 3490, 3491, 3492, 3493, 3494, 74, 50, 4107, 4178, - 1529, 937, 1530, 1531, 1529, 934, 1530, 1531, 3795, 1585, - 3796, 3797, 1529, 1585, 1530, 1531, 3240, 3241, 4160, 4161, - 1529, 933, 1530, 1531, 4162, 1529, 1532, 1530, 1531, 3612, - 1532, 3614, 2292, 1507, 1504, 3053, 2130, 104, 1532, 40, - 39, 38, 37, 36, 3622, 30, 1532, 29, 3582, 3465, - 28, 1532, 27, 26, 2891, 3586, 1907, 1910, 1911, 1912, - 1913, 1914, 1915, 33, 1916, 1917, 1919, 1920, 1918, 1921, - 1922, 1895, 1896, 1897, 1898, 1878, 1879, 1908, 23, 1881, - 25, 1882, 1883, 1884, 1885, 1886, 1887, 1888, 1889, 1890, - 24, 22, 1891, 1899, 1900, 1901, 1902, 4377, 1903, 1904, - 1905, 1906, 4378, 4407, 1892, 4243, 2498, 4183, 3321, 3417, - 2890, 1529, 3619, 1530, 1531, 2889, 4312, 4394, 131, 3672, - 3617, 4343, 3613, 4304, 3615, 2991, 2994, 2995, 2996, 2992, - 4303, 2993, 2997, 3436, 4254, 3435, 3432, 1532, 4383, 4249, - 3673, 60, 2886, 57, 55, 3630, 139, 3637, 2881, 3589, - 138, 3591, 3592, 3593, 2874, 58, 56, 54, 53, 1254, - 3654, 3642, 51, 3426, 102, 3459, 3460, 1529, 2500, 1530, - 1531, 35, 1529, 3661, 1530, 1531, 2873, 34, 3664, 3668, - 3669, 2872, 21, 20, 3667, 19, 2240, 3666, 18, 17, - 16, 2241, 15, 1532, 3684, 3685, 2871, 11, 1532, 1529, - 10, 1530, 1531, 2870, 43, 1529, 42, 1530, 1531, 2869, - 41, 1529, 32, 1530, 1531, 31, 44, 3690, 7, 3692, - 2, 3056, 2589, 0, 2868, 1532, 0, 0, 2867, 2303, - 0, 1532, 0, 1529, 2866, 1530, 1531, 1532, 1529, 2860, - 1530, 1531, 3715, 2859, 0, 0, 3719, 3720, 3721, 0, - 0, 0, 0, 1529, 0, 1530, 1531, 0, 0, 1532, - 1529, 0, 1530, 1531, 1532, 0, 1529, 0, 1530, 1531, - 2858, 0, 0, 0, 1766, 3732, 3733, 2855, 0, 1532, - 3734, 1529, 0, 1530, 1531, 1529, 1532, 1530, 1531, 2854, - 0, 1529, 1532, 1530, 1531, 2853, 1529, 0, 1530, 1531, - 1529, 0, 1530, 1531, 2851, 0, 0, 1532, 2844, 2386, - 0, 1532, 3749, 0, 0, 0, 0, 1532, 0, 0, - 0, 1909, 1532, 0, 0, 2841, 1532, 1529, 0, 1530, - 1531, 0, 0, 2839, 1529, 0, 1530, 1531, 3760, 2417, - 0, 2837, 0, 0, 0, 2796, 1529, 0, 1530, 1531, - 0, 0, 1529, 1532, 1530, 1531, 1805, 2424, 2776, 0, - 1532, 1529, 2775, 1530, 1531, 1529, 2771, 1530, 1531, 0, - 0, 3811, 1532, 0, 3818, 0, 3820, 3801, 1532, 3802, - 3803, 3804, 1529, 0, 1530, 1531, 0, 1532, 0, 0, - 1529, 1532, 1530, 1531, 0, 0, 0, 2449, 1529, 3754, - 1530, 1531, 1529, 3791, 1530, 1531, 0, 3322, 1532, 0, - 92, 0, 3322, 0, 0, 1529, 1532, 1530, 1531, 1529, - 3821, 1530, 1531, 1529, 1532, 1530, 1531, 2769, 1532, 0, - 3862, 0, 2761, 2199, 0, 2197, 1794, 0, 0, 0, - 0, 1532, 0, 0, 0, 1532, 2732, 0, 0, 1532, - 1802, 3822, 1081, 1795, 3852, 3854, 0, 0, 0, 0, - 0, 0, 0, 2726, 3842, 0, 3841, 0, 0, 0, - 3849, 3851, 46, 2721, 0, 4013, 0, 0, 2443, 2444, - 1801, 1799, 1800, 1796, 1529, 1797, 1530, 1531, 0, 1529, - 0, 1530, 1531, 3711, 3712, 0, 0, 0, 3866, 3863, - 3864, 0, 0, 1529, 0, 1530, 1531, 0, 1798, 0, - 1532, 0, 0, 0, 3782, 1532, 0, 0, 0, 4005, - 1529, 2577, 1530, 1531, 0, 0, 0, 4004, 4020, 1532, - 1529, 0, 1530, 1531, 0, 1794, 0, 4024, 4025, 0, - 0, 4032, 4015, 4016, 4017, 0, 1532, 4071, 4072, 1802, - 0, 3318, 1795, 0, 0, 4075, 1532, 0, 2199, 0, - 2197, 3856, 0, 0, 3819, 2991, 2994, 2995, 2996, 2992, - 0, 2993, 2997, 0, 0, 3657, 3658, 1790, 1791, 1801, - 1799, 1800, 1796, 0, 1797, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4078, 0, 1798, 0, 4081, - 0, 0, 0, 4123, 3322, 0, 0, 0, 0, 0, - 0, 3858, 0, 0, 0, 0, 0, 0, 1603, 1604, + 1005, 3794, 3795, 3793, 1000, 92, 4387, 992, 2199, 4376, + 4253, 4252, 4392, 4254, 953, 4405, 4137, 954, 812, 4393, + 3438, 4322, 4234, 2524, 4323, 4350, 4270, 3588, 4187, 1323, + 2211, 2078, 3743, 4394, 3452, 3363, 4399, 1874, 3370, 4116, + 1321, 3407, 3731, 2434, 4039, 90, 2584, 9, 3416, 3246, + 2436, 2594, 3378, 3421, 3418, 3417, 3415, 3420, 3419, 3324, + 3435, 3436, 1197, 784, 3328, 3325, 3642, 3628, 3847, 3135, + 3160, 129, 3836, 2476, 958, 993, 2495, 3664, 3322, 46, + 2498, 3311, 2970, 778, 3618, 2563, 2983, 779, 3046, 3459, + 3117, 1075, 3073, 92, 2955, 2568, 1135, 3047, 2625, 3048, + 171, 4114, 2512, 1102, 2996, 2499, 1072, 47, 2976, 2455, + 2944, 2391, 2500, 1110, 1075, 2928, 2954, 2359, 2195, 1173, + 2233, 2145, 3108, 1973, 2603, 45, 1955, 157, 2485, 1145, + 2570, 3039, 1155, 1863, 2358, 3013, 1841, 1931, 1081, 1160, + 781, 1101, 3653, 1809, 1007, 1826, 955, 3161, 2464, 3327, + 111, 1591, 2239, 112, 1772, 107, 2170, 2502, 2159, 1516, + 1499, 2073, 1962, 1142, 1166, 1074, 782, 1078, 1139, 1143, + 2559, 1163, 794, 1161, 1162, 789, 2560, 1847, 1862, 1085, + 1097, 1120, 3831, 1246, 2926, 1122, 106, 1794, 1104, 2247, + 2266, 1574, 3823, 1550, 1098, 1311, 2086, 2136, 14, 13, + 1080, 2477, 114, 3589, 12, 140, 135, 1070, 133, 175, + 134, 1947, 141, 1115, 1083, 1257, 113, 771, 1079, 1297, + 1251, 1595, 1199, 89, 1319, 1087, 4, 4250, 6, 4377, + 3732, 3404, 4, 1114, 2596, 1216, 1217, 1218, 1245, 1221, + 1222, 1223, 1224, 1600, 3064, 1227, 1228, 1229, 1230, 1231, + 1232, 1233, 1234, 1235, 1236, 1237, 1238, 1239, 1240, 1241, + 1242, 1243, 1089, 1202, 1177, 99, 1136, 136, 714, 2640, + 142, 3724, 4171, 2234, 118, 119, 120, 1069, 123, 2596, + 2597, 2598, 3096, 3095, 2039, 199, 1210, 4294, 706, 3689, + 1828, 3125, 3126, 4166, 1090, 772, 4167, 1268, 4172, 1129, + 769, 770, 2152, 756, 2151, 1824, 1071, 2431, 2432, 2150, + 1063, 1064, 1065, 1066, 1073, 2149, 1176, 1077, 3798, 4145, + 3066, 1082, 3426, 2148, 2147, 1130, 2117, 3426, 1267, 3798, + 711, 1147, 712, 3061, 2924, 1203, 1206, 1207, 1152, 1151, + 3423, 1150, 136, 1149, 3307, 2629, 2693, 1117, 1118, 756, + 2972, 1057, 4326, 774, 1831, 1006, 995, 1058, 1009, 1010, + 1011, 996, 750, 3086, 997, 998, 3250, 999, 1128, 1132, + 957, 4381, 101, 4424, 4298, 4321, 4296, 1219, 1829, 1103, + 4367, 1805, 3424, 3592, 1832, 1012, 1013, 3424, 3591, 1128, + 1132, 957, 2473, 2628, 2472, 3089, 1513, 4380, 750, 1510, + 4297, 1530, 4295, 1531, 1532, 4167, 1153, 4117, 1830, 2889, + 136, 3430, 4235, 1068, 3797, 2157, 3430, 750, 3478, 4249, + 4035, 4034, 1201, 3737, 1200, 3797, 3738, 1533, 4336, 4045, + 4292, 3755, 1501, 2700, 3744, 4231, 2585, 2622, 750, 4044, + 2204, 4275, 3504, 745, 3838, 2466, 2925, 1529, 1014, 1015, + 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, + 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, + 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, + 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, + 4239, 730, 2579, 2627, 3754, 91, 2518, 91, 93, 91, + 3360, 3361, 91, 2698, 1512, 3022, 3359, 3124, 3021, 750, + 2697, 3023, 2519, 2520, 728, 3107, 2573, 2129, 2130, 1864, + 2987, 1865, 1275, 1287, 1061, 1060, 4138, 1276, 1316, 1275, + 1292, 1293, 1517, 2082, 1276, 1274, 3034, 1273, 3427, 1551, + 750, 1517, 3447, 3427, 1288, 1281, 103, 3182, 2988, 3456, + 103, 2537, 2536, 3861, 2480, 725, 3486, 4280, 3484, 3454, + 2979, 2980, 3475, 1494, 740, 1552, 1553, 1554, 1555, 1556, + 1557, 1558, 1560, 1559, 1561, 1562, 2691, 4278, 101, 735, + 101, 2128, 101, 764, 1220, 101, 2132, 4285, 4286, 3074, + 751, 738, 768, 2964, 748, 2965, 3109, 3380, 3381, 762, + 3460, 1776, 749, 2433, 4279, 2029, 4087, 1500, 4088, 2604, + 3293, 1511, 2950, 1121, 1820, 2456, 3711, 1308, 3294, 4327, + 1290, 1291, 1493, 3448, 3449, 1313, 751, 4352, 4353, 4354, + 4355, 4356, 4357, 4358, 4359, 4360, 4361, 4362, 4363, 1294, + 4328, 1296, 1315, 1289, 1282, 751, 3457, 1254, 1314, 1295, + 2030, 1527, 2031, 2666, 2275, 2667, 3455, 2668, 2647, 3112, + 1527, 4019, 715, 2645, 717, 731, 751, 753, 1779, 752, + 721, 3639, 719, 723, 732, 724, 2083, 718, 3067, 729, + 3726, 2572, 720, 733, 734, 737, 741, 742, 743, 739, + 736, 3725, 727, 754, 2694, 2454, 2695, 2654, 2650, 2652, + 2653, 2651, 2655, 2656, 2657, 2658, 2644, 2669, 2456, 1226, + 1131, 1125, 1123, 1225, 2648, 2607, 2643, 1156, 3379, 2646, + 3802, 1157, 2496, 1157, 1195, 1194, 1193, 3183, 1192, 1191, + 3382, 1131, 1125, 1123, 1190, 1189, 1188, 751, 1183, 1940, + 1196, 3382, 1140, 4425, 1140, 1320, 1138, 1320, 1320, 1169, + 1205, 1860, 3402, 1140, 1168, 1116, 1168, 3113, 4434, 3062, + 1204, 2478, 2479, 2465, 1523, 2267, 2074, 1515, 751, 2633, + 2269, 2632, 2070, 1523, 2274, 2270, 750, 1502, 2271, 2272, + 2273, 1213, 3631, 2268, 2276, 2277, 2278, 2279, 2280, 2281, + 2282, 2283, 2284, 3297, 3098, 3249, 2949, 1075, 1575, 1580, + 1581, 2463, 1584, 1586, 1587, 1588, 1589, 1590, 101, 1593, + 1594, 1596, 1596, 2462, 1596, 1596, 1601, 1601, 1601, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, - 1615, 1616, 1617, 1618, 1619, 1620, 1621, 1623, 1624, 1625, - 1626, 1627, 1628, 1629, 1630, 1631, 1632, 1633, 1634, 1635, - 1636, 1637, 1638, 1639, 1640, 1641, 1642, 1643, 1644, 1645, - 1646, 1647, 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, - 1656, 1657, 1658, 1659, 1660, 1661, 1662, 1663, 1664, 1665, - 1666, 1667, 1668, 1669, 1670, 1671, 1672, 1673, 1674, 1675, - 1676, 1677, 1678, 1679, 1680, 1681, 1682, 1683, 1684, 1685, - 1686, 1687, 1688, 1689, 1690, 1691, 1692, 1693, 1694, 1695, - 1696, 1697, 1698, 1699, 1700, 1702, 1703, 1704, 1705, 1706, - 1707, 1708, 1709, 1710, 1711, 1712, 1713, 1714, 1715, 1716, - 1717, 1723, 1724, 1725, 1726, 1740, 1741, 1742, 1743, 1744, - 1745, 1746, 1747, 1748, 1749, 1750, 1751, 1752, 1753, 4126, - 4076, 4095, 4127, 4124, 4105, 4104, 0, 0, 4101, 0, - 4103, 0, 4141, 3321, 0, 0, 0, 4111, 3321, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 92, 0, 0, 0, 2714, 0, 0, 0, 2719, 4008, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2722, 4143, 2723, 0, 0, 0, 0, 0, 2731, - 4131, 0, 1081, 2733, 2734, 4148, 0, 0, 0, 0, - 4146, 4012, 2740, 2741, 2742, 2743, 2744, 2745, 2746, 2747, - 2748, 2749, 46, 2751, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 92, 0, 0, 2757, 2758, 2759, 2760, - 0, 2762, 2763, 4185, 2765, 4184, 0, 4166, 2767, 0, - 4167, 4201, 2772, 2773, 0, 2774, 0, 0, 2777, 2778, - 2780, 2782, 2783, 2784, 2785, 2786, 2787, 2789, 2791, 2792, - 2793, 2795, 4192, 2797, 2798, 2800, 2802, 2804, 2806, 2808, - 2810, 2812, 2814, 2816, 2818, 2820, 2822, 2824, 2826, 2828, - 2830, 2832, 2834, 2835, 2836, 46, 2838, 4230, 2840, 4206, - 2842, 2843, 4191, 2845, 2847, 2849, 4176, 0, 92, 2852, - 4216, 4128, 4195, 2856, 4032, 4219, 4215, 2861, 2862, 2863, - 2864, 4209, 4214, 4211, 4210, 1766, 4208, 4213, 4212, 0, - 2875, 2876, 2877, 2878, 2879, 2880, 0, 4238, 2884, 2885, - 3321, 0, 0, 0, 4256, 2887, 0, 4255, 0, 0, - 2893, 0, 0, 0, 0, 2896, 2897, 2898, 2899, 2900, - 4268, 4296, 4230, 4273, 4260, 92, 2907, 2908, 4285, 2909, - 46, 0, 2912, 2914, 2449, 4298, 2916, 4283, 0, 0, - 0, 4155, 0, 0, 0, 0, 2928, 4197, 0, 4165, - 3318, 0, 4295, 0, 0, 4202, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4300, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2962, 0, - 92, 4311, 0, 0, 0, 0, 0, 46, 0, 0, - 0, 4337, 2077, 4326, 0, 4327, 0, 4361, 0, 4330, - 2199, 0, 2197, 0, 0, 4336, 0, 0, 0, 0, - 0, 4133, 4356, 1766, 0, 4358, 4360, 4362, 92, 4364, - 4381, 0, 0, 0, 4230, 0, 0, 0, 4298, 0, - 4371, 0, 0, 0, 3436, 0, 3435, 3432, 0, 0, - 4392, 4382, 46, 0, 4151, 0, 0, 0, 0, 0, - 0, 0, 4291, 0, 0, 0, 0, 4396, 4139, 4404, - 0, 4402, 0, 0, 92, 4409, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4412, 0, 0, 0, - 46, 0, 0, 0, 0, 0, 0, 0, 4415, 92, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4421, 4425, 92, 92, 2199, 0, 2197, 4429, 92, 4428, - 4430, 4072, 4298, 4424, 4427, 0, 0, 0, 4298, 0, - 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, - 0, 0, 0, 0, 4196, 0, 0, 198, 0, 0, + 1615, 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 1624, + 1625, 1626, 1627, 1628, 1629, 1630, 1631, 1632, 1633, 1634, + 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1642, 1643, 1644, + 1645, 1646, 1647, 1648, 1649, 1650, 1651, 1652, 1653, 1654, + 1655, 1656, 1657, 1658, 1659, 1660, 1661, 1662, 1663, 1664, + 1665, 1666, 1667, 1668, 1669, 1670, 1671, 1672, 1673, 1674, + 1675, 1676, 1677, 1678, 1679, 1680, 1681, 1682, 1683, 1684, + 1685, 1686, 1687, 1688, 1689, 1690, 1691, 1692, 1693, 1694, + 1695, 1696, 1697, 1698, 1699, 1700, 1701, 1702, 1703, 1704, + 1705, 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713, 1714, + 1715, 1716, 1717, 1718, 1719, 1720, 1721, 1722, 1723, 1724, + 1725, 1726, 1727, 1585, 1576, 1260, 1828, 1728, 1490, 1730, + 1731, 1732, 1733, 1734, 1309, 4144, 3065, 1568, 1569, 1570, + 1571, 1601, 1601, 1601, 1601, 1601, 1601, 1582, 3576, 1572, + 4237, 1491, 1492, 4190, 2962, 1154, 1741, 1742, 1743, 1744, + 1745, 1746, 1747, 1748, 1749, 1750, 1751, 1752, 1753, 1754, + 3036, 755, 3840, 3839, 3640, 94, 1861, 3068, 2626, 1252, + 3088, 750, 1175, 4409, 751, 3722, 1186, 3476, 4236, 1184, + 1124, 1175, 746, 1271, 4150, 1277, 1278, 1279, 1280, 2041, + 2040, 2042, 2043, 2044, 3687, 3688, 3690, 747, 2576, 2699, + 3796, 1124, 3753, 1597, 1212, 1598, 1599, 3428, 3429, 1317, + 1318, 3796, 3428, 3429, 2461, 2698, 2480, 1565, 3087, 1961, + 3432, 1081, 1565, 3084, 2457, 3432, 2071, 1769, 3116, 1266, + 1602, 1603, 705, 1775, 4310, 2929, 2931, 1272, 1175, 2577, + 4398, 1250, 1075, 1258, 1259, 4309, 1075, 2575, 4422, 4290, + 1765, 4133, 1075, 1522, 1519, 1520, 1521, 1526, 1528, 1525, + 3258, 1524, 1522, 1519, 1520, 1521, 1526, 1528, 1525, 1509, + 1524, 1518, 1285, 1566, 1567, 100, 1262, 100, 2058, 100, + 1518, 2578, 100, 1261, 3678, 2624, 3106, 1174, 4284, 3105, + 3660, 1081, 3018, 2982, 2901, 2574, 1174, 2207, 1851, 1729, + 1263, 1766, 3721, 1265, 1175, 3257, 2977, 713, 132, 2525, + 1565, 1562, 3358, 2248, 3129, 1805, 1783, 92, 1533, 2715, + 1787, 1298, 91, 48, 49, 93, 1074, 1175, 1823, 3277, + 2249, 4282, 1252, 2726, 1545, 2059, 4283, 2087, 3275, 1187, + 1960, 98, 1185, 1250, 1244, 52, 81, 82, 1785, 79, + 83, 1786, 111, 1174, 1530, 112, 1531, 1532, 1532, 1531, + 1532, 80, 1081, 4430, 1934, 1093, 1304, 3366, 1306, 1270, + 1312, 1766, 4401, 103, 1735, 1736, 1737, 1738, 1739, 1740, + 1533, 1533, 1781, 1533, 4428, 1937, 1938, 1939, 1773, 4158, + 1198, 46, 1816, 67, 3717, 1819, 4265, 2175, 3119, 751, + 4305, 2726, 1827, 3118, 114, 101, 4421, 1303, 1305, 1248, + 3652, 3119, 2176, 1563, 1564, 2174, 3118, 4407, 3367, 1174, + 4408, 2930, 4406, 2478, 2479, 1168, 1171, 1172, 2467, 1140, + 1953, 126, 2141, 1165, 1169, 2055, 1807, 2056, 4342, 1805, + 2057, 2067, 1174, 3369, 1211, 1249, 1866, 1770, 1208, 1767, + 2024, 1784, 2014, 2015, 2762, 88, 3156, 1946, 2020, 2021, + 1071, 1963, 1963, 3364, 4388, 2080, 2240, 4416, 1810, 1822, + 1965, 2246, 1788, 1812, 2006, 1073, 4337, 1975, 1320, 1976, + 1299, 1978, 1980, 3380, 3381, 1984, 1986, 1988, 1990, 1992, + 3365, 1817, 1175, 1967, 2623, 1530, 2088, 1531, 1532, 2616, + 1284, 1857, 1858, 2960, 3856, 1964, 1250, 1782, 1813, 1253, + 127, 1286, 1926, 3695, 3694, 1815, 1814, 2621, 1301, 1247, + 2002, 1533, 1302, 2005, 1269, 2007, 3371, 2240, 2611, 2735, + 1970, 1969, 1307, 1959, 1944, 2619, 1186, 1184, 4329, 1956, + 1943, 1942, 2620, 2163, 2164, 2705, 2706, 1249, 4426, 3679, + 4201, 2616, 95, 59, 62, 61, 64, 4125, 78, 1820, + 2054, 87, 84, 101, 4197, 1263, 4340, 1805, 2063, 1300, + 2061, 2062, 2060, 2064, 2065, 2066, 1175, 2049, 1175, 1530, + 4196, 1531, 1532, 2173, 1088, 2010, 1557, 1558, 1560, 1559, + 1561, 1562, 2075, 2076, 2618, 4198, 66, 97, 96, 4202, + 1805, 76, 77, 63, 3379, 1533, 4126, 1174, 2245, 85, + 86, 4245, 1805, 1168, 1171, 1172, 3382, 1140, 1009, 1010, + 1011, 1165, 1169, 1530, 2047, 1531, 1532, 3750, 4411, 3751, + 1151, 4331, 1150, 136, 1149, 1555, 1556, 1557, 1558, 1560, + 1559, 1561, 1562, 1164, 4427, 4027, 4026, 4017, 2048, 1533, + 2093, 3767, 3766, 4195, 69, 3702, 70, 71, 72, 73, + 1320, 1320, 3701, 2089, 2090, 4243, 1805, 3691, 1530, 3405, + 1531, 1532, 3398, 3044, 2115, 3043, 92, 2094, 3042, 92, + 4241, 1805, 2582, 2036, 2101, 2102, 2103, 2050, 198, 1100, + 2731, 1174, 2034, 1174, 1533, 2046, 1178, 1168, 1178, 1168, + 2033, 1180, 2114, 1180, 2032, 1181, 1179, 1181, 1179, 2022, + 1249, 137, 4100, 1805, 2016, 2013, 2163, 2164, 2161, 2162, + 65, 2231, 1530, 2137, 1531, 1532, 2137, 180, 3136, 1182, + 2012, 2011, 4098, 1805, 1982, 1780, 3305, 1530, 3368, 1531, + 1532, 2202, 2202, 2160, 2200, 2200, 2203, 1496, 1533, 2091, + 46, 1100, 756, 46, 2035, 2393, 2095, 1860, 2097, 2098, + 2099, 2100, 4365, 1533, 2395, 2104, 1094, 4330, 2730, 1530, + 1805, 1531, 1532, 3027, 1095, 1099, 1100, 2116, 1551, 4153, + 1004, 1547, 3684, 1548, 756, 4152, 3025, 177, 756, 1530, + 178, 1531, 1532, 4129, 2165, 1533, 1936, 4378, 1549, 1563, + 1564, 1546, 1081, 4128, 1552, 1553, 1554, 1555, 1556, 1557, + 1558, 1560, 1559, 1561, 1562, 1533, 197, 4127, 1099, 1100, + 4317, 1805, 94, 3138, 2286, 1530, 4022, 1531, 1532, 1936, + 1805, 1765, 2223, 2212, 2213, 2214, 2215, 2225, 2216, 2217, + 2218, 2230, 2226, 2219, 2220, 2227, 2228, 2229, 2221, 2222, + 2224, 1533, 2592, 4007, 2591, 4095, 1805, 3651, 2590, 2178, + 2589, 2180, 2181, 2182, 2183, 2184, 2185, 2187, 2189, 2190, + 2191, 2192, 2193, 2194, 2140, 2138, 2142, 2140, 2138, 2235, + 2139, 4006, 1766, 2139, 2122, 2123, 2179, 1529, 1805, 2172, + 4077, 1805, 1576, 1530, 3855, 1531, 1532, 3148, 3147, 3146, + 3853, 2588, 3140, 2587, 3144, 3763, 3139, 1764, 3137, 2392, + 2241, 2177, 1530, 3142, 1531, 1532, 2774, 3617, 1805, 1533, + 1763, 1834, 3141, 1936, 4230, 110, 1529, 1805, 1551, 2405, + 3128, 2404, 100, 1762, 2310, 1805, 4146, 2206, 1533, 1593, + 2403, 3143, 3145, 181, 1936, 4211, 2302, 1530, 2722, 1531, + 1532, 3699, 187, 3683, 1552, 1553, 1554, 1555, 1556, 1557, + 1558, 1560, 1559, 1561, 1562, 2250, 2251, 2252, 2253, 1530, + 1835, 1531, 1532, 1533, 1530, 2394, 1531, 1532, 4307, 2264, + 1551, 1936, 4207, 2285, 3610, 1805, 4107, 1805, 3735, 4143, + 1805, 1530, 3372, 1531, 1532, 1533, 3376, 4030, 1805, 2471, + 1533, 1936, 4018, 2776, 3375, 1804, 1552, 1553, 1554, 1555, + 1556, 1557, 1558, 1560, 1559, 1561, 1562, 1533, 4054, 2402, + 3461, 3458, 2408, 2409, 3735, 1805, 108, 3401, 2504, 3400, + 1767, 3110, 110, 3607, 1805, 4053, 109, 3053, 3377, 111, + 3040, 1530, 112, 1531, 1532, 1936, 3733, 3373, 2616, 1805, + 75, 2405, 3374, 2492, 1761, 2724, 3658, 1805, 3605, 1805, + 4011, 111, 2403, 1755, 112, 2723, 2438, 1533, 2534, 108, + 117, 2688, 2171, 1530, 2451, 1531, 1532, 2300, 1551, 109, + 2714, 116, 172, 115, 2856, 1805, 3568, 1805, 3391, 3390, + 1530, 1098, 1531, 1532, 3388, 3389, 2444, 1805, 2445, 1533, + 2680, 1145, 2506, 2679, 1552, 1553, 1554, 1555, 1556, 1557, + 1558, 1560, 1559, 1561, 1562, 1530, 1533, 1531, 1532, 2638, + 2486, 2487, 1530, 2426, 1531, 1532, 2459, 3386, 3387, 1145, + 2544, 2545, 2546, 1089, 3386, 3385, 2993, 1805, 4010, 2529, + 1805, 1533, 2528, 1530, 2637, 1531, 1532, 2475, 1533, 2439, + 2510, 2452, 2698, 3097, 1930, 3078, 1805, 2383, 2384, 2385, + 2386, 2387, 3071, 3072, 3637, 2458, 2205, 1805, 3075, 1533, + 2118, 2468, 3014, 2084, 2407, 3566, 1805, 2410, 2411, 3562, + 1805, 2565, 2532, 2045, 2037, 3014, 2605, 2538, 2481, 2539, + 2540, 2541, 2542, 2543, 2571, 2027, 2490, 2547, 2023, 2019, + 2018, 2017, 1836, 2549, 1310, 1129, 2551, 2552, 2553, 2554, + 2516, 2515, 3058, 2428, 2533, 2514, 2531, 2530, 1529, 2602, + 1553, 1554, 1555, 1556, 1557, 1558, 1560, 1559, 1561, 1562, + 2581, 1130, 1530, 3323, 1531, 1532, 1530, 4185, 1531, 1532, + 3015, 1177, 3353, 1530, 3651, 1531, 1532, 1551, 3559, 1805, + 3017, 1963, 2698, 3015, 1936, 1935, 2610, 2947, 1533, 2613, + 4157, 2614, 1533, 2698, 2562, 2566, 2555, 2557, 2558, 1533, + 2580, 110, 2630, 1552, 1553, 1554, 1555, 1556, 1557, 1558, + 1560, 1559, 1561, 1562, 1551, 117, 1930, 1929, 1872, 1871, + 3655, 2608, 2609, 1176, 2612, 2566, 116, 2617, 115, 2634, + 2984, 2631, 2984, 2635, 2636, 1530, 110, 1531, 1532, 4332, + 1552, 1553, 1554, 1555, 1556, 1557, 1558, 1560, 1559, 1561, + 1562, 3557, 1805, 116, 2992, 1076, 1936, 4121, 2703, 3555, + 1805, 1533, 2993, 173, 2642, 2945, 3596, 1075, 1075, 1075, + 185, 3553, 1805, 3388, 2641, 1552, 1553, 1554, 1555, 1556, + 1557, 1558, 1560, 1559, 1561, 1562, 3703, 1586, 3654, 1586, + 3280, 2616, 2517, 3551, 1805, 1530, 2856, 1531, 1532, 2759, + 1998, 1805, 198, 3549, 1805, 2718, 103, 2993, 1530, 3651, + 1531, 1532, 193, 2758, 1839, 2993, 1530, 2616, 1531, 1532, + 1530, 1533, 1531, 1532, 2599, 137, 2484, 1529, 1530, 3158, + 1531, 1532, 2470, 2672, 1533, 1821, 2429, 2405, 101, 2404, + 2205, 180, 1533, 3704, 3705, 3706, 1533, 2143, 2721, 2127, + 1530, 2069, 1531, 1532, 1533, 3547, 1805, 1999, 2000, 2001, + 1530, 1859, 1531, 1532, 1837, 174, 179, 176, 182, 183, + 184, 186, 188, 189, 190, 191, 1533, 3545, 1805, 1159, + 1158, 192, 194, 195, 196, 1838, 1533, 101, 2690, 3543, + 1805, 4288, 4213, 3408, 3541, 1805, 2231, 3453, 3539, 1805, + 4041, 177, 4008, 2696, 178, 3050, 3537, 1805, 3868, 1252, + 3535, 1805, 1530, 130, 1531, 1532, 2711, 3716, 2713, 2704, + 3713, 3697, 4042, 3533, 1805, 3493, 3509, 2716, 3508, 2717, + 197, 2710, 1932, 2564, 1530, 3410, 1531, 1532, 1533, 2707, + 2708, 2709, 1530, 2712, 1531, 1532, 1530, 2172, 1531, 1532, + 3406, 1530, 2719, 1531, 1532, 1530, 3303, 1531, 1532, 3079, + 1533, 2561, 2556, 1530, 2550, 1531, 1532, 1530, 1533, 1531, + 1532, 2548, 1533, 3531, 1805, 2052, 1958, 1533, 3529, 1805, + 1530, 1533, 1531, 1532, 3515, 1805, 1954, 2682, 2683, 1533, + 1928, 2734, 2685, 1533, 2579, 128, 1805, 3049, 3665, 3666, + 2442, 2686, 4373, 4371, 2900, 4324, 1533, 2223, 2212, 2213, + 2214, 2215, 2225, 2216, 2217, 2218, 2230, 2226, 2219, 2220, + 2227, 2228, 2229, 2221, 2222, 2224, 3707, 3491, 1805, 4165, + 1530, 4082, 1531, 1532, 4049, 1530, 2932, 1531, 1532, 2120, + 3668, 1530, 3636, 1531, 1532, 2202, 1994, 2770, 2200, 2935, + 3635, 3050, 1530, 3634, 1531, 1532, 1533, 181, 3323, 2921, + 1805, 1533, 3298, 2919, 1805, 710, 187, 1533, 2894, 1805, + 1075, 2673, 2871, 1805, 3671, 3670, 2863, 1805, 1533, 3708, + 3709, 3710, 1833, 3342, 1530, 3345, 1531, 1532, 2933, 3341, + 3346, 1530, 4161, 1531, 1532, 4315, 2990, 2991, 4142, 1995, + 1996, 1997, 3343, 2854, 1805, 2504, 2121, 3344, 1075, 3010, + 1533, 4043, 2474, 2448, 2852, 1805, 1530, 1533, 1531, 1532, + 1530, 2741, 1531, 1532, 2936, 1530, 2938, 1531, 1532, 1530, + 2171, 1531, 1532, 1530, 3659, 1531, 1532, 2888, 2756, 1091, + 2772, 1081, 1533, 2989, 773, 3347, 1533, 3002, 3003, 2969, + 1081, 1533, 3312, 3314, 1530, 1533, 1531, 1532, 3285, 1533, + 1530, 3315, 1531, 1532, 3284, 2839, 1805, 3644, 4124, 2953, + 46, 1530, 3846, 1531, 1532, 3643, 3848, 2837, 1805, 3007, + 1533, 2985, 3009, 3647, 2923, 3008, 1533, 1773, 2978, 3822, + 1092, 3821, 3309, 2835, 1805, 2068, 172, 1533, 1059, 3384, + 3032, 3054, 2952, 2948, 2665, 2943, 2951, 2664, 2833, 1805, + 1215, 2663, 2248, 3035, 3037, 1827, 2967, 3038, 3083, 1805, + 2662, 2981, 1530, 2661, 1531, 1532, 2831, 1805, 3028, 2249, + 1766, 3012, 2660, 2659, 1530, 3052, 1531, 1532, 2829, 1805, + 3055, 3056, 2966, 1108, 3820, 2827, 1805, 3016, 1533, 1214, + 1530, 3019, 1531, 1532, 2825, 1805, 108, 1107, 3094, 3026, + 1533, 108, 110, 3673, 2571, 1530, 109, 1531, 1532, 3029, + 3469, 109, 3049, 2823, 1805, 1530, 1533, 1531, 1532, 2168, + 2166, 2167, 3041, 1530, 3612, 1531, 1532, 3122, 4313, 1495, + 4347, 1533, 2821, 1805, 3085, 1530, 137, 1531, 1532, 3649, + 3051, 1533, 1530, 110, 1531, 1532, 2819, 1805, 4403, 1533, + 3302, 1530, 3059, 1531, 1532, 2486, 2487, 2817, 1805, 2676, + 1530, 1533, 1531, 1532, 3091, 2815, 1805, 1946, 1533, 117, + 1530, 4248, 1531, 1532, 4037, 4349, 3383, 1533, 3080, 3081, + 116, 1530, 115, 1531, 1532, 2428, 1533, 3132, 3133, 1530, + 110, 1531, 1532, 2813, 1805, 3090, 1533, 3006, 2469, 1146, + 4348, 3283, 3619, 1530, 2702, 1531, 1532, 1533, 115, 3282, + 2811, 1805, 2126, 4106, 1530, 1533, 1531, 1532, 4105, 3092, + 2125, 4085, 1530, 3854, 1531, 1532, 3111, 3852, 3851, 1533, + 3833, 2809, 1805, 3149, 3114, 3714, 3648, 3646, 2807, 1805, + 1533, 3411, 3130, 2805, 1805, 2600, 1941, 1106, 1533, 3608, + 1530, 116, 1531, 1532, 3832, 3629, 3574, 3167, 3168, 3169, + 3170, 3171, 3172, 3173, 3174, 3175, 3176, 1530, 2984, 1531, + 1532, 117, 3806, 4375, 4374, 4374, 1533, 3184, 2800, 1805, + 2947, 3186, 116, 3150, 4014, 2760, 2440, 173, 1530, 3718, + 1531, 1532, 1853, 1533, 185, 1530, 1852, 1531, 1532, 3134, + 1530, 1844, 1531, 1532, 1843, 4375, 1530, 3151, 1531, 1532, + 121, 122, 117, 1530, 1533, 1531, 1532, 2796, 1805, 4130, + 3682, 1533, 3131, 116, 3, 115, 1533, 2794, 1805, 4194, + 3244, 105, 1533, 3188, 8, 1530, 193, 1531, 1532, 1533, + 1530, 3120, 1531, 1532, 3121, 1530, 5, 1531, 1532, 1, + 2392, 1067, 2392, 1498, 1761, 1806, 1808, 1497, 3686, 1759, + 4277, 1533, 2787, 1805, 1757, 726, 1533, 1758, 1756, 2430, + 1760, 1533, 3070, 3570, 1530, 1771, 1531, 1532, 4325, 4273, + 4274, 2038, 3262, 3253, 1530, 2028, 1531, 1532, 2504, 174, + 179, 176, 182, 183, 184, 186, 188, 189, 190, 191, + 1533, 3745, 2357, 4038, 3177, 192, 194, 195, 196, 3834, + 1533, 3045, 3835, 3837, 3224, 3506, 2394, 1896, 2394, 1530, + 3414, 1531, 1532, 2606, 3712, 2569, 1167, 162, 2526, 3330, + 1530, 92, 1531, 1532, 2504, 2504, 2504, 2504, 2504, 2527, + 4225, 3152, 125, 1133, 3252, 1533, 3254, 3234, 3235, 3236, + 3237, 3238, 124, 1170, 2504, 1283, 1533, 2504, 2601, 3736, + 3033, 3261, 2506, 3262, 2535, 1878, 1876, 1530, 3289, 1531, + 1532, 3287, 1530, 1877, 1531, 1532, 1081, 1875, 1936, 3251, + 1880, 1879, 4189, 3273, 3477, 2761, 3575, 2131, 2080, 3274, + 3276, 3278, 3335, 1533, 3286, 3352, 3279, 763, 1533, 3288, + 3005, 757, 3296, 200, 1867, 1078, 1845, 2124, 2506, 2506, + 2506, 2506, 2506, 3299, 3300, 3301, 1209, 3431, 716, 3392, + 2639, 3505, 3316, 3317, 722, 1583, 2119, 3439, 2506, 3281, + 3020, 2506, 1127, 1119, 3354, 1096, 2441, 3355, 1080, 3336, + 2937, 3444, 3339, 1126, 3443, 3440, 4015, 3337, 3338, 3348, + 3340, 111, 3396, 3397, 112, 3334, 1079, 3331, 3641, 3497, + 3356, 3308, 3310, 2971, 3313, 3319, 3306, 3321, 3362, 2785, + 1805, 4123, 3845, 3226, 3326, 3228, 1883, 3495, 1530, 3326, + 1531, 1532, 4346, 4212, 3393, 3030, 3395, 3394, 1840, 2917, + 3595, 3239, 3240, 3241, 3242, 2733, 2238, 1573, 2916, 788, + 2503, 959, 1825, 3801, 1533, 2912, 2158, 786, 3412, 785, + 2911, 783, 2939, 2571, 3433, 2986, 1530, 1537, 1531, 1532, + 1536, 994, 2927, 3450, 1854, 2910, 1530, 2997, 1531, 1532, + 2909, 2995, 2994, 2674, 1530, 2511, 1531, 1532, 2908, 3667, + 3663, 3462, 1533, 4269, 3465, 3464, 1530, 2907, 1531, 1532, + 2505, 2501, 1533, 2946, 945, 1530, 3472, 1531, 1532, 944, + 1533, 3413, 1530, 795, 1531, 1532, 3482, 1530, 787, 1531, + 1532, 1897, 1533, 3498, 3499, 3500, 3501, 3502, 777, 1008, + 943, 1533, 1530, 942, 1531, 1532, 3441, 1530, 1533, 1531, + 1532, 3442, 2961, 1533, 1818, 1530, 1586, 1531, 1532, 4314, + 1586, 3304, 2963, 3031, 1530, 3292, 1531, 1532, 1533, 1514, + 1790, 1793, 2449, 1533, 3479, 3480, 3620, 3481, 3622, 1811, + 3483, 1533, 3485, 3474, 3487, 4148, 2701, 3503, 1789, 2898, + 1533, 3630, 4155, 2897, 3422, 3730, 3473, 1910, 1913, 1914, + 1915, 1916, 1917, 1918, 3403, 1919, 1920, 1922, 1923, 1921, + 1924, 1925, 1898, 1899, 1900, 1901, 1881, 1882, 1911, 3076, + 1884, 2593, 1885, 1886, 1887, 1888, 1889, 1890, 1891, 1892, + 1893, 2896, 74, 1894, 1902, 1903, 1904, 1905, 50, 1906, + 1907, 1908, 1909, 4115, 3329, 1895, 1530, 2895, 1531, 1532, + 1530, 4186, 1531, 1532, 2504, 937, 934, 3803, 3804, 3805, + 3247, 3621, 3248, 3623, 3625, 4168, 2892, 3680, 4169, 933, + 4170, 2295, 1533, 3627, 1508, 1505, 1533, 3060, 2133, 104, + 40, 3444, 39, 38, 3443, 3440, 2887, 3681, 1530, 3638, + 1531, 1532, 3645, 2880, 3590, 37, 3597, 2879, 3599, 3600, + 3601, 3594, 36, 3650, 1530, 2878, 1531, 1532, 30, 29, + 28, 3434, 27, 2877, 1533, 26, 33, 3669, 3467, 3468, + 23, 3672, 3662, 1530, 2876, 1531, 1532, 25, 2506, 3674, + 1533, 24, 2243, 22, 3675, 4385, 4386, 2244, 4415, 3692, + 3693, 3676, 3677, 1530, 2875, 1531, 1532, 4251, 4191, 1533, + 1530, 2874, 1531, 1532, 1530, 2873, 1531, 1532, 3425, 3698, + 2872, 3700, 1530, 4320, 1531, 1532, 4402, 131, 4351, 1533, + 1530, 4312, 1531, 1532, 4311, 2306, 1533, 4262, 4391, 4257, + 1533, 1530, 2866, 1531, 1532, 60, 57, 3723, 1533, 2865, + 55, 3727, 3728, 3729, 139, 138, 1533, 58, 56, 2864, + 54, 1530, 53, 1531, 1532, 1255, 51, 1533, 1530, 2861, + 1531, 1532, 1530, 102, 1531, 1532, 2860, 1530, 35, 1531, + 1532, 3740, 3741, 3742, 34, 21, 20, 1533, 19, 2859, + 18, 17, 16, 15, 1533, 11, 10, 2857, 1533, 1530, + 43, 1531, 1532, 1533, 42, 41, 1530, 32, 1531, 1532, + 2850, 31, 44, 7, 3757, 2389, 1530, 2847, 1531, 1532, + 2, 3063, 1912, 2595, 0, 1533, 1530, 0, 1531, 1532, + 0, 0, 1533, 1530, 0, 1531, 1532, 0, 2845, 0, + 0, 3768, 1533, 0, 0, 2420, 1530, 0, 1531, 1532, + 2843, 0, 1533, 0, 1530, 0, 1531, 1532, 0, 1533, + 0, 0, 1806, 2427, 1767, 2802, 0, 1530, 0, 1531, + 1532, 0, 1533, 0, 1530, 2782, 1531, 1532, 0, 3819, + 1533, 0, 3826, 0, 3828, 0, 0, 2781, 3809, 0, + 3810, 3811, 3812, 1533, 0, 1530, 0, 1531, 1532, 0, + 1533, 0, 2777, 2453, 0, 3762, 3799, 1530, 0, 1531, + 1532, 0, 0, 0, 2775, 3330, 0, 0, 92, 0, + 3330, 1533, 1530, 0, 1531, 1532, 0, 2767, 3829, 0, + 0, 2738, 1530, 1533, 1531, 1532, 2732, 0, 2202, 0, + 0, 2200, 3870, 0, 1530, 0, 1531, 1532, 1533, 0, + 0, 0, 2727, 0, 0, 3830, 0, 0, 1533, 1530, + 0, 1531, 1532, 1081, 0, 3862, 3860, 0, 3850, 3849, + 1533, 1530, 0, 1531, 1532, 0, 0, 3857, 0, 3859, + 0, 0, 0, 4021, 1530, 1533, 1531, 1532, 1530, 0, + 1531, 1532, 46, 1530, 0, 1531, 1532, 1533, 0, 0, + 0, 0, 3719, 3720, 0, 0, 3874, 0, 0, 1530, + 1533, 1531, 1532, 0, 1533, 0, 0, 0, 0, 1533, + 0, 3871, 3872, 0, 0, 0, 4013, 0, 0, 2583, + 0, 0, 0, 0, 4012, 1533, 0, 0, 0, 0, + 4028, 0, 0, 0, 0, 4040, 4032, 4023, 4024, 4025, + 0, 1795, 0, 0, 0, 4079, 4080, 4033, 3326, 0, + 0, 0, 0, 2202, 0, 1803, 2200, 4083, 1796, 3864, + 0, 0, 0, 0, 0, 3827, 1539, 1540, 1541, 1542, + 1543, 1544, 1538, 1535, 2998, 3001, 3002, 3003, 2999, 0, + 3000, 3004, 0, 2446, 2447, 1802, 1800, 1801, 1797, 0, + 1798, 0, 0, 0, 3790, 2998, 3001, 3002, 3003, 2999, + 0, 3000, 3004, 4086, 0, 3665, 3666, 4089, 0, 0, + 0, 4131, 3330, 1799, 0, 0, 0, 0, 0, 0, + 3866, 0, 0, 0, 0, 0, 1604, 1605, 1606, 1607, + 1608, 1609, 1610, 1611, 1612, 1613, 1614, 1615, 1616, 1617, + 1618, 1619, 1620, 1621, 1622, 1624, 1625, 1626, 1627, 1628, + 1629, 1630, 1631, 1632, 1633, 1634, 1635, 1636, 1637, 1638, + 1639, 1640, 1641, 1642, 1643, 1644, 1645, 1646, 1647, 1648, + 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, 1658, + 1659, 1660, 1661, 1662, 1663, 1664, 1665, 1666, 1667, 1668, + 1669, 1670, 1671, 1672, 1673, 1674, 1675, 1676, 1677, 1678, + 1679, 1680, 1681, 1682, 1683, 1684, 1685, 1686, 1687, 1688, + 1689, 1690, 1691, 1692, 1693, 1694, 1695, 1696, 1697, 1698, + 1699, 1700, 1701, 1703, 1704, 1705, 1706, 1707, 1708, 1709, + 1710, 1711, 1712, 1713, 1714, 1715, 1716, 1717, 1718, 1724, + 1725, 1726, 1727, 1741, 1742, 1743, 1744, 1745, 1746, 1747, + 1748, 1749, 1750, 1751, 1752, 1753, 1754, 4134, 4135, 4084, + 3329, 4132, 4103, 4113, 4112, 3329, 1795, 0, 0, 4109, + 4149, 4111, 0, 0, 0, 0, 0, 0, 0, 0, + 1803, 0, 0, 1796, 0, 0, 0, 0, 92, 0, + 0, 0, 2720, 0, 0, 0, 2725, 0, 4016, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1791, 1792, + 1802, 1800, 1801, 1797, 0, 1798, 0, 0, 0, 2728, + 0, 2729, 0, 4154, 4151, 0, 0, 2737, 4020, 4139, + 0, 2739, 2740, 1081, 0, 4156, 0, 0, 1799, 0, + 2746, 2747, 2748, 2749, 2750, 2751, 2752, 2753, 2754, 2755, + 0, 2757, 0, 0, 0, 0, 0, 4119, 0, 0, + 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, + 0, 92, 0, 0, 2763, 2764, 2765, 2766, 0, 2768, + 2769, 4193, 2771, 0, 4192, 0, 2773, 0, 0, 4209, + 2778, 2779, 0, 2780, 0, 0, 2783, 2784, 2786, 2788, + 2789, 2790, 2791, 2792, 2793, 2795, 2797, 2798, 2799, 2801, + 4200, 2803, 2804, 2806, 2808, 2810, 2812, 2814, 2816, 2818, + 2820, 2822, 2824, 2826, 2828, 2830, 2832, 2834, 2836, 2838, + 2840, 2841, 2842, 775, 2844, 4238, 2846, 4214, 2848, 2849, + 4203, 2851, 2853, 2855, 4199, 46, 92, 2858, 4040, 4227, + 4136, 2862, 4224, 4223, 4217, 2867, 2868, 2869, 2870, 4222, + 4219, 4218, 4216, 4221, 4220, 4184, 0, 3329, 2881, 2882, + 2883, 2884, 2885, 2886, 0, 4246, 2890, 2891, 0, 0, + 0, 0, 4264, 2893, 4174, 4263, 0, 4175, 2899, 0, + 0, 0, 0, 2902, 2903, 2904, 2905, 2906, 4276, 4304, + 4238, 4281, 4268, 92, 2913, 2914, 0, 2915, 4293, 0, + 2918, 2920, 2453, 4306, 2922, 4291, 0, 0, 0, 0, + 46, 0, 0, 0, 2934, 4205, 4303, 3326, 0, 0, + 0, 4210, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4308, 1767, 0, 0, 0, 1105, + 0, 0, 1111, 1111, 0, 0, 0, 2968, 92, 4319, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4345, + 2080, 0, 4334, 0, 4335, 2202, 0, 46, 2200, 4369, + 4338, 0, 4344, 0, 0, 0, 0, 0, 0, 4364, + 4141, 0, 0, 4368, 4366, 4372, 92, 4370, 4389, 0, + 0, 4163, 4238, 0, 0, 0, 4306, 0, 0, 4173, + 4379, 0, 3444, 0, 0, 3443, 3440, 0, 4390, 4400, + 0, 0, 0, 4159, 0, 4147, 0, 0, 0, 0, + 4299, 0, 46, 0, 0, 0, 4404, 0, 4412, 0, + 0, 4410, 92, 4417, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4420, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4423, 92, 0, 0, + 46, 0, 0, 1767, 0, 0, 0, 0, 4429, 2202, + 92, 92, 2200, 4433, 4432, 4437, 92, 4436, 4438, 4080, + 4306, 0, 4435, 0, 0, 0, 4306, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4204, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, - 137, 0, 159, 0, 46, 46, 0, 0, 0, 0, - 46, 0, 0, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 46, 46, 0, 0, 0, 198, + 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4256, + 0, 0, 137, 0, 159, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 180, 1057, + 0, 0, 4318, 0, 995, 1058, 1009, 1010, 1011, 996, + 0, 1896, 997, 998, 0, 999, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3162, 3163, 3164, + 3165, 3166, 170, 1012, 1013, 0, 0, 0, 158, 0, + 0, 0, 0, 0, 0, 0, 0, 3181, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, + 0, 178, 0, 0, 0, 0, 0, 0, 0, 0, + 4333, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 146, 147, 169, 168, 197, 0, 0, + 0, 0, 0, 0, 0, 0, 1014, 1015, 1016, 1017, + 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, + 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, + 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, + 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 4239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4248, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 170, 0, 0, 0, 0, 1893, 158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 177, 0, 0, 178, - 0, 0, 0, 0, 0, 0, 3155, 3156, 3157, 3158, - 3159, 0, 0, 0, 0, 0, 0, 0, 0, 1773, - 0, 146, 147, 169, 168, 197, 3174, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1933, 0, 0, 775, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4325, 0, 0, 0, 0, 0, 0, 0, 0, + 1883, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 198, 0, + 3447, 163, 144, 166, 151, 143, 0, 164, 165, 3069, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 137, 0, 159, 181, 0, 0, 0, 0, 0, + 0, 0, 0, 187, 152, 0, 0, 180, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 155, + 153, 148, 149, 150, 154, 0, 0, 0, 0, 0, + 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, + 156, 170, 0, 0, 0, 1897, 0, 158, 0, 0, + 0, 3448, 3449, 0, 0, 0, 3332, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, + 178, 0, 0, 0, 3350, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 708, 0, 0, 0, 0, 0, 0, + 0, 0, 1949, 1950, 169, 168, 197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1062, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 198, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3062, 0, 0, 163, - 144, 166, 151, 143, 1880, 164, 165, 0, 137, 0, - 159, 0, 0, 0, 0, 0, 0, 1140, 0, 0, - 0, 0, 181, 0, 180, 1105, 0, 0, 1111, 1111, - 0, 187, 152, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 155, 153, 148, - 149, 150, 154, 0, 0, 0, 0, 0, 170, 145, - 0, 0, 0, 0, 158, 0, 0, 0, 156, 0, + 0, 1910, 1913, 1914, 1915, 1916, 1917, 1918, 0, 1919, + 1920, 1922, 1923, 1921, 1924, 1925, 1898, 1899, 1900, 1901, + 1881, 1882, 1911, 172, 1884, 0, 1885, 1886, 1887, 1888, + 1889, 1890, 1891, 1892, 1893, 0, 0, 1894, 1902, 1903, + 1904, 1905, 0, 1906, 1907, 1908, 1909, 0, 0, 1895, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 177, 0, 0, 178, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1894, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1946, - 1947, 169, 168, 197, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 172, 0, 0, 0, 1907, 1910, 1911, 1912, 1913, - 1914, 1915, 0, 1916, 1917, 1919, 1920, 1918, 1921, 1922, - 1895, 1896, 1897, 1898, 1878, 1879, 1908, 0, 1881, 0, - 1882, 1883, 1884, 1885, 1886, 1887, 1888, 1889, 1890, 0, - 0, 1891, 1899, 1900, 1901, 1902, 0, 1903, 1904, 1905, - 1906, 0, 0, 1892, 0, 0, 0, 163, 1948, 166, - 0, 1945, 0, 164, 165, 0, 0, 0, 0, 0, + 1534, 0, 0, 3471, 0, 0, 0, 0, 0, 0, + 163, 1951, 166, 0, 1948, 0, 164, 165, 0, 0, + 0, 0, 0, 0, 0, 3488, 3489, 0, 3490, 3492, + 3494, 1592, 0, 181, 0, 0, 0, 0, 0, 0, + 0, 0, 187, 0, 0, 0, 0, 0, 0, 0, + 0, 167, 0, 0, 0, 0, 3507, 0, 0, 0, + 0, 3510, 0, 3512, 3513, 3514, 3516, 3517, 3518, 3519, + 3520, 3521, 3522, 3523, 3524, 3525, 3526, 3527, 3528, 3530, + 3532, 3534, 3536, 3538, 3540, 3542, 3544, 3546, 3548, 3550, + 3552, 3554, 3556, 3558, 3560, 3561, 3563, 3564, 3565, 3567, + 0, 0, 3569, 0, 3571, 3572, 3573, 0, 0, 3577, + 3578, 3579, 3580, 3581, 3582, 3583, 3584, 3585, 3586, 3587, + 0, 0, 0, 0, 0, 0, 0, 0, 3593, 0, + 0, 0, 3598, 0, 0, 0, 3602, 3603, 0, 3604, + 3606, 0, 3609, 3611, 0, 3613, 3614, 3615, 3616, 0, + 0, 0, 0, 0, 0, 3624, 0, 0, 0, 0, + 160, 0, 0, 161, 0, 0, 0, 0, 0, 0, + 0, 0, 172, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1912, 0, 0, 0, + 0, 0, 0, 0, 173, 0, 0, 0, 0, 0, + 0, 185, 0, 0, 0, 0, 3656, 3657, 4237, 0, + 3661, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 181, 0, 0, 0, 0, 0, 0, 0, 0, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3463, 0, 0, 0, 0, 0, 0, 0, 167, + 0, 0, 0, 193, 0, 0, 4236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3480, 3481, 0, 3482, 3484, 3486, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3499, 0, 0, 0, 0, 3502, - 0, 3504, 3505, 3506, 3508, 3509, 3510, 3511, 3512, 3513, - 3514, 3515, 3516, 3517, 3518, 3519, 3520, 3522, 3524, 3526, - 3528, 3530, 3532, 3534, 3536, 3538, 3540, 3542, 3544, 3546, - 3548, 3550, 3552, 3553, 3555, 3556, 3557, 3559, 0, 0, - 3561, 0, 3563, 3564, 3565, 0, 0, 3569, 3570, 3571, - 3572, 3573, 3574, 3575, 3576, 3577, 3578, 3579, 160, 172, - 0, 161, 0, 0, 0, 0, 3585, 0, 0, 0, - 3590, 0, 0, 0, 3594, 3595, 0, 3596, 3598, 0, - 3601, 3603, 0, 3605, 3606, 3607, 3608, 0, 0, 0, - 0, 0, 173, 3616, 0, 0, 0, 0, 0, 185, + 167, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1774, 0, 174, 179, 176, 182, + 183, 184, 186, 188, 189, 190, 191, 0, 0, 0, + 0, 3734, 192, 194, 195, 196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1909, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1842, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 91, 48, 49, 93, 0, 0, 0, + 3752, 0, 0, 3756, 0, 0, 0, 0, 708, 0, + 0, 0, 98, 0, 0, 0, 52, 81, 82, 1933, + 79, 83, 0, 0, 0, 0, 0, 0, 1062, 0, + 0, 0, 80, 0, 0, 0, 0, 3769, 0, 160, + 0, 0, 161, 0, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, + 0, 0, 1141, 173, 0, 0, 101, 0, 0, 0, + 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 193, 0, 3648, 3649, 0, 0, 3653, 0, 0, + 0, 3792, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3800, 0, 0, 0, 0, 0, + 0, 3807, 193, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 167, 0, 0, + 0, 0, 0, 0, 2085, 4388, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 174, 179, 176, 182, 183, 184, - 186, 188, 189, 190, 191, 0, 0, 0, 0, 0, - 192, 194, 195, 196, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 174, 179, 176, 182, 183, + 184, 186, 188, 189, 190, 191, 0, 0, 0, 0, + 0, 192, 194, 195, 196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3726, 198, + 0, 0, 0, 95, 59, 62, 61, 64, 0, 78, + 0, 0, 87, 84, 0, 4197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1942, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 137, 0, 159, 1255, 160, 1263, 0, 161, - 0, 0, 0, 0, 0, 0, 0, 3744, 180, 0, - 3748, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4196, 0, 0, 0, 0, 4029, 0, 0, 0, + 0, 0, 0, 0, 0, 4036, 4198, 66, 97, 96, + 0, 0, 76, 77, 63, 0, 0, 0, 0, 0, + 85, 86, 0, 0, 4046, 4047, 4048, 0, 4050, 0, + 4051, 4052, 0, 0, 0, 0, 4055, 4056, 4057, 4058, + 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, + 4069, 4070, 4071, 4072, 4073, 4074, 4075, 4076, 0, 4078, + 4081, 0, 0, 0, 4195, 69, 0, 70, 71, 72, + 73, 0, 0, 0, 0, 4090, 4091, 4092, 4093, 4094, + 4096, 4097, 4099, 4101, 4102, 4104, 0, 0, 0, 4108, + 0, 0, 0, 4110, 0, 0, 0, 0, 0, 0, + 4120, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 65, 0, 0, 0, 0, 0, 0, 0, 4140, + 0, 0, 0, 2153, 2154, 2155, 2156, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2169, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2208, 2209, 0, 0, 0, 0, + 2232, 0, 0, 2236, 2237, 0, 0, 0, 2242, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2254, 2255, 2256, 2257, 2258, 2259, 2260, + 2261, 2262, 2263, 94, 2265, 0, 0, 0, 2287, 2288, + 2289, 2290, 2291, 2292, 2293, 2294, 2296, 0, 2301, 0, + 2303, 2304, 2305, 0, 2307, 2308, 2309, 0, 2311, 2312, + 2313, 2314, 2315, 2316, 2317, 2318, 2319, 2320, 2321, 2322, + 2323, 2324, 2325, 2326, 2327, 2328, 2329, 2330, 2331, 2332, + 2333, 2334, 2335, 2336, 2337, 2338, 2339, 2340, 2341, 2342, + 2343, 2344, 2345, 2346, 2347, 2348, 2349, 2350, 2351, 2352, + 2353, 2354, 2355, 2356, 2360, 2361, 2362, 2363, 2364, 2365, + 2366, 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, + 2376, 2377, 2378, 2379, 2380, 2381, 2382, 0, 0, 0, + 0, 0, 2388, 0, 2390, 0, 2396, 2397, 2398, 2399, + 2400, 2401, 0, 100, 0, 4164, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2412, 2413, 2414, 2415, 2416, + 2417, 2418, 2419, 0, 2421, 2422, 2423, 2424, 2425, 4179, + 0, 0, 0, 0, 0, 4182, 0, 4183, 0, 0, + 0, 0, 0, 198, 0, 0, 0, 0, 0, 0, + 1256, 0, 1264, 0, 1945, 0, 0, 0, 0, 0, + 0, 0, 0, 4208, 1111, 0, 137, 0, 159, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 180, 0, 0, 0, 0, 0, 4232, 4233, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4240, 4242, 4244, 0, 0, 0, 91, 48, + 49, 93, 2482, 2483, 1504, 0, 170, 0, 0, 0, + 0, 75, 158, 0, 0, 0, 0, 98, 0, 0, + 4267, 52, 81, 82, 0, 79, 83, 0, 0, 0, + 2523, 4289, 177, 0, 0, 178, 0, 80, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 103, + 0, 0, 0, 0, 0, 0, 0, 1949, 1950, 169, + 168, 197, 0, 0, 0, 0, 0, 0, 0, 67, + 0, 0, 0, 990, 0, 0, 0, 0, 0, 0, + 0, 101, 0, 0, 0, 4316, 0, 0, 0, 0, + 0, 0, 2567, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4339, 4341, 4343, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 88, 0, 0, 203, 0, 0, 203, 0, 0, + 0, 761, 0, 0, 0, 0, 767, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, + 4384, 0, 0, 0, 0, 163, 1951, 166, 0, 1948, + 0, 164, 165, 0, 203, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 181, 0, + 0, 0, 0, 0, 0, 0, 0, 187, 4413, 4414, + 767, 203, 767, 0, 767, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 173, 0, 0, 0, 0, 0, 0, 185, 0, 0, - 0, 0, 170, 0, 3761, 0, 0, 0, 158, 0, - 0, 0, 0, 0, 0, 0, 0, 1057, 0, 1503, - 1100, 0, 0, 1058, 0, 0, 0, 0, 177, 0, - 0, 178, 0, 2198, 0, 0, 0, 0, 0, 193, - 0, 0, 0, 0, 0, 0, 1533, 0, 0, 0, - 0, 0, 0, 1946, 1947, 169, 168, 197, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3784, 0, - 0, 0, 0, 0, 0, 0, 0, 1591, 0, 0, - 0, 3792, 0, 0, 0, 0, 0, 1893, 3799, 0, - 0, 0, 174, 179, 176, 182, 183, 184, 186, 188, - 189, 190, 191, 0, 0, 0, 0, 0, 192, 194, - 195, 196, 0, 0, 1014, 1015, 1016, 1017, 1018, 1019, - 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, - 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, - 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, - 1050, 1051, 1052, 1053, 1054, 1055, 0, 0, 0, 0, - 0, 163, 1948, 166, 0, 1945, 0, 164, 165, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 95, 59, + 62, 61, 64, 0, 78, 4431, 0, 87, 84, 0, + 4197, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 181, 0, 0, 0, 0, 0, - 0, 0, 0, 187, 0, 0, 0, 0, 0, 0, + 0, 4198, 66, 97, 96, 0, 0, 76, 77, 63, + 91, 48, 49, 93, 0, 85, 86, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, + 0, 0, 0, 52, 81, 82, 0, 79, 83, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, + 0, 0, 0, 0, 0, 0, 0, 172, 0, 4195, + 69, 103, 70, 71, 72, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1856, 67, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 101, 0, 0, 0, 0, 0, 1873, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4021, 0, 0, 0, 0, 0, 0, - 0, 0, 4028, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1880, 0, 0, 0, - 0, 4038, 4039, 4040, 0, 4042, 0, 4043, 4044, 0, - 0, 0, 0, 4047, 4048, 4049, 4050, 4051, 4052, 4053, - 4054, 4055, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, - 4064, 4065, 4066, 4067, 4068, 0, 4070, 4073, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 4082, 4083, 4084, 4085, 4086, 4088, 4089, 4091, - 4093, 4094, 4096, 0, 0, 0, 4100, 0, 0, 0, - 4102, 0, 0, 172, 0, 0, 0, 4112, 0, 0, + 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, + 0, 0, 0, 0, 2736, 0, 0, 0, 0, 0, + 0, 0, 0, 88, 2742, 2743, 2744, 2745, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1894, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 167, 0, 0, 0, 0, + 0, 0, 0, 0, 2008, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1592, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1853, 0, 4132, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1841, 0, 0, 0, - 0, 0, 0, 1870, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2053, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1907, 1910, 1911, - 1912, 1913, 1914, 1915, 1930, 1916, 1917, 1919, 1920, 1918, - 1921, 1922, 1895, 1896, 1897, 1898, 1878, 1879, 1908, 0, - 1881, 167, 1882, 1883, 1884, 1885, 1886, 1887, 1888, 1889, - 1890, 0, 0, 1891, 1899, 1900, 1901, 1902, 0, 1903, - 1904, 1905, 1906, 0, 0, 1892, 0, 0, 2005, 0, - 0, 0, 990, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 94, 0, + 0, 2081, 0, 0, 0, 0, 0, 0, 0, 0, + 95, 59, 62, 61, 64, 0, 78, 2092, 0, 87, + 84, 0, 0, 0, 2096, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2107, 2108, 2109, 2110, 2111, + 2112, 2113, 0, 0, 160, 0, 0, 161, 0, 0, + 0, 0, 0, 0, 66, 97, 96, 0, 0, 76, + 77, 63, 0, 0, 0, 0, 0, 85, 86, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 173, 0, + 0, 0, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 100, 0, + 0, 68, 69, 0, 70, 71, 72, 73, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2050, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1842, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2078, 0, 0, 0, 0, - 0, 0, 0, 203, 0, 0, 203, 0, 0, 0, - 761, 2089, 0, 0, 0, 767, 0, 0, 2093, 2082, - 160, 0, 0, 161, 0, 0, 203, 0, 0, 2104, - 2105, 2106, 2107, 2108, 2109, 2110, 0, 0, 0, 0, - 0, 0, 0, 203, 0, 0, 0, 0, 0, 0, - 0, 0, 4156, 0, 173, 0, 0, 0, 0, 0, - 0, 185, 0, 0, 0, 0, 0, 0, 0, 767, - 203, 767, 0, 767, 0, 0, 4171, 0, 0, 0, - 0, 0, 4174, 0, 4175, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1057, - 0, 0, 0, 193, 995, 1058, 1009, 1010, 1011, 996, - 4200, 0, 997, 998, 0, 999, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1012, 1013, 4224, 4225, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 4232, - 4234, 4236, 1909, 0, 0, 0, 174, 179, 176, 182, - 183, 184, 186, 188, 189, 190, 191, 0, 0, 0, - 0, 0, 192, 194, 195, 196, 0, 4259, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 4281, 0, - 0, 0, 0, 0, 0, 0, 1014, 1015, 1016, 1017, - 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, - 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, - 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, - 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 4231, 0, - 0, 0, 4308, 0, 2143, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4331, 4333, 4335, 0, 0, 2150, 2151, - 2152, 2153, 0, 0, 0, 0, 0, 0, 0, 0, - 3439, 0, 0, 0, 2166, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 4376, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2205, - 2206, 0, 0, 0, 0, 2229, 0, 0, 2233, 2234, - 0, 0, 0, 2239, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4405, 4406, 0, 2251, 2252, - 2253, 2254, 2255, 2256, 2257, 2258, 2259, 2260, 0, 2262, - 0, 3440, 3441, 2284, 2285, 2286, 2287, 2288, 2289, 2290, - 2291, 2293, 0, 2298, 0, 2300, 2301, 2302, 0, 2304, - 2305, 2306, 4423, 2308, 2309, 2310, 2311, 2312, 2313, 2314, - 2315, 2316, 2317, 2318, 2319, 2320, 2321, 2322, 2323, 2324, - 2325, 2326, 2327, 2328, 2329, 2330, 2331, 2332, 2333, 2334, - 2335, 2336, 2337, 2338, 2339, 2340, 2341, 2342, 2343, 2344, - 2345, 2346, 2347, 2348, 2349, 2350, 2351, 2352, 2353, 2357, - 2358, 2359, 2360, 2361, 2362, 2363, 2364, 2365, 2366, 2367, - 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, - 2378, 2379, 0, 0, 0, 0, 0, 2385, 0, 2387, - 0, 2393, 2394, 2395, 2396, 2397, 2398, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2409, 2410, 2411, 2412, 2413, 2414, 2415, 2416, 0, 2418, - 2419, 2420, 2421, 2422, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 65, 0, + 174, 179, 176, 182, 183, 184, 186, 188, 189, 190, + 191, 0, 0, 0, 0, 0, 192, 194, 195, 196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1111, + 0, 0, 0, 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 91, 48, 49, 93, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, - 0, 0, 2484, 52, 81, 82, 0, 79, 83, 0, - 2488, 0, 2491, 0, 0, 2143, 0, 2478, 2479, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 103, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2517, 0, 0, 0, 0, 0, 0, - 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 101, 4413, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, - 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2561, 0, 0, 0, 0, - 0, 0, 0, 88, 0, 0, 0, 767, 0, 767, - 767, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 203, + 94, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 767, 203, 0, 0, 0, 0, 0, 4229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 767, 0, + 767, 767, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1577, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4228, 0, 0, 0, + 0, 0, 767, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2143, - 95, 59, 62, 61, 64, 2643, 78, 0, 0, 87, - 84, 0, 4189, 1057, 0, 0, 2664, 2665, 0, 1058, - 2669, 0, 0, 2672, 0, 0, 0, 0, 4188, 2198, - 0, 0, 0, 2675, 0, 0, 0, 0, 0, 0, - 2678, 0, 0, 4190, 66, 97, 96, 0, 0, 76, - 77, 63, 0, 0, 0, 0, 0, 85, 86, 0, - 0, 0, 0, 0, 0, 0, 2681, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3127, 0, 0, + 0, 1578, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 100, 0, 0, 0, 3153, 3154, 3155, 0, 0, 3157, + 0, 0, 3159, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3178, 3179, 3180, 0, 0, 0, 0, 0, + 0, 3185, 0, 0, 0, 0, 3187, 0, 0, 3189, + 3190, 3191, 0, 0, 0, 3192, 3193, 0, 0, 3194, + 0, 3195, 0, 0, 0, 0, 0, 0, 3196, 0, + 3197, 0, 0, 0, 3198, 0, 3199, 0, 0, 3200, + 0, 3201, 0, 3202, 0, 3203, 0, 3204, 0, 3205, + 0, 3206, 0, 3207, 0, 3208, 0, 3209, 0, 3210, + 0, 3211, 0, 3212, 0, 3213, 0, 3214, 0, 3215, + 0, 3216, 0, 3217, 0, 0, 0, 3218, 75, 3219, + 0, 3220, 0, 0, 3221, 0, 3222, 0, 3223, 0, + 2360, 3225, 0, 0, 3227, 0, 0, 3229, 3230, 3231, + 3232, 0, 0, 0, 0, 3233, 2360, 2360, 2360, 2360, + 2360, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3243, 0, 0, 0, 0, 0, 0, 0, 3256, + 0, 0, 3260, 1896, 0, 0, 0, 0, 0, 0, + 0, 3263, 3264, 3265, 3266, 3267, 3268, 0, 2488, 2489, + 3269, 3270, 0, 3271, 0, 3272, 0, 2493, 2494, 0, + 2497, 0, 0, 2146, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4187, 69, 0, 70, 71, 72, 73, 0, 0, - 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, - 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, - 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, - 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, - 1054, 1055, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 65, 0, + 0, 0, 0, 0, 203, 0, 0, 0, 767, 767, + 0, 0, 0, 0, 0, 0, 0, 0, 3320, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3351, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 767, 0, 0, 0, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 767, 0, 0, 0, 0, 0, 0, 203, 0, + 0, 0, 767, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1883, 0, 0, 0, 0, 0, 0, 0, + 0, 3409, 0, 0, 0, 0, 0, 767, 0, 767, + 0, 0, 0, 0, 0, 0, 0, 767, 0, 0, + 1578, 767, 0, 0, 767, 767, 767, 767, 0, 767, + 0, 767, 767, 0, 767, 767, 767, 767, 767, 767, + 0, 0, 0, 0, 0, 0, 0, 1578, 767, 767, + 1578, 767, 1578, 203, 767, 0, 0, 2146, 0, 0, + 0, 0, 0, 2649, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 203, 2670, 2671, 0, 0, 2675, 0, + 0, 2678, 0, 0, 0, 0, 767, 1897, 203, 0, + 0, 2681, 3496, 0, 0, 0, 0, 0, 2684, 0, + 0, 0, 767, 0, 0, 1057, 767, 0, 1100, 203, + 203, 1058, 0, 0, 0, 0, 0, 0, 0, 0, + 3511, 2201, 0, 0, 2687, 0, 203, 0, 0, 0, + 0, 0, 0, 203, 0, 0, 0, 0, 0, 0, + 0, 0, 203, 203, 203, 203, 203, 203, 203, 203, + 203, 767, 0, 1910, 1913, 1914, 1915, 1916, 1917, 1918, + 0, 1919, 1920, 1922, 1923, 1921, 1924, 1925, 1898, 1899, + 1900, 1901, 1881, 1882, 1911, 0, 1884, 0, 1885, 1886, + 1887, 1888, 1889, 1890, 1891, 1892, 1893, 0, 0, 1894, + 1902, 1903, 1904, 1905, 0, 1906, 1907, 1908, 1909, 0, + 0, 1895, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, + 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, + 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, + 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, + 1052, 1053, 1054, 1055, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2730, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2736, 2737, 2738, - 2739, 0, 0, 203, 0, 0, 0, 767, 767, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 203, 91, 48, - 49, 93, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1591, 0, 0, 0, 0, 98, 0, 0, - 94, 52, 81, 82, 767, 79, 83, 203, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 80, 0, 767, - 0, 0, 0, 0, 0, 0, 203, 0, 0, 103, - 767, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, - 0, 0, 0, 0, 0, 767, 0, 767, 0, 0, - 0, 101, 0, 0, 0, 767, 0, 0, 1577, 767, - 0, 0, 767, 767, 767, 767, 0, 767, 0, 767, - 767, 0, 767, 767, 767, 767, 767, 767, 0, 0, - 0, 0, 0, 0, 0, 1577, 767, 767, 1577, 767, - 1577, 203, 767, 0, 0, 0, 0, 0, 0, 0, - 100, 88, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 203, 0, 0, 0, 0, 0, 0, 0, 0, - 4380, 0, 0, 0, 767, 0, 203, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 767, 0, 0, 0, 767, 0, 0, 203, 203, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 203, 0, 0, 0, 0, 0, - 1841, 203, 0, 3004, 0, 0, 0, 0, 0, 0, - 203, 203, 203, 203, 203, 203, 203, 203, 203, 767, - 0, 0, 0, 0, 0, 0, 0, 0, 95, 59, - 62, 61, 64, 0, 78, 0, 0, 87, 84, 0, - 4189, 0, 0, 0, 0, 0, 0, 0, 75, 0, - 0, 0, 0, 0, 0, 0, 4188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4190, 66, 97, 96, 0, 0, 76, 77, 63, - 0, 0, 0, 0, 0, 85, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 4187, - 69, 0, 70, 71, 72, 73, 0, 3092, 3093, 3094, - 3095, 3096, 3097, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 989, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2143, 3108, 0, 0, + 0, 0, 0, 767, 767, 0, 0, 0, 0, 0, + 3715, 0, 0, 0, 0, 0, 0, 0, 767, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3739, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 744, 0, 0, 0, + 0, 0, 766, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 767, + 0, 0, 0, 0, 0, 0, 0, 0, 1912, 1578, + 0, 0, 0, 0, 0, 3758, 0, 3759, 0, 3760, + 0, 3761, 0, 0, 0, 0, 0, 1578, 0, 3764, + 3765, 0, 0, 0, 0, 0, 766, 0, 766, 3770, + 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3771, 0, 3772, 0, 3773, 0, 3774, + 0, 3775, 0, 3776, 0, 3777, 0, 3778, 0, 3779, + 0, 3780, 0, 3781, 0, 3782, 0, 3783, 0, 3784, + 0, 3785, 0, 3786, 0, 0, 3787, 0, 0, 0, + 3788, 0, 3789, 0, 0, 0, 0, 0, 3791, 0, + 0, 0, 0, 0, 3011, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3808, 0, 0, 0, 0, 0, 0, 0, 0, 3813, + 0, 3814, 3815, 0, 3816, 0, 3817, 0, 0, 0, + 0, 3818, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2406, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3858, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3867, + 0, 0, 3869, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3873, 0, 0, 0, 203, 0, + 0, 0, 0, 767, 101, 0, 0, 1057, 0, 0, + 0, 4009, 995, 1058, 1009, 1010, 1011, 996, 0, 0, + 997, 998, 0, 999, 0, 0, 0, 0, 3099, 3100, + 3101, 3102, 3103, 3104, 0, 0, 0, 767, 0, 1004, + 0, 1012, 1013, 0, 0, 203, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2146, 3115, 0, + 0, 0, 0, 0, 0, 0, 0, 203, 203, 0, + 0, 0, 767, 0, 0, 2406, 203, 203, 0, 203, + 0, 203, 203, 3123, 0, 0, 0, 0, 0, 0, + 0, 0, 3445, 3446, 0, 0, 767, 0, 0, 0, + 0, 0, 0, 0, 1014, 1015, 1016, 1017, 1018, 1019, + 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, + 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, + 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, + 1050, 1051, 1052, 1053, 1054, 1055, 4118, 0, 0, 0, + 0, 0, 0, 0, 767, 0, 0, 0, 0, 0, + 767, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 767, 0, 0, 0, + 0, 0, 767, 767, 0, 0, 767, 0, 767, 0, + 0, 0, 0, 0, 767, 0, 0, 0, 3447, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3116, 0, 0, 0, 65, 0, 0, 0, - 0, 767, 767, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 767, 3120, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3146, 3147, 3148, 0, 0, 3150, - 0, 0, 3152, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3171, 3172, 3173, 0, 0, 767, 0, 0, - 0, 3178, 0, 0, 0, 0, 3180, 1577, 0, 3182, - 3183, 3184, 0, 0, 0, 3185, 3186, 0, 94, 3187, - 0, 3188, 0, 0, 0, 1577, 0, 0, 3189, 0, - 3190, 0, 0, 0, 3191, 0, 3192, 0, 0, 3193, - 0, 3194, 0, 3195, 0, 3196, 0, 3197, 0, 3198, - 0, 3199, 0, 3200, 0, 3201, 0, 3202, 0, 3203, - 0, 3204, 0, 3205, 0, 3206, 0, 3207, 0, 3208, - 0, 3209, 0, 3210, 0, 0, 0, 3211, 0, 3212, - 0, 3213, 0, 0, 3214, 0, 3215, 0, 3216, 0, - 2357, 3218, 0, 0, 3220, 0, 0, 3222, 3223, 3224, - 3225, 0, 0, 0, 0, 3226, 2357, 2357, 2357, 2357, - 2357, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3236, 0, 0, 0, 0, 0, 0, 100, 3249, - 0, 0, 3253, 0, 0, 0, 0, 0, 0, 0, - 0, 3256, 3257, 3258, 3259, 3260, 3261, 0, 0, 0, - 3262, 3263, 0, 3264, 0, 3265, 0, 0, 0, 0, - 0, 2403, 3283, 3284, 0, 3288, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1111, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 767, + 0, 0, 0, 0, 767, 0, 0, 0, 767, 767, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, - 0, 767, 0, 0, 0, 0, 0, 0, 3313, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 203, 0, 0, 3448, + 3449, 0, 203, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 203, 203, 0, 0, 203, 0, 203, + 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 203, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3343, 0, 767, 75, 0, 0, 0, + 0, 0, 0, 3290, 3291, 0, 3295, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 0, 0, 0, + 203, 0, 0, 0, 0, 767, 0, 0, 0, 0, + 0, 0, 0, 4162, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 960, 0, 0, 0, + 0, 0, 964, 0, 0, 0, 961, 962, 0, 0, + 0, 963, 965, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4176, + 0, 0, 4177, 0, 4178, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1578, + 0, 2406, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 766, 1489, 766, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 203, 0, 0, 0, 767, - 0, 0, 2403, 203, 0, 203, 0, 203, 203, 0, - 0, 0, 0, 0, 0, 0, 0, 3429, 0, 0, - 3401, 0, 767, 0, 0, 0, 0, 0, 0, 0, - 0, 3443, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3455, 0, 0, 3458, + 0, 0, 0, 0, 0, 0, 0, 0, 766, 3437, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3451, 0, 0, 1057, 0, 0, 0, + 0, 995, 1058, 1009, 1010, 1011, 996, 1577, 3463, 997, + 998, 3466, 999, 0, 0, 0, 0, 0, 0, 0, + 4255, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1012, 1013, 0, 0, 0, 0, 0, 4287, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 767, 0, 0, 0, 0, 0, 767, 0, 0, 0, + 0, 0, 0, 0, 0, 4300, 0, 4301, 0, 4302, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 767, 0, 0, 0, 0, 0, 767, 767, - 0, 3488, 767, 0, 767, 0, 0, 0, 0, 0, - 767, 0, 989, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3503, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 946, + 0, 0, 0, 1014, 1015, 1016, 1017, 1018, 1019, 1020, + 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, + 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, + 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, + 1051, 1052, 1053, 1054, 1055, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 767, 0, 0, 0, 0, - 767, 0, 0, 0, 767, 767, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 744, - 0, 0, 0, 0, 0, 766, 0, 0, 0, 0, - 0, 0, 203, 0, 0, 0, 0, 0, 203, 0, - 0, 0, 0, 0, 3618, 0, 0, 0, 0, 203, - 203, 0, 0, 203, 0, 203, 203, 0, 0, 0, - 3624, 3625, 0, 0, 0, 0, 203, 0, 0, 0, - 0, 0, 0, 203, 0, 0, 0, 0, 0, 766, - 0, 766, 0, 766, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 203, - 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, - 0, 767, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 765, 203, 4382, 0, 4383, 0, 0, 0, + 0, 203, 0, 0, 0, 0, 3626, 0, 0, 0, + 0, 0, 767, 0, 0, 0, 0, 3447, 0, 0, + 0, 0, 3632, 3633, 0, 767, 767, 767, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 767, 4418, 4419, 0, 0, 1137, 0, 1144, 0, + 1148, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, + 0, 0, 0, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3688, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3448, 3449, + 0, 0, 0, 0, 766, 766, 0, 3696, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1577, 0, 2403, 3707, 0, + 0, 0, 0, 767, 0, 0, 0, 0, 0, 0, + 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 767, 0, 0, 766, 0, 0, + 0, 767, 0, 0, 0, 767, 767, 0, 766, 0, + 767, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1578, 767, 0, 0, + 0, 0, 0, 766, 0, 766, 0, 203, 203, 203, + 203, 203, 203, 766, 0, 0, 1577, 766, 0, 0, + 766, 766, 766, 766, 0, 766, 0, 766, 766, 0, + 766, 766, 766, 766, 766, 766, 203, 203, 0, 0, + 0, 0, 0, 1577, 766, 766, 1577, 766, 1577, 0, + 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 203, 0, 0, 1057, 0, 0, 0, 0, + 0, 1058, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2201, 766, 0, 0, 0, 0, 0, 767, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 766, 0, + 0, 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 767, 0, + 0, 0, 0, 0, 0, 0, 0, 766, 0, 0, + 0, 0, 0, 0, 0, 0, 3841, 0, 0, 3842, + 3843, 3844, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, + 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, + 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, + 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, + 1052, 1053, 1054, 1055, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3731, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 91, 48, 49, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 98, 0, 0, 0, 52, 81, 82, 0, - 79, 83, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 80, 3750, 0, 3751, 0, 3752, 0, 3753, - 0, 0, 0, 0, 103, 0, 0, 3756, 3757, 0, - 0, 0, 0, 0, 0, 0, 946, 3762, 0, 0, - 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, - 0, 3763, 0, 3764, 0, 3765, 101, 3766, 0, 3767, - 0, 3768, 0, 3769, 0, 3770, 0, 3771, 0, 3772, - 0, 3773, 0, 3774, 0, 3775, 0, 3776, 0, 3777, - 0, 3778, 0, 0, 3779, 0, 0, 0, 3780, 0, - 3781, 0, 0, 0, 0, 0, 3783, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 88, 0, 0, 765, - 0, 0, 0, 0, 0, 0, 0, 0, 3800, 0, - 0, 0, 0, 0, 0, 0, 0, 3805, 0, 3806, - 3807, 0, 3808, 3833, 3809, 0, 3834, 3835, 3836, 3810, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 203, - 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, - 0, 0, 0, 1136, 0, 1143, 0, 1147, 767, 0, - 0, 0, 0, 0, 3850, 0, 0, 0, 0, 0, - 767, 767, 767, 203, 0, 0, 0, 3859, 0, 0, - 3861, 0, 0, 0, 0, 0, 767, 0, 0, 0, - 0, 0, 3865, 95, 59, 62, 61, 64, 0, 78, - 0, 0, 87, 84, 0, 4189, 0, 0, 0, 4001, - 0, 203, 0, 0, 0, 0, 203, 0, 0, 0, - 0, 4188, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4190, 66, 97, 96, - 0, 0, 76, 77, 63, 0, 0, 0, 0, 0, - 85, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 767, 0, 0, 0, - 0, 0, 0, 0, 4187, 69, 0, 70, 71, 72, - 73, 0, 0, 0, 0, 0, 0, 767, 0, 0, - 0, 0, 0, 0, 767, 0, 0, 0, 767, 767, 0, 0, 0, 767, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1577, - 767, 0, 0, 0, 4110, 0, 0, 0, 0, 0, - 203, 203, 203, 203, 203, 203, 0, 0, 0, 0, - 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 203, - 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 91, 48, 49, 93, 0, - 0, 0, 0, 0, 0, 203, 0, 0, 0, 0, - 0, 0, 0, 0, 98, 0, 0, 0, 52, 81, - 82, 0, 79, 83, 0, 0, 0, 766, 1488, 766, - 766, 767, 0, 0, 80, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 103, 0, 0, 0, - 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 94, 0, 0, 67, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 101, 0, - 1576, 767, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 88, 0, - 0, 0, 0, 0, 4152, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 767, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4154, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 767, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 4168, 767, 0, - 4169, 0, 4170, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 95, 59, 62, 61, 64, - 0, 78, 0, 0, 87, 84, 0, 0, 0, 767, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 203, 203, 203, 0, 203, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, - 97, 96, 0, 0, 76, 77, 63, 0, 0, 0, - 0, 0, 85, 86, 0, 0, 0, 0, 0, 767, - 0, 75, 0, 1577, 0, 0, 767, 767, 1577, 203, - 203, 203, 203, 203, 0, 0, 0, 0, 4247, 0, - 0, 203, 0, 0, 0, 0, 0, 203, 0, 203, - 0, 0, 203, 203, 203, 4279, 68, 69, 0, 70, - 71, 72, 73, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 766, 766, 0, - 0, 0, 0, 4292, 0, 4293, 0, 4294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1321, 0, 1321, 1321, 0, 0, 767, 0, 0, - 1577, 0, 0, 0, 0, 767, 0, 0, 0, 0, - 203, 0, 0, 65, 766, 1502, 0, 0, 0, 0, - 0, 0, 0, 0, 203, 0, 0, 0, 0, 766, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 203, - 766, 0, 203, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 766, 0, 766, 0, 0, - 0, 0, 4374, 0, 4375, 766, 0, 0, 1576, 766, - 0, 0, 766, 766, 766, 766, 0, 766, 0, 766, - 766, 0, 766, 766, 766, 766, 766, 766, 0, 0, - 0, 0, 0, 0, 0, 1576, 766, 766, 1576, 766, - 1576, 0, 766, 0, 0, 94, 0, 0, 0, 0, - 4410, 4411, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1057, 0, 0, 0, 0, 995, 1058, 1009, - 1010, 1011, 996, 0, 766, 997, 998, 0, 999, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 766, 0, 0, 0, 766, 0, 1012, 1013, 0, 0, - 767, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 203, 203, 203, 0, 203, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 766, + 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 766, 0, 767, 0, 0, 0, + 0, 1578, 0, 0, 767, 767, 1578, 203, 203, 203, + 203, 203, 0, 0, 0, 0, 0, 0, 0, 203, + 0, 0, 0, 0, 0, 203, 0, 203, 0, 0, + 203, 203, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 766, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1577, 0, 0, 0, 0, + 0, 0, 0, 0, 2210, 0, 0, 0, 0, 0, + 0, 0, 0, 1577, 0, 767, 0, 0, 1578, 0, + 0, 0, 0, 767, 0, 0, 0, 0, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 203, 0, 766, + 0, 0, 203, 0, 1322, 0, 1322, 1322, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, + 203, 0, 0, 0, 0, 0, 0, 0, 1503, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 203, 203, 100, 0, 0, 0, 1014, - 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, - 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, - 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, - 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, - 1055, 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, - 0, 1776, 1777, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3439, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 767, 767, 0, 0, 0, - 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1847, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1865, 0, 0, 0, 0, 767, 767, - 767, 767, 0, 0, 1924, 0, 0, 0, 0, 0, - 0, 766, 766, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3440, 3441, 766, 0, 0, 1136, - 0, 1954, 0, 0, 0, 0, 0, 0, 0, 1963, - 0, 0, 0, 1965, 0, 0, 1968, 1969, 1971, 1971, - 0, 1971, 0, 1971, 1971, 0, 1980, 1971, 1971, 1971, - 1971, 1971, 0, 0, 0, 0, 0, 0, 0, 0, - 2000, 2001, 0, 1136, 0, 0, 2006, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 766, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1576, 0, 0, - 0, 0, 0, 0, 0, 0, 2207, 0, 2048, 0, - 0, 0, 0, 0, 0, 1576, 0, 0, 0, 0, - 0, 0, 0, 0, 2069, 0, 0, 0, 2074, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 767, 0, 767, 0, 203, - 0, 0, 0, 1321, 0, 0, 203, 0, 0, 203, - 203, 203, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1577, 0, 0, 0, - 203, 0, 0, 767, 0, 767, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4160, 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 767, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 203, 0, 0, 767, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 767, + 0, 0, 0, 0, 0, 0, 0, 0, 767, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 203, 0, 0, 0, 0, + 0, 0, 0, 766, 0, 0, 0, 0, 0, 0, + 0, 203, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 766, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 766, 0, + 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1321, 1321, 0, 0, 0, - 0, 0, 0, 0, 767, 0, 0, 0, 0, 766, - 2131, 767, 766, 767, 0, 0, 0, 0, 0, 0, - 0, 0, 767, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 766, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 766, 0, 0, 0, 0, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 767, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2193, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 766, 0, 0, 0, 0, 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 766, 0, 0, 0, 767, 767, 766, 0, 0, 0, + 0, 0, 0, 0, 1777, 1778, 0, 0, 0, 0, 0, 0, 766, 0, 0, 0, 0, 0, 766, 766, 0, 0, 766, 0, 766, 0, 0, 0, 0, 0, - 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 101, 0, 0, 1057, 0, 0, 0, - 0, 995, 1058, 1009, 1010, 1011, 996, 0, 0, 997, - 998, 0, 999, 0, 0, 766, 0, 0, 0, 0, - 766, 0, 0, 0, 766, 766, 0, 0, 1004, 0, - 1012, 1013, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 767, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 203, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 767, 203, 0, 0, - 0, 3437, 3438, 0, 0, 1321, 0, 0, 0, 0, - 0, 0, 0, 1014, 1015, 1016, 1017, 1018, 1019, 1020, - 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, - 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, - 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, - 1051, 1052, 1053, 1054, 1055, 2440, 0, 0, 0, 0, - 0, 766, 767, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 767, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1577, 767, 0, 767, 2456, - 0, 0, 0, 0, 0, 947, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3439, 0, 0, - 0, 0, 767, 2403, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1847, 0, 0, 1321, 0, 0, 0, - 0, 0, 0, 0, 0, 1576, 0, 766, 0, 0, - 0, 0, 0, 0, 0, 0, 1136, 0, 0, 0, - 0, 0, 767, 767, 0, 0, 201, 0, 0, 709, - 0, 0, 0, 203, 767, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 709, - 0, 0, 0, 0, 0, 0, 0, 0, 3440, 3441, - 0, 0, 0, 0, 0, 0, 1086, 0, 0, 0, - 0, 0, 767, 0, 1143, 0, 0, 0, 0, 0, - 2580, 0, 0, 0, 1112, 1112, 0, 0, 0, 0, - 0, 0, 0, 709, 0, 0, 1136, 0, 0, 0, - 0, 0, 1143, 1963, 0, 0, 1963, 0, 1963, 0, - 0, 0, 0, 767, 2609, 203, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 767, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 767, 0, 0, 0, 0, 0, 0, 1136, - 0, 0, 0, 0, 2193, 960, 0, 0, 2193, 2193, - 0, 964, 0, 0, 0, 961, 962, 0, 0, 0, - 963, 965, 0, 767, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 766, 0, 0, 0, 0, 0, 0, 767, 767, 767, + 767, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1849, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 766, 0, 1868, 0, 0, + 766, 0, 0, 0, 766, 766, 0, 0, 1927, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1137, 0, 1957, 0, 0, 0, 0, + 0, 0, 0, 1966, 0, 0, 0, 1968, 0, 0, + 1971, 1972, 1974, 1974, 0, 1974, 0, 1974, 1974, 0, + 1983, 1974, 1974, 1974, 1974, 1974, 0, 0, 0, 0, + 0, 0, 0, 0, 2003, 2004, 0, 1137, 0, 0, + 2009, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 947, 0, 0, 0, + 0, 0, 2051, 0, 0, 0, 0, 0, 0, 0, + 0, 766, 0, 0, 0, 0, 0, 0, 2072, 0, + 0, 0, 2077, 0, 767, 0, 767, 0, 203, 0, + 0, 0, 0, 0, 0, 203, 0, 0, 203, 203, + 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1578, 0, 201, 0, 203, + 709, 0, 767, 0, 767, 0, 0, 1322, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 709, 0, 0, 0, 0, 1577, 0, 766, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1086, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1112, 1112, 0, 0, 0, + 767, 0, 0, 0, 709, 0, 0, 0, 0, 0, + 0, 0, 0, 203, 0, 0, 767, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 767, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 767, 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 766, 766, 766, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2686, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 767, 0, 0, 0, 0, 0, 0, + 767, 0, 767, 0, 0, 0, 0, 0, 0, 0, + 0, 767, 0, 0, 0, 0, 0, 0, 0, 1322, + 1322, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2134, 0, 0, 0, 0, 0, + 0, 0, 767, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3017, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1321, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 766, 0, 0, 0, + 0, 0, 0, 0, 0, 2196, 0, 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 766, 766, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 766, 0, 0, - 0, 0, 0, 0, 766, 0, 0, 0, 766, 766, - 0, 0, 0, 766, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1576, - 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3024, 0, 0, 0, 0, + 0, 0, 767, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 767, 203, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 766, 0, 0, 0, 0, 0, 0, 766, 0, 1322, + 0, 766, 766, 0, 0, 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 767, 1577, 766, 0, 0, 0, 0, 0, 0, + 0, 767, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1578, 767, 0, 767, 0, 2443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2934, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2950, 2951, 2952, 0, 0, 0, + 0, 767, 2406, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2460, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2967, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 767, 767, 0, 766, 0, 0, 0, 1849, 0, + 0, 1322, 203, 767, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 767, 0, 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 709, 0, 709, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 766, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3050, 0, 0, 0, 0, 0, 0, 0, 0, 766, - 0, 0, 0, 0, 0, 709, 0, 0, 0, 0, - 0, 1147, 0, 0, 0, 0, 0, 0, 3070, 0, - 0, 0, 1963, 1963, 0, 0, 0, 3075, 0, 0, - 0, 0, 0, 1578, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3086, 0, 0, 0, 0, 766, - 0, 0, 0, 1576, 0, 0, 766, 766, 1576, 0, + 1144, 0, 767, 0, 203, 0, 2586, 0, 0, 0, + 0, 0, 709, 0, 709, 0, 0, 0, 767, 0, + 0, 0, 1137, 0, 0, 0, 0, 0, 1144, 1966, + 0, 767, 1966, 0, 1966, 0, 0, 0, 0, 0, + 2615, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 767, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1137, 709, 0, 0, 766, + 2196, 0, 0, 0, 2196, 2196, 0, 0, 0, 0, + 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1579, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 766, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 767, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 766, 0, 0, 0, 0, 1577, 0, 0, + 766, 766, 1577, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3391, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2193, 0, 766, 0, 0, - 1576, 0, 0, 0, 0, 766, 0, 0, 0, 0, + 0, 2692, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2193, 0, 0, 0, 0, - 0, 0, 3462, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3399, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 766, 0, 0, 1577, 0, 0, 0, 0, 766, + 0, 0, 0, 0, 0, 0, 0, 1322, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3470, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 709, 0, 0, 0, - 3238, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 766, 0, 1321, 0, 0, 0, 0, 0, 0, 0, - 1086, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1971, 0, 0, 0, 0, 0, 0, - 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 709, + 0, 1086, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1321, 0, 0, 0, 0, 0, 0, - 3325, 1971, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1578, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 709, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 766, 0, 0, 0, 0, 0, + 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3677, 0, 1578, 0, - 0, 1578, 0, 1578, 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2022, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 766, 766, 0, 0, 709, - 0, 1136, 0, 0, 0, 0, 0, 0, 0, 1147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2076, 709, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 709, 766, 766, - 766, 766, 0, 0, 709, 0, 0, 0, 0, 0, - 0, 0, 0, 2102, 2103, 709, 709, 709, 709, 709, - 709, 709, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1579, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1579, 0, 0, 1579, 0, 1579, 709, 0, 2940, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2956, 2957, 2958, 0, 0, 2025, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2973, 0, 0, + 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3685, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2079, 709, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 709, + 0, 0, 0, 0, 0, 0, 709, 0, 0, 0, + 766, 766, 0, 0, 0, 2105, 2106, 709, 709, 709, + 709, 709, 709, 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 766, 766, 766, 766, 0, 0, 3057, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1148, 0, 0, 0, 0, 0, 0, 3077, 0, 0, + 0, 1966, 1966, 0, 0, 0, 3082, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3093, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1924, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 766, 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1576, 0, 0, 0, - 0, 0, 0, 766, 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 766, 0, 766, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 766, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 766, - 1578, 0, 0, 0, 0, 0, 0, 0, 0, 1147, - 1147, 0, 0, 0, 0, 0, 0, 0, 1578, 0, + 0, 1577, 0, 0, 2196, 0, 0, 0, 766, 0, + 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1579, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3738, 3739, 3740, 3741, 0, 0, 0, 0, + 1579, 0, 0, 0, 0, 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 766, 0, 0, 0, 0, 0, - 0, 766, 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 766, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3245, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 766, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2076, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2022, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1112, 0, 0, 0, 3816, - 0, 3816, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1322, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1086, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3855, 0, 3857, - 0, 0, 0, 766, 0, 0, 0, 0, 709, 0, - 0, 0, 0, 0, 0, 2076, 709, 0, 709, 0, - 709, 2507, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1147, 0, 0, 0, 0, + 0, 0, 1974, 0, 0, 0, 0, 0, 0, 766, + 0, 0, 0, 0, 0, 0, 766, 0, 766, 0, + 0, 0, 0, 0, 0, 0, 0, 766, 0, 0, + 0, 0, 0, 0, 0, 0, 2079, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4023, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1321, 0, 0, 0, 0, 0, 0, + 0, 0, 1322, 0, 0, 0, 0, 0, 766, 0, + 3333, 1974, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 766, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 766, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1576, 766, 0, 766, 0, + 0, 2025, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 766, 766, 0, 0, 0, 0, 3816, 0, - 0, 0, 0, 0, 0, 3816, 0, 3816, 0, 0, - 0, 0, 0, 0, 0, 0, 4114, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1086, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 766, 766, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 766, 0, 0, 1147, 0, 0, - 0, 0, 0, 0, 0, 709, 0, 0, 0, 0, - 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 709, 709, 0, 0, 709, 0, 2671, 709, - 0, 0, 766, 0, 0, 0, 0, 0, 0, 709, - 0, 0, 0, 0, 0, 0, 709, 0, 0, 0, + 0, 1137, 0, 0, 0, 0, 0, 0, 0, 1148, + 709, 709, 0, 0, 0, 0, 0, 0, 2079, 709, + 709, 0, 709, 0, 709, 2513, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 709, 766, 0, 0, 0, 0, 0, 2683, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 766, + 0, 0, 0, 0, 0, 0, 0, 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 766, 0, 0, 0, 1147, 0, 0, + 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1578, 0, - 2076, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4172, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4180, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 766, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 766, 0, 0, + 0, 0, 0, 0, 1927, 0, 0, 0, 0, 0, + 1577, 766, 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1147, 0, 4198, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 766, 766, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 709, + 0, 0, 0, 0, 0, 709, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 709, 709, 0, 0, + 709, 0, 2677, 709, 0, 0, 0, 766, 766, 0, + 0, 0, 0, 709, 0, 0, 0, 0, 0, 766, + 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1321, 1321, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3887, 3889, 3888, - 3954, 3955, 3956, 3957, 3958, 3959, 3960, 3890, 3891, 837, + 0, 0, 0, 0, 0, 0, 709, 0, 0, 0, + 0, 0, 0, 2689, 0, 0, 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4250, 4258, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 4263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 766, 0, + 1148, 1148, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 766, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 766, 0, 0, + 0, 0, 1579, 0, 2079, 0, 0, 0, 0, 0, + 0, 0, 0, 3746, 3747, 3748, 3749, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4180, 0, 0, 0, - 0, 0, 709, 0, 0, 0, 0, 0, 0, 0, - 2022, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2953, 1147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1924, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4263, 0, 0, 0, - 0, 0, 0, 0, 709, 0, 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 4258, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4258, 0, 0, 0, 3895, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3903, - 3904, 0, 0, 3979, 3978, 3977, 0, 0, 3975, 3976, - 3974, 0, 1578, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 709, 709, 709, 709, 709, 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 709, 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3980, 960, 709, 813, - 814, 3981, 3982, 964, 3983, 816, 817, 961, 962, 0, - 811, 815, 963, 965, 0, 0, 0, 0, 0, 0, + 3824, 0, 3824, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3884, - 3885, 3886, 3892, 3893, 3894, 3905, 3952, 3953, 3961, 3963, - 916, 3962, 3964, 3965, 3966, 3969, 3970, 3971, 3972, 3967, - 3968, 3973, 3867, 3871, 3868, 3869, 3870, 3882, 3872, 3873, - 3874, 3875, 3876, 3877, 3878, 3879, 3880, 3881, 3883, 3984, - 3985, 3986, 3987, 3988, 3989, 3898, 3902, 3901, 3899, 3900, - 3896, 3897, 3924, 3923, 3925, 3926, 3927, 3928, 3929, 3930, - 3932, 3931, 3933, 3934, 3935, 3936, 3937, 3938, 3906, 3907, - 3910, 3911, 3909, 3908, 3912, 3921, 3922, 3913, 3914, 3915, - 3916, 3917, 3918, 3920, 3919, 3939, 3940, 3941, 3942, 3943, - 3945, 3944, 3948, 3949, 3947, 3946, 3951, 3950, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3863, 0, + 3865, 0, 0, 0, 0, 0, 709, 0, 0, 0, + 0, 0, 0, 0, 2025, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 966, 0, 967, 0, 0, 971, 0, 0, 0, - 973, 972, 0, 974, 936, 935, 0, 0, 968, 969, - 0, 970, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2959, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4031, 0, 0, 0, 0, 0, 0, 0, + 0, 709, 0, 0, 1322, 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1112, 0, 709, 709, 709, - 0, 709, 0, 0, 0, 0, 0, 3990, 3991, 3992, - 3993, 3994, 3995, 3996, 3997, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1578, 0, 0, 0, - 0, 1578, 709, 709, 709, 709, 709, 0, 0, 0, - 0, 0, 0, 0, 3341, 0, 0, 0, 0, 0, - 2022, 0, 709, 0, 0, 709, 3349, 2076, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3824, + 0, 0, 0, 0, 0, 0, 3824, 0, 3824, 0, + 0, 0, 0, 0, 0, 0, 0, 4122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1148, 1579, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1578, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 709, 0, 0, + 709, 709, 709, 709, 709, 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 709, 0, 0, 709, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 709, + 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4180, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 709, 709, 0, 0, + 0, 1148, 0, 4206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1322, 1322, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1112, 0, 709, 709, 709, 0, 709, 0, + 0, 0, 0, 0, 0, 0, 0, 4258, 4266, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4271, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1579, 0, 0, 0, 0, 1579, + 709, 709, 709, 709, 709, 0, 0, 0, 0, 0, + 0, 0, 3349, 0, 0, 0, 0, 4188, 2025, 0, + 709, 0, 0, 709, 3357, 2079, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3895, 3897, + 3896, 3962, 3963, 3964, 3965, 3966, 3967, 3968, 3898, 3899, + 837, 0, 0, 0, 0, 0, 0, 0, 1148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1927, 0, 0, 0, 0, 0, + 0, 1579, 0, 0, 0, 0, 0, 4271, 0, 0, 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 709, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 4266, 0, + 709, 0, 0, 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4266, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3141,30 +3094,52 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 709, 0, + 0, 0, 0, 0, 0, 3903, 0, 0, 0, 0, + 0, 0, 0, 0, 709, 709, 0, 0, 0, 0, + 3911, 3912, 0, 0, 3987, 3986, 3985, 0, 0, 3983, + 3984, 3982, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 709, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3988, 960, 709, + 813, 814, 3989, 3990, 964, 3991, 816, 817, 961, 962, + 0, 811, 815, 963, 965, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3892, 3893, 3894, 3900, 3901, 3902, 3913, 3960, 3961, 3969, + 3971, 916, 3970, 3972, 3973, 3974, 3977, 3978, 3979, 3980, + 3975, 3976, 3981, 3875, 3879, 3876, 3877, 3878, 3890, 3880, + 3881, 3882, 3883, 3884, 3885, 3886, 3887, 3888, 3889, 3891, + 3992, 3993, 3994, 3995, 3996, 3997, 3906, 3910, 3909, 3907, + 3908, 3904, 3905, 3932, 3931, 3933, 3934, 3935, 3936, 3937, + 3938, 3940, 3939, 3941, 3942, 3943, 3944, 3945, 3946, 3914, + 3915, 3918, 3919, 3917, 3916, 3920, 3929, 3930, 3921, 3922, + 3923, 3924, 3925, 3926, 3928, 3927, 3947, 3948, 3949, 3950, + 3951, 3953, 3952, 3956, 3957, 3955, 3954, 3959, 3958, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 966, 0, 967, 0, 0, 971, 0, 0, + 0, 973, 972, 0, 974, 936, 935, 0, 0, 968, + 969, 0, 970, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2022, 0, 0, 0, 0, 0, 0, 709, - 0, 0, 709, 709, 709, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1578, - 0, 0, 0, 2022, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2025, 0, 0, 0, 0, 0, 0, 709, 0, + 0, 709, 709, 709, 0, 0, 0, 0, 3998, 3999, + 4000, 4001, 4002, 4003, 4004, 4005, 0, 0, 1579, 0, + 0, 0, 2025, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2022, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2025, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3183,114 +3158,349 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1471, 1450, 557, - 0, 1391, 1474, 1356, 1377, 1484, 1380, 1383, 1428, 1331, - 1406, 438, 1374, 1360, 1326, 1368, 1327, 1358, 1393, 286, - 1355, 1452, 1410, 1473, 385, 283, 1333, 1324, 212, 530, - 1361, 453, 1379, 211, 1431, 511, 268, 396, 393, 615, - 298, 289, 285, 264, 336, 405, 450, 547, 444, 1480, - 389, 1416, 0, 522, 422, 0, 0, 0, 1457, 1456, - 1384, 1395, 1462, 1404, 1443, 1389, 1430, 1343, 1415, 1475, - 1375, 1425, 1476, 342, 262, 344, 210, 435, 523, 302, - 0, 2022, 0, 0, 4220, 536, 991, 0, 0, 0, - 0, 4221, 0, 0, 0, 0, 249, 0, 0, 256, - 709, 0, 0, 370, 379, 378, 358, 359, 361, 363, - 369, 376, 382, 355, 364, 1371, 1422, 641, 1469, 1372, - 1424, 281, 340, 288, 280, 612, 1481, 1461, 1330, 1403, - 1468, 1398, 628, 0, 0, 238, 1472, 1397, 0, 1427, - 0, 1487, 1325, 1418, 0, 1328, 1332, 1483, 1466, 1364, - 1365, 291, 0, 0, 0, 0, 0, 0, 0, 1394, - 1405, 1440, 1444, 1387, 0, 416, 0, 0, 0, 0, - 0, 0, 0, 1362, 0, 1414, 0, 0, 0, 1337, - 1329, 0, 0, 0, 0, 0, 0, 0, 1578, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4218, 0, 0, 0, - 0, 0, 0, 1392, 0, 0, 0, 0, 1342, 0, - 1363, 1441, 0, 1323, 313, 1334, 423, 273, 0, 477, - 1354, 319, 334, 1340, 1369, 1470, 1458, 1459, 1460, 1339, - 1448, 1465, 1388, 661, 1467, 1386, 1385, 1435, 1338, 1455, - 1378, 384, 1336, 349, 205, 233, 2022, 1376, 434, 485, - 497, 1454, 1453, 1359, 1370, 269, 1367, 495, 448, 636, - 243, 300, 482, 455, 493, 463, 303, 1413, 1433, 494, - 391, 617, 473, 633, 662, 663, 279, 428, 647, 551, - 655, 680, 234, 276, 442, 535, 639, 519, 417, 613, - 614, 348, 518, 311, 209, 388, 668, 232, 503, 390, - 253, 241, 619, 644, 315, 267, 305, 480, 675, 221, - 546, 630, 250, 507, 0, 0, 683, 258, 529, 642, - 631, 223, 626, 528, 413, 345, 346, 222, 2076, 481, - 284, 309, 0, 0, 274, 437, 621, 622, 272, 684, - 237, 654, 228, 1335, 653, 430, 616, 627, 414, 402, - 227, 625, 412, 401, 353, 374, 375, 296, 324, 470, - 394, 471, 323, 325, 425, 424, 426, 215, 640, 658, - 0, 216, 0, 524, 643, 685, 475, 220, 244, 245, - 248, 1353, 295, 299, 307, 310, 320, 321, 331, 386, - 441, 469, 465, 474, 1449, 610, 634, 648, 660, 666, - 667, 669, 670, 671, 672, 673, 676, 674, 429, 329, - 520, 352, 392, 1438, 1486, 447, 496, 251, 638, 521, - 240, 604, 418, 427, 259, 261, 260, 235, 512, 609, - 246, 266, 207, 1347, 1352, 1345, 0, 270, 271, 1419, - 605, 1348, 1346, 1408, 1409, 1349, 1477, 1478, 1479, 1463, - 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, - 696, 697, 698, 699, 700, 701, 702, 703, 681, 537, - 543, 538, 539, 540, 541, 542, 0, 544, 1442, 1341, - 0, 1350, 1351, 419, 1451, 623, 624, 704, 403, 510, - 635, 354, 368, 371, 360, 380, 0, 381, 356, 357, - 362, 365, 366, 367, 372, 373, 377, 383, 263, 218, - 410, 420, 608, 330, 224, 225, 226, 553, 554, 555, - 556, 651, 652, 656, 213, 486, 487, 488, 489, 308, - 646, 326, 492, 491, 350, 351, 398, 472, 569, 571, - 582, 586, 588, 590, 596, 599, 570, 572, 583, 587, - 589, 591, 597, 600, 559, 561, 563, 565, 578, 577, - 574, 602, 603, 580, 585, 564, 576, 581, 594, 601, - 598, 558, 562, 566, 575, 593, 592, 573, 584, 595, - 579, 567, 560, 568, 1412, 204, 229, 387, 1482, 478, - 304, 682, 650, 508, 645, 214, 231, 1344, 278, 1357, - 1366, 0, 1373, 1381, 1382, 1396, 1399, 1400, 1401, 1402, - 1420, 1421, 1423, 1432, 1434, 1437, 1439, 1446, 1464, 1485, - 206, 208, 217, 230, 242, 247, 254, 277, 292, 294, - 301, 314, 327, 328, 337, 338, 341, 347, 399, 406, - 407, 408, 409, 431, 432, 433, 436, 439, 440, 443, - 445, 446, 449, 454, 458, 459, 460, 462, 464, 466, - 479, 484, 498, 499, 500, 501, 502, 505, 506, 513, - 514, 515, 516, 517, 525, 526, 531, 532, 533, 534, - 545, 618, 620, 637, 657, 664, 504, 404, 452, 476, - 611, 1429, 1390, 317, 318, 467, 468, 332, 333, 678, - 679, 316, 632, 665, 629, 677, 659, 461, 397, 1411, - 1417, 400, 297, 322, 339, 1426, 649, 527, 236, 490, - 306, 265, 1445, 1447, 219, 257, 239, 275, 290, 293, - 343, 411, 421, 451, 457, 312, 287, 255, 483, 252, - 509, 548, 549, 550, 552, 415, 282, 456, 1407, 1436, - 395, 606, 607, 335, 1471, 1450, 557, 0, 1391, 1474, - 1356, 1377, 1484, 1380, 1383, 1428, 1331, 1406, 438, 1374, - 1360, 1326, 1368, 1327, 1358, 1393, 286, 1355, 1452, 1410, - 1473, 385, 283, 1333, 1324, 212, 530, 1361, 453, 1379, - 211, 1431, 511, 268, 396, 393, 615, 298, 289, 285, - 264, 336, 405, 450, 547, 444, 1480, 389, 1416, 0, - 522, 422, 0, 0, 0, 1457, 1456, 1384, 1395, 1462, - 1404, 1443, 1389, 1430, 1343, 1415, 1475, 1375, 1425, 1476, - 342, 262, 344, 210, 435, 523, 302, 0, 0, 0, - 0, 0, 536, 202, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1472, 1451, 557, 0, + 1392, 1475, 1357, 1378, 1485, 1381, 1384, 1429, 1332, 1407, + 438, 1375, 1361, 1327, 1369, 1328, 1359, 1394, 286, 1356, + 1453, 1411, 1474, 385, 283, 1334, 1325, 212, 530, 1362, + 453, 1380, 211, 1432, 511, 268, 396, 393, 615, 298, + 289, 285, 264, 336, 405, 450, 547, 444, 1481, 389, + 1417, 0, 522, 422, 0, 0, 0, 1458, 1457, 1385, + 1396, 1463, 1405, 1444, 1390, 1431, 1344, 1416, 1476, 1376, + 1426, 1477, 342, 262, 344, 210, 435, 523, 302, 0, + 2025, 0, 0, 4228, 536, 991, 0, 0, 0, 0, + 4229, 0, 0, 0, 0, 249, 0, 0, 256, 709, + 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, + 376, 382, 355, 364, 1372, 1423, 641, 1470, 1373, 1425, + 281, 340, 288, 280, 612, 1482, 1462, 1331, 1404, 1469, + 1399, 628, 0, 0, 238, 1473, 1398, 0, 1428, 0, + 1488, 1326, 1419, 0, 1329, 1333, 1484, 1467, 1365, 1366, + 291, 0, 0, 0, 0, 0, 0, 0, 1395, 1406, + 1441, 1445, 1388, 0, 416, 0, 0, 0, 0, 0, + 0, 0, 1363, 0, 1415, 0, 0, 0, 1338, 1330, + 0, 0, 0, 0, 0, 0, 0, 1579, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4226, 0, 0, 0, 0, + 0, 0, 1393, 0, 0, 0, 0, 1343, 0, 1364, + 1442, 0, 1324, 313, 1335, 423, 273, 0, 477, 1355, + 319, 334, 1341, 1370, 1471, 1459, 1460, 1461, 1340, 1449, + 1466, 1389, 661, 1468, 1387, 1386, 1436, 1339, 1456, 1379, + 384, 1337, 349, 205, 233, 2025, 1377, 434, 485, 497, + 1455, 1454, 1360, 1371, 269, 1368, 495, 448, 636, 243, + 300, 482, 455, 493, 463, 303, 1414, 1434, 494, 391, + 617, 473, 633, 662, 663, 279, 428, 647, 551, 655, + 680, 234, 276, 442, 535, 639, 519, 417, 613, 614, + 348, 518, 311, 209, 388, 668, 232, 503, 390, 253, + 241, 619, 644, 315, 267, 305, 480, 675, 221, 546, + 630, 250, 507, 0, 0, 683, 258, 529, 642, 631, + 223, 626, 528, 413, 345, 346, 222, 2079, 481, 284, + 309, 0, 0, 274, 437, 621, 622, 272, 684, 237, + 654, 228, 1336, 653, 430, 616, 627, 414, 402, 227, + 625, 412, 401, 353, 374, 375, 296, 324, 470, 394, + 471, 323, 325, 425, 424, 426, 215, 640, 658, 0, + 216, 0, 524, 643, 685, 475, 220, 244, 245, 248, + 1354, 295, 299, 307, 310, 320, 321, 331, 386, 441, + 469, 465, 474, 1450, 610, 634, 648, 660, 666, 667, + 669, 670, 671, 672, 673, 676, 674, 429, 329, 520, + 352, 392, 1439, 1487, 447, 496, 251, 638, 521, 240, + 604, 418, 427, 259, 261, 260, 235, 512, 609, 246, + 266, 207, 1348, 1353, 1346, 0, 270, 271, 1420, 605, + 1349, 1347, 1409, 1410, 1350, 1478, 1479, 1480, 1464, 686, + 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, + 697, 698, 699, 700, 701, 702, 703, 681, 537, 543, + 538, 539, 540, 541, 542, 0, 544, 1443, 1342, 0, + 1351, 1352, 419, 1452, 623, 624, 704, 403, 510, 635, + 354, 368, 371, 360, 380, 0, 381, 356, 357, 362, + 365, 366, 367, 372, 373, 377, 383, 263, 218, 410, + 420, 608, 330, 224, 225, 226, 553, 554, 555, 556, + 651, 652, 656, 213, 486, 487, 488, 489, 308, 646, + 326, 492, 491, 350, 351, 398, 472, 569, 571, 582, + 586, 588, 590, 596, 599, 570, 572, 583, 587, 589, + 591, 597, 600, 559, 561, 563, 565, 578, 577, 574, + 602, 603, 580, 585, 564, 576, 581, 594, 601, 598, + 558, 562, 566, 575, 593, 592, 573, 584, 595, 579, + 567, 560, 568, 1413, 204, 229, 387, 1483, 478, 304, + 682, 650, 508, 645, 214, 231, 1345, 278, 1358, 1367, + 0, 1374, 1382, 1383, 1397, 1400, 1401, 1402, 1403, 1421, + 1422, 1424, 1433, 1435, 1438, 1440, 1447, 1465, 1486, 206, + 208, 217, 230, 242, 247, 254, 277, 292, 294, 301, + 314, 327, 328, 337, 338, 341, 347, 399, 406, 407, + 408, 409, 431, 432, 433, 436, 439, 440, 443, 445, + 446, 449, 454, 458, 459, 460, 462, 464, 466, 479, + 484, 498, 499, 500, 501, 502, 505, 506, 513, 514, + 515, 516, 517, 525, 526, 531, 532, 533, 534, 545, + 618, 620, 637, 657, 664, 504, 404, 452, 476, 611, + 1430, 1391, 317, 318, 467, 468, 332, 333, 678, 679, + 316, 632, 665, 629, 677, 659, 461, 397, 1412, 1418, + 400, 297, 322, 339, 1427, 649, 527, 236, 490, 306, + 265, 1446, 1448, 219, 257, 239, 275, 290, 293, 343, + 411, 421, 451, 457, 312, 287, 255, 483, 252, 509, + 548, 549, 550, 552, 415, 282, 456, 1408, 1437, 395, + 606, 607, 335, 1472, 1451, 557, 0, 1392, 1475, 1357, + 1378, 1485, 1381, 1384, 1429, 1332, 1407, 438, 1375, 1361, + 1327, 1369, 1328, 1359, 1394, 286, 1356, 1453, 1411, 1474, + 385, 283, 1334, 1325, 212, 530, 1362, 453, 1380, 211, + 1432, 511, 268, 396, 393, 615, 298, 289, 285, 264, + 336, 405, 450, 547, 444, 1481, 389, 1417, 0, 522, + 422, 0, 0, 0, 1458, 1457, 1385, 1396, 1463, 1405, + 1444, 1390, 1431, 1344, 1416, 1476, 1376, 1426, 1477, 342, + 262, 344, 210, 435, 523, 302, 0, 0, 0, 0, + 0, 536, 202, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, + 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, + 364, 1372, 1423, 641, 1470, 1373, 1425, 281, 340, 288, + 280, 612, 1482, 1462, 1331, 1404, 1469, 1399, 628, 0, + 0, 238, 1473, 1398, 0, 1428, 0, 1488, 1326, 1419, + 0, 1329, 1333, 1484, 1467, 1365, 1366, 291, 0, 0, + 0, 0, 0, 0, 0, 1395, 1406, 1441, 1445, 1388, + 0, 416, 0, 0, 0, 0, 0, 3358, 0, 1363, + 0, 1415, 0, 0, 0, 1338, 1330, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1393, + 0, 0, 0, 0, 1343, 0, 1364, 1442, 0, 1324, + 313, 1335, 423, 273, 0, 477, 1355, 319, 334, 1341, + 1370, 1471, 1459, 1460, 1461, 1340, 1449, 1466, 1389, 661, + 1468, 1387, 1386, 1436, 1339, 1456, 1379, 384, 1337, 349, + 205, 233, 0, 1377, 434, 485, 497, 1455, 1454, 1360, + 1371, 269, 1368, 495, 448, 636, 243, 300, 482, 455, + 493, 463, 303, 1414, 1434, 494, 391, 617, 473, 633, + 662, 663, 279, 428, 647, 551, 655, 680, 234, 276, + 442, 535, 639, 519, 417, 613, 614, 348, 518, 311, + 209, 388, 668, 232, 503, 390, 253, 241, 619, 644, + 315, 267, 305, 480, 675, 221, 546, 630, 250, 507, + 0, 0, 683, 258, 529, 642, 631, 223, 626, 528, + 413, 345, 346, 222, 0, 481, 284, 309, 0, 0, + 274, 437, 621, 622, 272, 684, 237, 654, 228, 1336, + 653, 430, 616, 627, 414, 402, 227, 625, 412, 401, + 353, 374, 375, 296, 324, 470, 394, 471, 323, 325, + 425, 424, 426, 215, 640, 658, 0, 216, 0, 524, + 643, 685, 475, 220, 244, 245, 248, 1354, 295, 299, + 307, 310, 320, 321, 331, 386, 441, 469, 465, 474, + 1450, 610, 634, 648, 660, 666, 667, 669, 670, 671, + 672, 673, 676, 674, 429, 329, 520, 352, 392, 1439, + 1487, 447, 496, 251, 638, 521, 240, 604, 418, 427, + 259, 261, 260, 235, 512, 609, 246, 266, 207, 1348, + 1353, 1346, 0, 270, 271, 1420, 605, 1349, 1347, 1409, + 1410, 1350, 1478, 1479, 1480, 1464, 686, 687, 688, 689, + 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, + 700, 701, 702, 703, 681, 537, 543, 538, 539, 540, + 541, 542, 0, 544, 1443, 1342, 0, 1351, 1352, 419, + 1452, 623, 624, 704, 403, 510, 635, 354, 368, 371, + 360, 380, 0, 381, 356, 357, 362, 365, 366, 367, + 372, 373, 377, 383, 263, 218, 410, 420, 608, 330, + 224, 225, 226, 553, 554, 555, 556, 651, 652, 656, + 213, 486, 487, 488, 489, 308, 646, 326, 492, 491, + 350, 351, 398, 472, 569, 571, 582, 586, 588, 590, + 596, 599, 570, 572, 583, 587, 589, 591, 597, 600, + 559, 561, 563, 565, 578, 577, 574, 602, 603, 580, + 585, 564, 576, 581, 594, 601, 598, 558, 562, 566, + 575, 593, 592, 573, 584, 595, 579, 567, 560, 568, + 1413, 204, 229, 387, 1483, 478, 304, 682, 650, 508, + 645, 214, 231, 1345, 278, 1358, 1367, 0, 1374, 1382, + 1383, 1397, 1400, 1401, 1402, 1403, 1421, 1422, 1424, 1433, + 1435, 1438, 1440, 1447, 1465, 1486, 206, 208, 217, 230, + 242, 247, 254, 277, 292, 294, 301, 314, 327, 328, + 337, 338, 341, 347, 399, 406, 407, 408, 409, 431, + 432, 433, 436, 439, 440, 443, 445, 446, 449, 454, + 458, 459, 460, 462, 464, 466, 479, 484, 498, 499, + 500, 501, 502, 505, 506, 513, 514, 515, 516, 517, + 525, 526, 531, 532, 533, 534, 545, 618, 620, 637, + 657, 664, 504, 404, 452, 476, 611, 1430, 1391, 317, + 318, 467, 468, 332, 333, 678, 679, 316, 632, 665, + 629, 677, 659, 461, 397, 1412, 1418, 400, 297, 322, + 339, 1427, 649, 527, 236, 490, 306, 265, 1446, 1448, + 219, 257, 239, 275, 290, 293, 343, 411, 421, 451, + 457, 312, 287, 255, 483, 252, 509, 548, 549, 550, + 552, 415, 282, 456, 1408, 1437, 395, 606, 607, 335, + 1472, 1451, 557, 0, 1392, 1475, 1357, 1378, 1485, 1381, + 1384, 1429, 1332, 1407, 438, 1375, 1361, 1327, 1369, 1328, + 1359, 1394, 286, 1356, 1453, 1411, 1474, 385, 283, 1334, + 1325, 212, 530, 1362, 453, 1380, 211, 1432, 511, 268, + 396, 393, 615, 298, 289, 285, 264, 336, 405, 450, + 547, 444, 1481, 389, 1417, 0, 522, 422, 0, 0, + 0, 1458, 1457, 1385, 1396, 1463, 1405, 1444, 1390, 1431, + 1344, 1416, 1476, 1376, 1426, 1477, 342, 262, 344, 210, + 435, 523, 302, 0, 0, 0, 0, 0, 536, 756, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, + 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, + 359, 361, 363, 369, 376, 382, 355, 364, 1372, 1423, + 641, 1470, 1373, 1425, 281, 340, 288, 280, 612, 1482, + 1462, 1331, 1404, 1469, 1399, 628, 0, 0, 238, 1473, + 1398, 0, 1428, 0, 1488, 1326, 1419, 0, 1329, 1333, + 1484, 1467, 1365, 1366, 291, 0, 0, 0, 0, 0, + 0, 0, 1395, 1406, 1441, 1445, 1388, 0, 416, 0, + 0, 0, 0, 0, 3318, 0, 1363, 0, 1415, 0, + 0, 0, 1338, 1330, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1393, 0, 0, 0, + 0, 1343, 0, 1364, 1442, 0, 1324, 313, 1335, 423, + 273, 0, 477, 1355, 319, 334, 1341, 1370, 1471, 1459, + 1460, 1461, 1340, 1449, 1466, 1389, 661, 1468, 1387, 1386, + 1436, 1339, 1456, 1379, 384, 1337, 349, 205, 233, 0, + 1377, 434, 485, 497, 1455, 1454, 1360, 1371, 269, 1368, + 495, 448, 636, 243, 300, 482, 455, 493, 463, 303, + 1414, 1434, 494, 391, 617, 473, 633, 662, 663, 279, + 428, 647, 551, 655, 680, 234, 276, 442, 535, 639, + 519, 417, 613, 614, 348, 518, 311, 209, 388, 668, + 232, 503, 390, 253, 241, 619, 644, 315, 267, 305, + 480, 675, 221, 546, 630, 250, 507, 0, 0, 683, + 258, 529, 642, 631, 223, 626, 528, 413, 345, 346, + 222, 0, 481, 284, 309, 0, 0, 274, 437, 621, + 622, 272, 684, 237, 654, 228, 1336, 653, 430, 616, + 627, 414, 402, 227, 625, 412, 401, 353, 374, 375, + 296, 324, 470, 394, 471, 323, 325, 425, 424, 426, + 215, 640, 658, 0, 216, 0, 524, 643, 685, 475, + 220, 244, 245, 248, 1354, 295, 299, 307, 310, 320, + 321, 331, 386, 441, 469, 465, 474, 1450, 610, 634, + 648, 660, 666, 667, 669, 670, 671, 672, 673, 676, + 674, 429, 329, 520, 352, 392, 1439, 1487, 447, 496, + 251, 638, 521, 240, 604, 418, 427, 259, 261, 260, + 235, 512, 609, 246, 266, 207, 1348, 1353, 1346, 0, + 270, 271, 1420, 605, 1349, 1347, 1409, 1410, 1350, 1478, + 1479, 1480, 1464, 686, 687, 688, 689, 690, 691, 692, + 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, + 703, 681, 537, 543, 538, 539, 540, 541, 542, 0, + 544, 1443, 1342, 0, 1351, 1352, 419, 1452, 623, 624, + 704, 403, 510, 635, 354, 368, 371, 360, 380, 0, + 381, 356, 357, 362, 365, 366, 367, 372, 373, 377, + 383, 263, 218, 410, 420, 608, 330, 224, 225, 226, + 553, 554, 555, 556, 651, 652, 656, 213, 486, 487, + 488, 489, 308, 646, 326, 492, 491, 350, 351, 398, + 472, 569, 571, 582, 586, 588, 590, 596, 599, 570, + 572, 583, 587, 589, 591, 597, 600, 559, 561, 563, + 565, 578, 577, 574, 602, 603, 580, 585, 564, 576, + 581, 594, 601, 598, 558, 562, 566, 575, 593, 592, + 573, 584, 595, 579, 567, 560, 568, 1413, 204, 229, + 387, 1483, 478, 304, 682, 650, 508, 645, 214, 231, + 1345, 278, 1358, 1367, 0, 1374, 1382, 1383, 1397, 1400, + 1401, 1402, 1403, 1421, 1422, 1424, 1433, 1435, 1438, 1440, + 1447, 1465, 1486, 206, 208, 217, 230, 242, 247, 254, + 277, 292, 294, 301, 314, 327, 328, 337, 338, 341, + 347, 399, 406, 407, 408, 409, 431, 432, 433, 436, + 439, 440, 443, 445, 446, 449, 454, 458, 459, 460, + 462, 464, 466, 479, 484, 498, 499, 500, 501, 502, + 505, 506, 513, 514, 515, 516, 517, 525, 526, 531, + 532, 533, 534, 545, 618, 620, 637, 657, 664, 504, + 404, 452, 476, 611, 1430, 1391, 317, 318, 467, 468, + 332, 333, 678, 679, 316, 632, 665, 629, 677, 659, + 461, 397, 1412, 1418, 400, 297, 322, 339, 1427, 649, + 527, 236, 490, 306, 265, 1446, 1448, 219, 257, 239, + 275, 290, 293, 343, 411, 421, 451, 457, 312, 287, + 255, 483, 252, 509, 548, 549, 550, 552, 415, 282, + 456, 1408, 1437, 395, 606, 607, 335, 1472, 1451, 557, + 0, 1392, 1475, 1357, 1378, 1485, 1381, 1384, 1429, 1332, + 1407, 438, 1375, 1361, 1327, 1369, 1328, 1359, 1394, 286, + 1356, 1453, 1411, 1474, 385, 283, 1334, 1325, 212, 530, + 1362, 453, 1380, 211, 1432, 511, 268, 396, 393, 615, + 298, 289, 285, 264, 336, 405, 450, 547, 444, 1481, + 389, 1417, 0, 522, 422, 0, 0, 0, 1458, 1457, + 1385, 1396, 1463, 1405, 1444, 1390, 1431, 1344, 1416, 1476, + 1376, 1426, 1477, 342, 262, 344, 210, 435, 523, 302, + 0, 0, 0, 0, 0, 536, 991, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, + 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, + 369, 376, 382, 355, 364, 1372, 1423, 641, 1470, 1373, + 1425, 281, 340, 288, 280, 612, 1482, 1462, 1331, 1404, + 1469, 1399, 628, 0, 0, 238, 1473, 1398, 0, 1428, + 0, 1488, 1326, 1419, 0, 1329, 1333, 1484, 1467, 1365, + 1366, 291, 0, 0, 0, 0, 0, 0, 0, 1395, + 1406, 1441, 1445, 1388, 0, 416, 0, 0, 0, 0, + 0, 2491, 0, 1363, 0, 1415, 0, 0, 0, 1338, + 1330, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1393, 0, 0, 0, 0, 1343, 0, + 1364, 1442, 0, 1324, 313, 1335, 423, 273, 0, 477, + 1355, 319, 334, 1341, 1370, 1471, 1459, 1460, 1461, 1340, + 1449, 1466, 1389, 661, 1468, 1387, 1386, 1436, 1339, 1456, + 1379, 384, 1337, 349, 205, 233, 0, 1377, 434, 485, + 497, 1455, 1454, 1360, 1371, 269, 1368, 495, 448, 636, + 243, 300, 482, 455, 493, 463, 303, 1414, 1434, 494, + 391, 617, 473, 633, 662, 663, 279, 428, 647, 551, + 655, 680, 234, 276, 442, 535, 639, 519, 417, 613, + 614, 348, 518, 311, 209, 388, 668, 232, 503, 390, + 253, 241, 619, 644, 315, 267, 305, 480, 675, 221, + 546, 630, 250, 507, 0, 0, 683, 258, 529, 642, + 631, 223, 626, 528, 413, 345, 346, 222, 0, 481, + 284, 309, 0, 0, 274, 437, 621, 622, 272, 684, + 237, 654, 228, 1336, 653, 430, 616, 627, 414, 402, + 227, 625, 412, 401, 353, 374, 375, 296, 324, 470, + 394, 471, 323, 325, 425, 424, 426, 215, 640, 658, + 0, 216, 0, 524, 643, 685, 475, 220, 244, 245, + 248, 1354, 295, 299, 307, 310, 320, 321, 331, 386, + 441, 469, 465, 474, 1450, 610, 634, 648, 660, 666, + 667, 669, 670, 671, 672, 673, 676, 674, 429, 329, + 520, 352, 392, 1439, 1487, 447, 496, 251, 638, 521, + 240, 604, 418, 427, 259, 261, 260, 235, 512, 609, + 246, 266, 207, 1348, 1353, 1346, 0, 270, 271, 1420, + 605, 1349, 1347, 1409, 1410, 1350, 1478, 1479, 1480, 1464, + 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, + 696, 697, 698, 699, 700, 701, 702, 703, 681, 537, + 543, 538, 539, 540, 541, 542, 0, 544, 1443, 1342, + 0, 1351, 1352, 419, 1452, 623, 624, 704, 403, 510, + 635, 354, 368, 371, 360, 380, 0, 381, 356, 357, + 362, 365, 366, 367, 372, 373, 377, 383, 263, 218, + 410, 420, 608, 330, 224, 225, 226, 553, 554, 555, + 556, 651, 652, 656, 213, 486, 487, 488, 489, 308, + 646, 326, 492, 491, 350, 351, 398, 472, 569, 571, + 582, 586, 588, 590, 596, 599, 570, 572, 583, 587, + 589, 591, 597, 600, 559, 561, 563, 565, 578, 577, + 574, 602, 603, 580, 585, 564, 576, 581, 594, 601, + 598, 558, 562, 566, 575, 593, 592, 573, 584, 595, + 579, 567, 560, 568, 1413, 204, 229, 387, 1483, 478, + 304, 682, 650, 508, 645, 214, 231, 1345, 278, 1358, + 1367, 0, 1374, 1382, 1383, 1397, 1400, 1401, 1402, 1403, + 1421, 1422, 1424, 1433, 1435, 1438, 1440, 1447, 1465, 1486, + 206, 208, 217, 230, 242, 247, 254, 277, 292, 294, + 301, 314, 327, 328, 337, 338, 341, 347, 399, 406, + 407, 408, 409, 431, 432, 433, 436, 439, 440, 443, + 445, 446, 449, 454, 458, 459, 460, 462, 464, 466, + 479, 484, 498, 499, 500, 501, 502, 505, 506, 513, + 514, 515, 516, 517, 525, 526, 531, 532, 533, 534, + 545, 618, 620, 637, 657, 664, 504, 404, 452, 476, + 611, 1430, 1391, 317, 318, 467, 468, 332, 333, 678, + 679, 316, 632, 665, 629, 677, 659, 461, 397, 1412, + 1418, 400, 297, 322, 339, 1427, 649, 527, 236, 490, + 306, 265, 1446, 1448, 219, 257, 239, 275, 290, 293, + 343, 411, 421, 451, 457, 312, 287, 255, 483, 252, + 509, 548, 549, 550, 552, 415, 282, 456, 1408, 1437, + 395, 606, 607, 335, 1472, 1451, 557, 0, 1392, 1475, + 1357, 1378, 1485, 1381, 1384, 1429, 1332, 1407, 438, 1375, + 1361, 1327, 1369, 1328, 1359, 1394, 286, 1356, 1453, 1411, + 1474, 385, 283, 1334, 1325, 212, 530, 1362, 453, 1380, + 211, 1432, 511, 268, 396, 393, 615, 298, 289, 285, + 264, 336, 405, 450, 547, 444, 1481, 389, 1417, 0, + 522, 422, 0, 0, 0, 1458, 1457, 1385, 1396, 1463, + 1405, 1444, 1390, 1431, 1344, 1416, 1476, 1376, 1426, 1477, + 342, 262, 344, 210, 435, 523, 302, 0, 101, 0, + 0, 0, 536, 756, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, - 355, 364, 1371, 1422, 641, 1469, 1372, 1424, 281, 340, - 288, 280, 612, 1481, 1461, 1330, 1403, 1468, 1398, 628, - 0, 0, 238, 1472, 1397, 0, 1427, 0, 1487, 1325, - 1418, 0, 1328, 1332, 1483, 1466, 1364, 1365, 291, 0, - 0, 0, 0, 0, 0, 0, 1394, 1405, 1440, 1444, - 1387, 0, 416, 0, 0, 0, 0, 0, 3350, 0, - 1362, 0, 1414, 0, 0, 0, 1337, 1329, 0, 0, + 355, 364, 1372, 1423, 641, 1470, 1373, 1425, 281, 340, + 288, 280, 612, 1482, 1462, 1331, 1404, 1469, 1399, 628, + 0, 0, 238, 1473, 1398, 0, 1428, 0, 1488, 1326, + 1419, 0, 1329, 1333, 1484, 1467, 1365, 1366, 291, 0, + 0, 0, 0, 0, 0, 0, 1395, 1406, 1441, 1445, + 1388, 0, 416, 0, 0, 0, 0, 0, 0, 0, + 1363, 0, 1415, 0, 0, 0, 1338, 1330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1392, 0, 0, 0, 0, 1342, 0, 1363, 1441, 0, - 1323, 313, 1334, 423, 273, 0, 477, 1354, 319, 334, - 1340, 1369, 1470, 1458, 1459, 1460, 1339, 1448, 1465, 1388, - 661, 1467, 1386, 1385, 1435, 1338, 1455, 1378, 384, 1336, - 349, 205, 233, 0, 1376, 434, 485, 497, 1454, 1453, - 1359, 1370, 269, 1367, 495, 448, 636, 243, 300, 482, - 455, 493, 463, 303, 1413, 1433, 494, 391, 617, 473, + 1393, 0, 0, 0, 0, 1343, 0, 1364, 1442, 0, + 1324, 313, 1335, 423, 273, 0, 477, 1355, 319, 334, + 1341, 1370, 1471, 1459, 1460, 1461, 1340, 1449, 1466, 1389, + 661, 1468, 1387, 1386, 1436, 1339, 1456, 1379, 384, 1337, + 349, 205, 233, 0, 1377, 434, 485, 497, 1455, 1454, + 1360, 1371, 269, 1368, 495, 448, 636, 243, 300, 482, + 455, 493, 463, 303, 1414, 1434, 494, 391, 617, 473, 633, 662, 663, 279, 428, 647, 551, 655, 680, 234, 276, 442, 535, 639, 519, 417, 613, 614, 348, 518, 311, 209, 388, 668, 232, 503, 390, 253, 241, 619, @@ -3298,21 +3508,21 @@ var yyAct = [...]int{ 507, 0, 0, 683, 258, 529, 642, 631, 223, 626, 528, 413, 345, 346, 222, 0, 481, 284, 309, 0, 0, 274, 437, 621, 622, 272, 684, 237, 654, 228, - 1335, 653, 430, 616, 627, 414, 402, 227, 625, 412, + 1336, 653, 430, 616, 627, 414, 402, 227, 625, 412, 401, 353, 374, 375, 296, 324, 470, 394, 471, 323, 325, 425, 424, 426, 215, 640, 658, 0, 216, 0, - 524, 643, 685, 475, 220, 244, 245, 248, 1353, 295, + 524, 643, 685, 475, 220, 244, 245, 248, 1354, 295, 299, 307, 310, 320, 321, 331, 386, 441, 469, 465, - 474, 1449, 610, 634, 648, 660, 666, 667, 669, 670, + 474, 1450, 610, 634, 648, 660, 666, 667, 669, 670, 671, 672, 673, 676, 674, 429, 329, 520, 352, 392, - 1438, 1486, 447, 496, 251, 638, 521, 240, 604, 418, + 1439, 1487, 447, 496, 251, 638, 521, 240, 604, 418, 427, 259, 261, 260, 235, 512, 609, 246, 266, 207, - 1347, 1352, 1345, 0, 270, 271, 1419, 605, 1348, 1346, - 1408, 1409, 1349, 1477, 1478, 1479, 1463, 686, 687, 688, + 1348, 1353, 1346, 0, 270, 271, 1420, 605, 1349, 1347, + 1409, 1410, 1350, 1478, 1479, 1480, 1464, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 681, 537, 543, 538, 539, - 540, 541, 542, 0, 544, 1442, 1341, 0, 1350, 1351, - 419, 1451, 623, 624, 704, 403, 510, 635, 354, 368, + 540, 541, 542, 0, 544, 1443, 1342, 0, 1351, 1352, + 419, 1452, 623, 624, 704, 403, 510, 635, 354, 368, 371, 360, 380, 0, 381, 356, 357, 362, 365, 366, 367, 372, 373, 377, 383, 263, 218, 410, 420, 608, 330, 224, 225, 226, 553, 554, 555, 556, 651, 652, @@ -3322,74 +3532,74 @@ var yyAct = [...]int{ 600, 559, 561, 563, 565, 578, 577, 574, 602, 603, 580, 585, 564, 576, 581, 594, 601, 598, 558, 562, 566, 575, 593, 592, 573, 584, 595, 579, 567, 560, - 568, 1412, 204, 229, 387, 1482, 478, 304, 682, 650, - 508, 645, 214, 231, 1344, 278, 1357, 1366, 0, 1373, - 1381, 1382, 1396, 1399, 1400, 1401, 1402, 1420, 1421, 1423, - 1432, 1434, 1437, 1439, 1446, 1464, 1485, 206, 208, 217, + 568, 1413, 204, 229, 387, 1483, 478, 304, 682, 650, + 508, 645, 214, 231, 1345, 278, 1358, 1367, 0, 1374, + 1382, 1383, 1397, 1400, 1401, 1402, 1403, 1421, 1422, 1424, + 1433, 1435, 1438, 1440, 1447, 1465, 1486, 206, 208, 217, 230, 242, 247, 254, 277, 292, 294, 301, 314, 327, 328, 337, 338, 341, 347, 399, 406, 407, 408, 409, 431, 432, 433, 436, 439, 440, 443, 445, 446, 449, 454, 458, 459, 460, 462, 464, 466, 479, 484, 498, 499, 500, 501, 502, 505, 506, 513, 514, 515, 516, 517, 525, 526, 531, 532, 533, 534, 545, 618, 620, - 637, 657, 664, 504, 404, 452, 476, 611, 1429, 1390, + 637, 657, 664, 504, 404, 452, 476, 611, 1430, 1391, 317, 318, 467, 468, 332, 333, 678, 679, 316, 632, - 665, 629, 677, 659, 461, 397, 1411, 1417, 400, 297, - 322, 339, 1426, 649, 527, 236, 490, 306, 265, 1445, - 1447, 219, 257, 239, 275, 290, 293, 343, 411, 421, + 665, 629, 677, 659, 461, 397, 1412, 1418, 400, 297, + 322, 339, 1427, 649, 527, 236, 490, 306, 265, 1446, + 1448, 219, 257, 239, 275, 290, 293, 343, 411, 421, 451, 457, 312, 287, 255, 483, 252, 509, 548, 549, - 550, 552, 415, 282, 456, 1407, 1436, 395, 606, 607, - 335, 1471, 1450, 557, 0, 1391, 1474, 1356, 1377, 1484, - 1380, 1383, 1428, 1331, 1406, 438, 1374, 1360, 1326, 1368, - 1327, 1358, 1393, 286, 1355, 1452, 1410, 1473, 385, 283, - 1333, 1324, 212, 530, 1361, 453, 1379, 211, 1431, 511, + 550, 552, 415, 282, 456, 1408, 1437, 395, 606, 607, + 335, 1472, 1451, 557, 0, 1392, 1475, 1357, 1378, 1485, + 1381, 1384, 1429, 1332, 1407, 438, 1375, 1361, 1327, 1369, + 1328, 1359, 1394, 286, 1356, 1453, 1411, 1474, 385, 283, + 1334, 1325, 212, 530, 1362, 453, 1380, 211, 1432, 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, - 450, 547, 444, 1480, 389, 1416, 0, 522, 422, 0, - 0, 0, 1457, 1456, 1384, 1395, 1462, 1404, 1443, 1389, - 1430, 1343, 1415, 1475, 1375, 1425, 1476, 342, 262, 344, + 450, 547, 444, 1481, 389, 1417, 0, 522, 422, 0, + 0, 0, 1458, 1457, 1385, 1396, 1463, 1405, 1444, 1390, + 1431, 1344, 1416, 1476, 1376, 1426, 1477, 342, 262, 344, 210, 435, 523, 302, 0, 0, 0, 0, 0, 536, - 756, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, - 358, 359, 361, 363, 369, 376, 382, 355, 364, 1371, - 1422, 641, 1469, 1372, 1424, 281, 340, 288, 280, 612, - 1481, 1461, 1330, 1403, 1468, 1398, 628, 0, 0, 238, - 1472, 1397, 0, 1427, 0, 1487, 1325, 1418, 0, 1328, - 1332, 1483, 1466, 1364, 1365, 291, 0, 0, 0, 0, - 0, 0, 0, 1394, 1405, 1440, 1444, 1387, 0, 416, - 0, 0, 0, 0, 0, 3311, 0, 1362, 0, 1414, - 0, 0, 0, 1337, 1329, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1392, 0, 0, - 0, 0, 1342, 0, 1363, 1441, 0, 1323, 313, 1334, - 423, 273, 0, 477, 1354, 319, 334, 1340, 1369, 1470, - 1458, 1459, 1460, 1339, 1448, 1465, 1388, 661, 1467, 1386, - 1385, 1435, 1338, 1455, 1378, 384, 1336, 349, 205, 233, - 0, 1376, 434, 485, 497, 1454, 1453, 1359, 1370, 269, - 1367, 495, 448, 636, 243, 300, 482, 455, 493, 463, - 303, 1413, 1433, 494, 391, 617, 473, 633, 662, 663, + 358, 359, 361, 363, 369, 376, 382, 355, 364, 1372, + 1423, 641, 1470, 1373, 1425, 281, 340, 288, 280, 612, + 1482, 1462, 1331, 1404, 1469, 1399, 628, 0, 0, 238, + 1473, 1398, 0, 1428, 0, 1488, 1326, 1419, 0, 1329, + 1333, 1484, 1467, 1365, 1366, 291, 0, 0, 0, 0, + 0, 0, 0, 1395, 1406, 1441, 1445, 1388, 0, 416, + 0, 0, 0, 0, 0, 0, 0, 1363, 0, 1415, + 0, 0, 0, 1338, 1330, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1393, 0, 0, + 0, 0, 1343, 0, 1364, 1442, 0, 1324, 313, 1335, + 423, 273, 0, 477, 1355, 319, 334, 1341, 1370, 1471, + 1459, 1460, 1461, 1340, 1449, 1466, 1389, 661, 1468, 1387, + 1386, 1436, 1339, 1456, 1379, 384, 1337, 349, 205, 233, + 0, 1377, 434, 485, 497, 1455, 1454, 1360, 1371, 269, + 1368, 495, 448, 636, 243, 300, 482, 455, 493, 463, + 303, 1414, 1434, 494, 391, 617, 473, 633, 662, 663, 279, 428, 647, 551, 655, 680, 234, 276, 442, 535, 639, 519, 417, 613, 614, 348, 518, 311, 209, 388, 668, 232, 503, 390, 253, 241, 619, 644, 315, 267, 305, 480, 675, 221, 546, 630, 250, 507, 0, 0, 683, 258, 529, 642, 631, 223, 626, 528, 413, 345, 346, 222, 0, 481, 284, 309, 0, 0, 274, 437, - 621, 622, 272, 684, 237, 654, 228, 1335, 653, 430, + 621, 622, 272, 684, 237, 654, 228, 1336, 653, 430, 616, 627, 414, 402, 227, 625, 412, 401, 353, 374, 375, 296, 324, 470, 394, 471, 323, 325, 425, 424, 426, 215, 640, 658, 0, 216, 0, 524, 643, 685, - 475, 220, 244, 245, 248, 1353, 295, 299, 307, 310, - 320, 321, 331, 386, 441, 469, 465, 474, 1449, 610, + 475, 220, 244, 245, 248, 1354, 295, 299, 307, 310, + 320, 321, 331, 386, 441, 469, 465, 474, 1450, 610, 634, 648, 660, 666, 667, 669, 670, 671, 672, 673, - 676, 674, 429, 329, 520, 352, 392, 1438, 1486, 447, + 676, 674, 429, 329, 520, 352, 392, 1439, 1487, 447, 496, 251, 638, 521, 240, 604, 418, 427, 259, 261, - 260, 235, 512, 609, 246, 266, 207, 1347, 1352, 1345, - 0, 270, 271, 1419, 605, 1348, 1346, 1408, 1409, 1349, - 1477, 1478, 1479, 1463, 686, 687, 688, 689, 690, 691, + 260, 235, 512, 609, 246, 266, 207, 1348, 1353, 1346, + 0, 270, 271, 1420, 605, 1349, 1347, 1409, 1410, 1350, + 1478, 1479, 1480, 1464, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 681, 537, 543, 538, 539, 540, 541, 542, - 0, 544, 1442, 1341, 0, 1350, 1351, 419, 1451, 623, + 0, 544, 1443, 1342, 0, 1351, 1352, 419, 1452, 623, 624, 704, 403, 510, 635, 354, 368, 371, 360, 380, 0, 381, 356, 357, 362, 365, 366, 367, 372, 373, 377, 383, 263, 218, 410, 420, 608, 330, 224, 225, @@ -3399,53 +3609,53 @@ var yyAct = [...]int{ 570, 572, 583, 587, 589, 591, 597, 600, 559, 561, 563, 565, 578, 577, 574, 602, 603, 580, 585, 564, 576, 581, 594, 601, 598, 558, 562, 566, 575, 593, - 592, 573, 584, 595, 579, 567, 560, 568, 1412, 204, - 229, 387, 1482, 478, 304, 682, 650, 508, 645, 214, - 231, 1344, 278, 1357, 1366, 0, 1373, 1381, 1382, 1396, - 1399, 1400, 1401, 1402, 1420, 1421, 1423, 1432, 1434, 1437, - 1439, 1446, 1464, 1485, 206, 208, 217, 230, 242, 247, + 592, 573, 584, 595, 579, 567, 560, 568, 1413, 204, + 229, 387, 1483, 478, 304, 682, 650, 508, 645, 214, + 231, 1345, 278, 1358, 1367, 0, 1374, 1382, 1383, 1397, + 1400, 1401, 1402, 1403, 1421, 1422, 1424, 1433, 1435, 1438, + 1440, 1447, 1465, 1486, 206, 208, 217, 230, 242, 247, 254, 277, 292, 294, 301, 314, 327, 328, 337, 338, 341, 347, 399, 406, 407, 408, 409, 431, 432, 433, 436, 439, 440, 443, 445, 446, 449, 454, 458, 459, 460, 462, 464, 466, 479, 484, 498, 499, 500, 501, 502, 505, 506, 513, 514, 515, 516, 517, 525, 526, 531, 532, 533, 534, 545, 618, 620, 637, 657, 664, - 504, 404, 452, 476, 611, 1429, 1390, 317, 318, 467, + 504, 404, 452, 476, 611, 1430, 1391, 317, 318, 467, 468, 332, 333, 678, 679, 316, 632, 665, 629, 677, - 659, 461, 397, 1411, 1417, 400, 297, 322, 339, 1426, - 649, 527, 236, 490, 306, 265, 1445, 1447, 219, 257, + 659, 461, 397, 1412, 1418, 400, 297, 322, 339, 1427, + 649, 527, 236, 490, 306, 265, 1446, 1448, 219, 257, 239, 275, 290, 293, 343, 411, 421, 451, 457, 312, 287, 255, 483, 252, 509, 548, 549, 550, 552, 415, - 282, 456, 1407, 1436, 395, 606, 607, 335, 1471, 1450, - 557, 0, 1391, 1474, 1356, 1377, 1484, 1380, 1383, 1428, - 1331, 1406, 438, 1374, 1360, 1326, 1368, 1327, 1358, 1393, - 286, 1355, 1452, 1410, 1473, 385, 283, 1333, 1324, 212, - 530, 1361, 453, 1379, 211, 1431, 511, 268, 396, 393, + 282, 456, 1408, 1437, 395, 606, 607, 335, 1472, 1451, + 557, 0, 1392, 1475, 1357, 1378, 1485, 1381, 1384, 1429, + 1332, 1407, 438, 1375, 1361, 1327, 1369, 1328, 1359, 1394, + 286, 1356, 1453, 1411, 1474, 385, 283, 1334, 1325, 212, + 530, 1362, 453, 1380, 211, 1432, 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, 450, 547, 444, - 1480, 389, 1416, 0, 522, 422, 0, 0, 0, 1457, - 1456, 1384, 1395, 1462, 1404, 1443, 1389, 1430, 1343, 1415, - 1475, 1375, 1425, 1476, 342, 262, 344, 210, 435, 523, - 302, 0, 0, 0, 0, 0, 536, 991, 0, 0, + 1481, 389, 1417, 0, 522, 422, 0, 0, 0, 1458, + 1457, 1385, 1396, 1463, 1405, 1444, 1390, 1431, 1344, 1416, + 1476, 1376, 1426, 1477, 342, 262, 344, 210, 435, 523, + 302, 0, 0, 0, 0, 0, 536, 756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, - 363, 369, 376, 382, 355, 364, 1371, 1422, 641, 1469, - 1372, 1424, 281, 340, 288, 280, 612, 1481, 1461, 1330, - 1403, 1468, 1398, 628, 0, 0, 238, 1472, 1397, 0, - 1427, 0, 1487, 1325, 1418, 0, 1328, 1332, 1483, 1466, - 1364, 1365, 291, 0, 0, 0, 0, 0, 0, 0, - 1394, 1405, 1440, 1444, 1387, 0, 416, 0, 0, 0, - 0, 0, 2486, 0, 1362, 0, 1414, 0, 0, 0, - 1337, 1329, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1392, 0, 0, 0, 0, 1342, - 0, 1363, 1441, 0, 1323, 313, 1334, 423, 273, 0, - 477, 1354, 319, 334, 1340, 1369, 1470, 1458, 1459, 1460, - 1339, 1448, 1465, 1388, 661, 1467, 1386, 1385, 1435, 1338, - 1455, 1378, 384, 1336, 349, 205, 233, 0, 1376, 434, - 485, 497, 1454, 1453, 1359, 1370, 269, 1367, 495, 448, - 636, 243, 300, 482, 455, 493, 463, 303, 1413, 1433, + 363, 369, 376, 382, 355, 364, 1372, 1423, 641, 1470, + 1373, 1425, 281, 340, 288, 280, 612, 1482, 1462, 1331, + 1404, 1469, 1399, 628, 0, 0, 238, 1473, 1398, 0, + 1428, 0, 1488, 1326, 1419, 0, 1329, 1333, 1484, 1467, + 1365, 1366, 291, 0, 0, 0, 0, 0, 0, 0, + 1395, 1406, 1441, 1445, 1388, 0, 416, 0, 0, 0, + 0, 0, 0, 0, 1363, 0, 1415, 0, 0, 0, + 1338, 1330, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1393, 0, 0, 0, 0, 1343, + 0, 1364, 1442, 0, 1324, 313, 1335, 423, 273, 0, + 477, 1355, 319, 334, 1341, 1370, 1471, 1459, 1460, 1461, + 1340, 1449, 1466, 1389, 661, 1468, 1387, 1386, 1436, 1339, + 1456, 1379, 384, 1337, 349, 205, 233, 0, 1377, 434, + 485, 497, 1455, 1454, 1360, 1371, 269, 1368, 495, 448, + 636, 243, 300, 482, 455, 493, 463, 303, 1414, 1434, 494, 391, 617, 473, 633, 662, 663, 279, 428, 647, 551, 655, 680, 234, 276, 442, 535, 639, 519, 417, 613, 614, 348, 518, 311, 209, 388, 668, 232, 503, @@ -3453,21 +3663,21 @@ var yyAct = [...]int{ 221, 546, 630, 250, 507, 0, 0, 683, 258, 529, 642, 631, 223, 626, 528, 413, 345, 346, 222, 0, 481, 284, 309, 0, 0, 274, 437, 621, 622, 272, - 684, 237, 654, 228, 1335, 653, 430, 616, 627, 414, + 684, 237, 654, 228, 1336, 653, 430, 616, 627, 414, 402, 227, 625, 412, 401, 353, 374, 375, 296, 324, 470, 394, 471, 323, 325, 425, 424, 426, 215, 640, 658, 0, 216, 0, 524, 643, 685, 475, 220, 244, - 245, 248, 1353, 295, 299, 307, 310, 320, 321, 331, - 386, 441, 469, 465, 474, 1449, 610, 634, 648, 660, + 245, 248, 1354, 295, 299, 307, 310, 320, 321, 331, + 386, 441, 469, 465, 474, 1450, 610, 634, 648, 660, 666, 667, 669, 670, 671, 672, 673, 676, 674, 429, - 329, 520, 352, 392, 1438, 1486, 447, 496, 251, 638, + 329, 520, 352, 392, 1439, 1487, 447, 496, 251, 638, 521, 240, 604, 418, 427, 259, 261, 260, 235, 512, - 609, 246, 266, 207, 1347, 1352, 1345, 0, 270, 271, - 1419, 605, 1348, 1346, 1408, 1409, 1349, 1477, 1478, 1479, - 1463, 686, 687, 688, 689, 690, 691, 692, 693, 694, + 609, 246, 266, 207, 1348, 1353, 1346, 0, 270, 271, + 1420, 605, 1349, 1347, 1409, 1410, 1350, 1478, 1479, 1480, + 1464, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 681, - 537, 543, 538, 539, 540, 541, 542, 0, 544, 1442, - 1341, 0, 1350, 1351, 419, 1451, 623, 624, 704, 403, + 537, 543, 538, 539, 540, 541, 542, 0, 544, 1443, + 1342, 0, 1351, 1352, 419, 1452, 623, 624, 704, 403, 510, 635, 354, 368, 371, 360, 380, 0, 381, 356, 357, 362, 365, 366, 367, 372, 373, 377, 383, 263, 218, 410, 420, 608, 330, 224, 225, 226, 553, 554, @@ -3477,53 +3687,53 @@ var yyAct = [...]int{ 587, 589, 591, 597, 600, 559, 561, 563, 565, 578, 577, 574, 602, 603, 580, 585, 564, 576, 581, 594, 601, 598, 558, 562, 566, 575, 593, 592, 573, 584, - 595, 579, 567, 560, 568, 1412, 204, 229, 387, 1482, - 478, 304, 682, 650, 508, 645, 214, 231, 1344, 278, - 1357, 1366, 0, 1373, 1381, 1382, 1396, 1399, 1400, 1401, - 1402, 1420, 1421, 1423, 1432, 1434, 1437, 1439, 1446, 1464, - 1485, 206, 208, 217, 230, 242, 247, 254, 277, 292, + 595, 579, 567, 560, 568, 1413, 204, 229, 387, 1483, + 478, 304, 682, 650, 508, 645, 214, 231, 1345, 278, + 1358, 1367, 0, 1374, 1382, 1383, 1397, 1400, 1401, 1402, + 1403, 1421, 1422, 1424, 1433, 1435, 1438, 1440, 1447, 1465, + 1486, 206, 208, 217, 230, 242, 247, 254, 277, 292, 294, 301, 314, 327, 328, 337, 338, 341, 347, 399, 406, 407, 408, 409, 431, 432, 433, 436, 439, 440, 443, 445, 446, 449, 454, 458, 459, 460, 462, 464, 466, 479, 484, 498, 499, 500, 501, 502, 505, 506, 513, 514, 515, 516, 517, 525, 526, 531, 532, 533, 534, 545, 618, 620, 637, 657, 664, 504, 404, 452, - 476, 611, 1429, 1390, 317, 318, 467, 468, 332, 333, + 476, 611, 1430, 1391, 317, 318, 467, 468, 332, 333, 678, 679, 316, 632, 665, 629, 677, 659, 461, 397, - 1411, 1417, 400, 297, 322, 339, 1426, 649, 527, 236, - 490, 306, 265, 1445, 1447, 219, 257, 239, 275, 290, + 1412, 1418, 400, 297, 322, 339, 1427, 649, 527, 236, + 490, 306, 265, 1446, 1448, 219, 257, 239, 275, 290, 293, 343, 411, 421, 451, 457, 312, 287, 255, 483, - 252, 509, 548, 549, 550, 552, 415, 282, 456, 1407, - 1436, 395, 606, 607, 335, 1471, 1450, 557, 0, 1391, - 1474, 1356, 1377, 1484, 1380, 1383, 1428, 1331, 1406, 438, - 1374, 1360, 1326, 1368, 1327, 1358, 1393, 286, 1355, 1452, - 1410, 1473, 385, 283, 1333, 1324, 212, 530, 1361, 453, - 1379, 211, 1431, 511, 268, 396, 393, 615, 298, 289, - 285, 264, 336, 405, 450, 547, 444, 1480, 389, 1416, - 0, 522, 422, 0, 0, 0, 1457, 1456, 1384, 1395, - 1462, 1404, 1443, 1389, 1430, 1343, 1415, 1475, 1375, 1425, - 1476, 342, 262, 344, 210, 435, 523, 302, 0, 101, - 0, 0, 0, 536, 756, 0, 0, 0, 0, 0, + 252, 509, 548, 549, 550, 552, 415, 282, 456, 1408, + 1437, 395, 606, 607, 335, 1472, 1451, 557, 0, 1392, + 1475, 1357, 1378, 1485, 1381, 1384, 1429, 1332, 1407, 438, + 1375, 1361, 1327, 1369, 1328, 1359, 1394, 286, 1356, 1453, + 1411, 1474, 385, 283, 1334, 1325, 212, 530, 1362, 453, + 1380, 211, 1432, 511, 268, 396, 393, 615, 298, 289, + 285, 264, 336, 405, 450, 547, 444, 1481, 389, 1417, + 0, 522, 422, 0, 0, 0, 1458, 1457, 1385, 1396, + 1463, 1405, 1444, 1390, 1431, 1344, 1416, 1476, 1376, 1426, + 1477, 342, 262, 344, 210, 435, 523, 302, 0, 0, + 0, 0, 0, 536, 991, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, - 382, 355, 364, 1371, 1422, 641, 1469, 1372, 1424, 281, - 340, 288, 280, 612, 1481, 1461, 1330, 1403, 1468, 1398, - 628, 0, 0, 238, 1472, 1397, 0, 1427, 0, 1487, - 1325, 1418, 0, 1328, 1332, 1483, 1466, 1364, 1365, 291, - 0, 0, 0, 0, 0, 0, 0, 1394, 1405, 1440, - 1444, 1387, 0, 416, 0, 0, 0, 0, 0, 0, - 0, 1362, 0, 1414, 0, 0, 0, 1337, 1329, 0, + 382, 355, 364, 1372, 1423, 641, 1470, 1373, 1425, 281, + 340, 288, 280, 612, 1482, 1462, 1331, 1404, 1469, 1399, + 628, 0, 0, 238, 1473, 1398, 0, 1428, 0, 1488, + 1326, 1419, 0, 1329, 1333, 1484, 1467, 1365, 1366, 291, + 0, 0, 0, 0, 0, 0, 0, 1395, 1406, 1441, + 1445, 1388, 0, 416, 0, 0, 0, 0, 0, 0, + 0, 1363, 0, 1415, 0, 0, 0, 1338, 1330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1392, 0, 0, 0, 0, 1342, 0, 1363, 1441, - 0, 1323, 313, 1334, 423, 273, 0, 477, 1354, 319, - 334, 1340, 1369, 1470, 1458, 1459, 1460, 1339, 1448, 1465, - 1388, 661, 1467, 1386, 1385, 1435, 1338, 1455, 1378, 384, - 1336, 349, 205, 233, 0, 1376, 434, 485, 497, 1454, - 1453, 1359, 1370, 269, 1367, 495, 448, 636, 243, 300, - 482, 455, 493, 463, 303, 1413, 1433, 494, 391, 617, + 0, 1393, 0, 0, 0, 0, 1343, 0, 1364, 1442, + 0, 1324, 313, 1335, 423, 273, 0, 477, 1355, 319, + 334, 1341, 1370, 1471, 1459, 1460, 1461, 1340, 1449, 1466, + 1389, 661, 1468, 1387, 1386, 1436, 1339, 1456, 1379, 384, + 1337, 349, 205, 233, 0, 1377, 434, 485, 497, 1455, + 1454, 1360, 1371, 269, 1368, 495, 448, 636, 243, 300, + 482, 455, 493, 463, 303, 1414, 1434, 494, 391, 617, 473, 633, 662, 663, 279, 428, 647, 551, 655, 680, 234, 276, 442, 535, 639, 519, 417, 613, 614, 348, 518, 311, 209, 388, 668, 232, 503, 390, 253, 241, @@ -3531,21 +3741,21 @@ var yyAct = [...]int{ 250, 507, 0, 0, 683, 258, 529, 642, 631, 223, 626, 528, 413, 345, 346, 222, 0, 481, 284, 309, 0, 0, 274, 437, 621, 622, 272, 684, 237, 654, - 228, 1335, 653, 430, 616, 627, 414, 402, 227, 625, + 228, 1336, 653, 430, 616, 627, 414, 402, 227, 625, 412, 401, 353, 374, 375, 296, 324, 470, 394, 471, 323, 325, 425, 424, 426, 215, 640, 658, 0, 216, - 0, 524, 643, 685, 475, 220, 244, 245, 248, 1353, + 0, 524, 643, 685, 475, 220, 244, 245, 248, 1354, 295, 299, 307, 310, 320, 321, 331, 386, 441, 469, - 465, 474, 1449, 610, 634, 648, 660, 666, 667, 669, + 465, 474, 1450, 610, 634, 648, 660, 666, 667, 669, 670, 671, 672, 673, 676, 674, 429, 329, 520, 352, - 392, 1438, 1486, 447, 496, 251, 638, 521, 240, 604, + 392, 1439, 1487, 447, 496, 251, 638, 521, 240, 604, 418, 427, 259, 261, 260, 235, 512, 609, 246, 266, - 207, 1347, 1352, 1345, 0, 270, 271, 1419, 605, 1348, - 1346, 1408, 1409, 1349, 1477, 1478, 1479, 1463, 686, 687, + 207, 1348, 1353, 1346, 0, 270, 271, 1420, 605, 1349, + 1347, 1409, 1410, 1350, 1478, 1479, 1480, 1464, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 681, 537, 543, 538, - 539, 540, 541, 542, 0, 544, 1442, 1341, 0, 1350, - 1351, 419, 1451, 623, 624, 704, 403, 510, 635, 354, + 539, 540, 541, 542, 0, 544, 1443, 1342, 0, 1351, + 1352, 419, 1452, 623, 624, 704, 403, 510, 635, 354, 368, 371, 360, 380, 0, 381, 356, 357, 362, 365, 366, 367, 372, 373, 377, 383, 263, 218, 410, 420, 608, 330, 224, 225, 226, 553, 554, 555, 556, 651, @@ -3555,243 +3765,320 @@ var yyAct = [...]int{ 597, 600, 559, 561, 563, 565, 578, 577, 574, 602, 603, 580, 585, 564, 576, 581, 594, 601, 598, 558, 562, 566, 575, 593, 592, 573, 584, 595, 579, 567, - 560, 568, 1412, 204, 229, 387, 1482, 478, 304, 682, - 650, 508, 645, 214, 231, 1344, 278, 1357, 1366, 0, - 1373, 1381, 1382, 1396, 1399, 1400, 1401, 1402, 1420, 1421, - 1423, 1432, 1434, 1437, 1439, 1446, 1464, 1485, 206, 208, + 560, 568, 1413, 204, 229, 387, 1483, 478, 304, 682, + 650, 508, 645, 214, 231, 1345, 278, 1358, 1367, 0, + 1374, 1382, 1383, 1397, 1400, 1401, 1402, 1403, 1421, 1422, + 1424, 1433, 1435, 1438, 1440, 1447, 1465, 1486, 206, 208, 217, 230, 242, 247, 254, 277, 292, 294, 301, 314, 327, 328, 337, 338, 341, 347, 399, 406, 407, 408, 409, 431, 432, 433, 436, 439, 440, 443, 445, 446, 449, 454, 458, 459, 460, 462, 464, 466, 479, 484, 498, 499, 500, 501, 502, 505, 506, 513, 514, 515, 516, 517, 525, 526, 531, 532, 533, 534, 545, 618, - 620, 637, 657, 664, 504, 404, 452, 476, 611, 1429, - 1390, 317, 318, 467, 468, 332, 333, 678, 679, 316, - 632, 665, 629, 677, 659, 461, 397, 1411, 1417, 400, - 297, 322, 339, 1426, 649, 527, 236, 490, 306, 265, - 1445, 1447, 219, 257, 239, 275, 290, 293, 343, 411, + 620, 637, 657, 664, 504, 404, 452, 476, 611, 1430, + 1391, 317, 318, 467, 468, 332, 333, 678, 679, 316, + 632, 665, 629, 677, 659, 461, 397, 1412, 1418, 400, + 297, 322, 339, 1427, 649, 527, 236, 490, 306, 265, + 1446, 1448, 219, 257, 239, 275, 290, 293, 343, 411, 421, 451, 457, 312, 287, 255, 483, 252, 509, 548, - 549, 550, 552, 415, 282, 456, 1407, 1436, 395, 606, - 607, 335, 1471, 1450, 557, 0, 1391, 1474, 1356, 1377, - 1484, 1380, 1383, 1428, 1331, 1406, 438, 1374, 1360, 1326, - 1368, 1327, 1358, 1393, 286, 1355, 1452, 1410, 1473, 385, - 283, 1333, 1324, 212, 530, 1361, 453, 1379, 211, 1431, - 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, - 405, 450, 547, 444, 1480, 389, 1416, 0, 522, 422, - 0, 0, 0, 1457, 1456, 1384, 1395, 1462, 1404, 1443, - 1389, 1430, 1343, 1415, 1475, 1375, 1425, 1476, 342, 262, - 344, 210, 435, 523, 302, 0, 0, 0, 0, 0, - 536, 202, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, - 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, - 1371, 1422, 641, 1469, 1372, 1424, 281, 340, 288, 280, - 612, 1481, 1461, 1330, 1403, 1468, 1398, 628, 0, 0, - 238, 1472, 1397, 0, 1427, 0, 1487, 1325, 1418, 0, - 1328, 1332, 1483, 1466, 1364, 1365, 291, 0, 0, 0, - 0, 0, 0, 0, 1394, 1405, 1440, 1444, 1387, 0, - 416, 0, 0, 0, 0, 0, 0, 0, 1362, 0, - 1414, 0, 0, 0, 1337, 1329, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1392, 0, - 0, 0, 0, 1342, 0, 1363, 1441, 0, 1323, 313, - 1334, 423, 273, 0, 477, 1354, 319, 334, 1340, 1369, - 1470, 1458, 1459, 1460, 1339, 1448, 1465, 1388, 661, 1467, - 1386, 1385, 1435, 1338, 1455, 1378, 384, 1336, 349, 205, - 233, 0, 1376, 434, 485, 497, 1454, 1453, 1359, 1370, - 269, 1367, 495, 448, 636, 243, 300, 482, 455, 493, - 463, 303, 1413, 1433, 494, 391, 617, 473, 633, 662, - 663, 279, 428, 647, 551, 655, 680, 234, 276, 442, - 535, 639, 519, 417, 613, 614, 348, 518, 311, 209, - 388, 668, 232, 503, 390, 253, 241, 619, 644, 315, - 267, 305, 480, 675, 221, 546, 630, 250, 507, 0, - 0, 683, 258, 529, 642, 631, 223, 626, 528, 413, - 345, 346, 222, 0, 481, 284, 309, 0, 0, 274, - 437, 621, 622, 272, 684, 237, 654, 228, 1335, 653, - 430, 616, 627, 414, 402, 227, 625, 412, 401, 353, - 374, 375, 296, 324, 470, 394, 471, 323, 325, 425, - 424, 426, 215, 640, 658, 0, 216, 0, 524, 643, - 685, 475, 220, 244, 245, 248, 1353, 295, 299, 307, - 310, 320, 321, 331, 386, 441, 469, 465, 474, 1449, - 610, 634, 648, 660, 666, 667, 669, 670, 671, 672, - 673, 676, 674, 429, 329, 520, 352, 392, 1438, 1486, - 447, 496, 251, 638, 521, 240, 604, 418, 427, 259, - 261, 260, 235, 512, 609, 246, 266, 207, 1347, 1352, - 1345, 0, 270, 271, 1419, 605, 1348, 1346, 1408, 1409, - 1349, 1477, 1478, 1479, 1463, 686, 687, 688, 689, 690, - 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, - 701, 702, 703, 681, 537, 543, 538, 539, 540, 541, - 542, 0, 544, 1442, 1341, 0, 1350, 1351, 419, 1451, - 623, 624, 704, 403, 510, 635, 354, 368, 371, 360, - 380, 0, 381, 356, 357, 362, 365, 366, 367, 372, - 373, 377, 383, 263, 218, 410, 420, 608, 330, 224, - 225, 226, 553, 554, 555, 556, 651, 652, 656, 213, - 486, 487, 488, 489, 308, 646, 326, 492, 491, 350, - 351, 398, 472, 569, 571, 582, 586, 588, 590, 596, - 599, 570, 572, 583, 587, 589, 591, 597, 600, 559, - 561, 563, 565, 578, 577, 574, 602, 603, 580, 585, - 564, 576, 581, 594, 601, 598, 558, 562, 566, 575, - 593, 592, 573, 584, 595, 579, 567, 560, 568, 1412, - 204, 229, 387, 1482, 478, 304, 682, 650, 508, 645, - 214, 231, 1344, 278, 1357, 1366, 0, 1373, 1381, 1382, - 1396, 1399, 1400, 1401, 1402, 1420, 1421, 1423, 1432, 1434, - 1437, 1439, 1446, 1464, 1485, 206, 208, 217, 230, 242, - 247, 254, 277, 292, 294, 301, 314, 327, 328, 337, - 338, 341, 347, 399, 406, 407, 408, 409, 431, 432, - 433, 436, 439, 440, 443, 445, 446, 449, 454, 458, - 459, 460, 462, 464, 466, 479, 484, 498, 499, 500, - 501, 502, 505, 506, 513, 514, 515, 516, 517, 525, - 526, 531, 532, 533, 534, 545, 618, 620, 637, 657, - 664, 504, 404, 452, 476, 611, 1429, 1390, 317, 318, - 467, 468, 332, 333, 678, 679, 316, 632, 665, 629, - 677, 659, 461, 397, 1411, 1417, 400, 297, 322, 339, - 1426, 649, 527, 236, 490, 306, 265, 1445, 1447, 219, - 257, 239, 275, 290, 293, 343, 411, 421, 451, 457, - 312, 287, 255, 483, 252, 509, 548, 549, 550, 552, - 415, 282, 456, 1407, 1436, 395, 606, 607, 335, 1471, - 1450, 557, 0, 1391, 1474, 1356, 1377, 1484, 1380, 1383, - 1428, 1331, 1406, 438, 1374, 1360, 1326, 1368, 1327, 1358, - 1393, 286, 1355, 1452, 1410, 1473, 385, 283, 1333, 1324, - 212, 530, 1361, 453, 1379, 211, 1431, 511, 268, 396, - 393, 615, 298, 289, 285, 264, 336, 405, 450, 547, - 444, 1480, 389, 1416, 0, 522, 422, 0, 0, 0, - 1457, 1456, 1384, 1395, 1462, 1404, 1443, 1389, 1430, 1343, - 1415, 1475, 1375, 1425, 1476, 342, 262, 344, 210, 435, - 523, 302, 0, 0, 0, 0, 0, 536, 756, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, - 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, - 361, 363, 369, 376, 382, 355, 364, 1371, 1422, 641, - 1469, 1372, 1424, 281, 340, 288, 280, 612, 1481, 1461, - 1330, 1403, 1468, 1398, 628, 0, 0, 238, 1472, 1397, - 0, 1427, 0, 1487, 1325, 1418, 0, 1328, 1332, 1483, - 1466, 1364, 1365, 291, 0, 0, 0, 0, 0, 0, - 0, 1394, 1405, 1440, 1444, 1387, 0, 416, 0, 0, - 0, 0, 0, 0, 0, 1362, 0, 1414, 0, 0, - 0, 1337, 1329, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1392, 0, 0, 0, 0, - 1342, 0, 1363, 1441, 0, 1323, 313, 1334, 423, 273, - 0, 477, 1354, 319, 334, 1340, 1369, 1470, 1458, 1459, - 1460, 1339, 1448, 1465, 1388, 661, 1467, 1386, 1385, 1435, - 1338, 1455, 1378, 384, 1336, 349, 205, 233, 0, 1376, - 434, 485, 497, 1454, 1453, 1359, 1370, 269, 1367, 495, - 448, 636, 243, 300, 482, 455, 493, 463, 303, 1413, - 1433, 494, 391, 617, 473, 633, 662, 663, 279, 428, - 647, 551, 655, 680, 234, 276, 442, 535, 639, 519, - 417, 613, 614, 348, 518, 311, 209, 388, 668, 232, - 503, 390, 253, 241, 619, 644, 315, 267, 305, 480, - 675, 221, 546, 630, 250, 507, 0, 0, 683, 258, - 529, 642, 631, 223, 626, 528, 413, 345, 346, 222, - 0, 481, 284, 309, 0, 0, 274, 437, 621, 622, - 272, 684, 237, 654, 228, 1335, 653, 430, 616, 627, - 414, 402, 227, 625, 412, 401, 353, 374, 375, 296, - 324, 470, 394, 471, 323, 325, 425, 424, 426, 215, - 640, 658, 0, 216, 0, 524, 643, 685, 475, 220, - 244, 245, 248, 1353, 295, 299, 307, 310, 320, 321, - 331, 386, 441, 469, 465, 474, 1449, 610, 634, 648, - 660, 666, 667, 669, 670, 671, 672, 673, 676, 674, - 429, 329, 520, 352, 392, 1438, 1486, 447, 496, 251, - 638, 521, 240, 604, 418, 427, 259, 261, 260, 235, - 512, 609, 246, 266, 207, 1347, 1352, 1345, 0, 270, - 271, 1419, 605, 1348, 1346, 1408, 1409, 1349, 1477, 1478, - 1479, 1463, 686, 687, 688, 689, 690, 691, 692, 693, - 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, - 681, 537, 543, 538, 539, 540, 541, 542, 0, 544, - 1442, 1341, 0, 1350, 1351, 419, 1451, 623, 624, 704, - 403, 510, 635, 354, 368, 371, 360, 380, 0, 381, - 356, 357, 362, 365, 366, 367, 372, 373, 377, 383, - 263, 218, 410, 420, 608, 330, 224, 225, 226, 553, - 554, 555, 556, 651, 652, 656, 213, 486, 487, 488, - 489, 308, 646, 326, 492, 491, 350, 351, 398, 472, - 569, 571, 582, 586, 588, 590, 596, 599, 570, 572, - 583, 587, 589, 591, 597, 600, 559, 561, 563, 565, - 578, 577, 574, 602, 603, 580, 585, 564, 576, 581, - 594, 601, 598, 558, 562, 566, 575, 593, 592, 573, - 584, 595, 579, 567, 560, 568, 1412, 204, 229, 387, - 1482, 478, 304, 682, 650, 508, 645, 214, 231, 1344, - 278, 1357, 1366, 0, 1373, 1381, 1382, 1396, 1399, 1400, - 1401, 1402, 1420, 1421, 1423, 1432, 1434, 1437, 1439, 1446, - 1464, 1485, 206, 208, 217, 230, 242, 247, 254, 277, - 292, 294, 301, 314, 327, 328, 337, 338, 341, 347, - 399, 406, 407, 408, 409, 431, 432, 433, 436, 439, - 440, 443, 445, 446, 449, 454, 458, 459, 460, 462, - 464, 466, 479, 484, 498, 499, 500, 501, 502, 505, - 506, 513, 514, 515, 516, 517, 525, 526, 531, 532, - 533, 534, 545, 618, 620, 637, 657, 664, 504, 404, - 452, 476, 611, 1429, 1390, 317, 318, 467, 468, 332, - 333, 678, 679, 316, 632, 665, 629, 677, 659, 461, - 397, 1411, 1417, 400, 297, 322, 339, 1426, 649, 527, - 236, 490, 306, 265, 1445, 1447, 219, 257, 239, 275, - 290, 293, 343, 411, 421, 451, 457, 312, 287, 255, - 483, 252, 509, 548, 549, 550, 552, 415, 282, 456, - 1407, 1436, 395, 606, 607, 335, 1471, 1450, 557, 0, - 1391, 1474, 1356, 1377, 1484, 1380, 1383, 1428, 1331, 1406, - 438, 1374, 1360, 1326, 1368, 1327, 1358, 1393, 286, 1355, - 1452, 1410, 1473, 385, 283, 1333, 1324, 212, 530, 1361, - 453, 1379, 211, 1431, 511, 268, 396, 393, 615, 298, - 289, 285, 264, 336, 405, 450, 547, 444, 1480, 389, - 1416, 0, 522, 422, 0, 0, 0, 1457, 1456, 1384, - 1395, 1462, 1404, 1443, 1389, 1430, 1343, 1415, 1475, 1375, - 1425, 1476, 342, 262, 344, 210, 435, 523, 302, 0, - 0, 0, 0, 0, 536, 991, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, - 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, - 376, 382, 355, 364, 1371, 1422, 641, 1469, 1372, 1424, - 281, 340, 288, 280, 612, 1481, 1461, 1330, 1403, 1468, - 1398, 628, 0, 0, 238, 1472, 1397, 0, 1427, 0, - 1487, 1325, 1418, 0, 1328, 1332, 1483, 1466, 1364, 1365, - 291, 0, 0, 0, 0, 0, 0, 0, 1394, 1405, - 1440, 1444, 1387, 0, 416, 0, 0, 0, 0, 0, - 0, 0, 1362, 0, 1414, 0, 0, 0, 1337, 1329, + 549, 550, 552, 415, 282, 456, 1408, 1437, 395, 606, + 607, 335, 557, 0, 809, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 438, 0, 0, 0, 796, 0, + 0, 0, 286, 801, 0, 0, 0, 385, 283, 0, + 0, 212, 530, 0, 453, 0, 211, 0, 511, 268, + 396, 393, 615, 298, 289, 285, 264, 336, 405, 450, + 547, 444, 808, 389, 0, 0, 522, 422, 0, 0, + 0, 0, 0, 0, 0, 0, 803, 804, 0, 0, + 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, + 435, 523, 302, 0, 101, 0, 0, 1057, 536, 991, + 780, 957, 995, 1058, 1009, 1010, 1011, 996, 0, 249, + 997, 998, 256, 999, 0, 956, 839, 841, 840, 906, + 907, 908, 909, 910, 911, 912, 842, 843, 837, 1004, + 641, 1012, 1013, 0, 281, 340, 288, 280, 612, 0, + 0, 2297, 2298, 2299, 0, 628, 0, 0, 238, 0, + 0, 0, 0, 0, 0, 0, 776, 793, 0, 807, + 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 416, 0, + 0, 0, 790, 791, 0, 0, 0, 0, 951, 0, + 792, 0, 0, 800, 1014, 1015, 1016, 1017, 1018, 1019, + 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, + 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, + 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, + 1050, 1051, 1052, 1053, 1054, 1055, 802, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 313, 0, 423, + 273, 0, 477, 0, 319, 334, 0, 0, 0, 0, + 0, 0, 0, 950, 0, 0, 661, 0, 0, 948, + 0, 0, 0, 0, 384, 0, 349, 205, 233, 0, + 0, 434, 485, 497, 0, 0, 0, 0, 1001, 0, + 495, 448, 636, 243, 300, 482, 455, 493, 463, 303, + 0, 0, 494, 391, 617, 473, 633, 662, 663, 279, + 428, 647, 551, 655, 680, 234, 276, 442, 535, 639, + 519, 417, 613, 614, 348, 518, 311, 209, 388, 668, + 232, 503, 390, 253, 241, 619, 644, 315, 267, 305, + 480, 675, 221, 546, 630, 250, 507, 0, 0, 683, + 258, 529, 642, 631, 223, 626, 528, 413, 345, 346, + 222, 0, 481, 284, 309, 0, 0, 274, 437, 1002, + 1003, 272, 684, 847, 654, 228, 0, 653, 430, 616, + 627, 414, 402, 227, 625, 412, 401, 353, 855, 856, + 296, 324, 932, 931, 930, 323, 325, 928, 929, 927, + 215, 640, 658, 0, 216, 0, 524, 643, 685, 475, + 220, 244, 245, 248, 0, 295, 299, 307, 310, 320, + 321, 331, 386, 441, 469, 465, 474, 0, 610, 634, + 648, 660, 666, 667, 669, 670, 671, 672, 673, 676, + 674, 429, 329, 520, 352, 392, 0, 0, 447, 496, + 251, 638, 521, 240, 604, 418, 427, 259, 261, 260, + 235, 512, 609, 246, 266, 938, 960, 949, 813, 814, + 939, 940, 964, 941, 816, 817, 961, 962, 810, 811, + 815, 963, 965, 686, 687, 688, 689, 690, 691, 692, + 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, + 703, 681, 537, 543, 538, 539, 540, 541, 542, 0, + 544, 952, 799, 798, 0, 805, 806, 0, 835, 836, + 838, 844, 845, 846, 857, 904, 905, 913, 915, 916, + 914, 917, 918, 919, 922, 923, 924, 925, 920, 921, + 926, 818, 822, 819, 820, 821, 833, 823, 824, 825, + 826, 827, 828, 829, 830, 831, 832, 834, 975, 976, + 977, 978, 979, 980, 850, 854, 853, 851, 852, 848, + 849, 876, 875, 877, 878, 879, 880, 881, 882, 884, + 883, 885, 886, 887, 888, 889, 890, 858, 859, 862, + 863, 861, 860, 864, 873, 874, 865, 866, 867, 868, + 869, 870, 872, 871, 891, 892, 893, 894, 895, 897, + 896, 900, 901, 899, 898, 903, 902, 797, 204, 229, + 387, 0, 478, 304, 682, 650, 508, 645, 214, 231, + 966, 278, 967, 0, 0, 971, 0, 0, 0, 973, + 972, 0, 974, 936, 935, 0, 0, 968, 969, 0, + 970, 0, 0, 206, 208, 217, 230, 242, 247, 254, + 277, 292, 294, 301, 314, 327, 328, 337, 338, 341, + 347, 399, 406, 407, 408, 409, 431, 432, 433, 436, + 439, 440, 443, 445, 446, 449, 454, 458, 459, 460, + 462, 464, 466, 479, 484, 498, 499, 500, 501, 502, + 505, 506, 513, 514, 515, 516, 517, 525, 526, 531, + 532, 533, 534, 545, 618, 620, 637, 657, 664, 504, + 404, 452, 476, 611, 0, 0, 981, 982, 983, 984, + 985, 986, 987, 988, 316, 632, 665, 629, 677, 659, + 461, 397, 0, 0, 400, 297, 322, 339, 0, 649, + 527, 236, 490, 306, 265, 1056, 0, 219, 257, 239, + 275, 290, 293, 343, 411, 421, 451, 457, 312, 287, + 255, 483, 252, 509, 548, 549, 550, 552, 415, 282, + 456, 0, 0, 395, 606, 607, 335, 557, 0, 809, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 438, + 0, 0, 0, 796, 0, 0, 0, 286, 801, 0, + 0, 0, 385, 283, 0, 0, 212, 530, 0, 453, + 0, 211, 0, 511, 268, 396, 393, 615, 298, 289, + 285, 264, 336, 405, 450, 547, 444, 808, 389, 0, + 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, + 0, 803, 804, 0, 0, 0, 0, 0, 0, 2521, + 0, 342, 262, 344, 210, 435, 523, 302, 0, 101, + 0, 0, 1057, 536, 991, 780, 957, 995, 1058, 1009, + 1010, 1011, 996, 0, 249, 997, 998, 256, 999, 0, + 956, 839, 841, 840, 906, 907, 908, 909, 910, 911, + 912, 842, 843, 837, 1004, 641, 1012, 1013, 2522, 281, + 340, 288, 280, 612, 0, 0, 0, 0, 0, 0, + 628, 0, 0, 238, 0, 0, 0, 0, 0, 0, + 0, 776, 793, 0, 807, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1392, 0, 0, 0, 0, 1342, 0, 1363, - 1441, 0, 1323, 313, 1334, 423, 273, 0, 477, 1354, - 319, 334, 1340, 1369, 1470, 1458, 1459, 1460, 1339, 1448, - 1465, 1388, 661, 1467, 1386, 1385, 1435, 1338, 1455, 1378, - 384, 1336, 349, 205, 233, 0, 1376, 434, 485, 497, - 1454, 1453, 1359, 1370, 269, 1367, 495, 448, 636, 243, - 300, 482, 455, 493, 463, 303, 1413, 1433, 494, 391, + 0, 0, 0, 416, 0, 0, 0, 790, 791, 0, + 0, 0, 0, 951, 0, 792, 0, 0, 800, 1014, + 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, + 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, + 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, + 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, + 1055, 802, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 313, 0, 423, 273, 0, 477, 0, 319, + 334, 0, 0, 0, 0, 0, 0, 0, 950, 0, + 0, 661, 0, 0, 948, 0, 0, 0, 0, 384, + 0, 349, 205, 233, 0, 0, 434, 485, 497, 0, + 0, 0, 0, 1001, 0, 495, 448, 636, 243, 300, + 482, 455, 493, 463, 303, 0, 0, 494, 391, 617, + 473, 633, 662, 663, 279, 428, 647, 551, 655, 680, + 234, 276, 442, 535, 639, 519, 417, 613, 614, 348, + 518, 311, 209, 388, 668, 232, 503, 390, 253, 241, + 619, 644, 315, 267, 305, 480, 675, 221, 546, 630, + 250, 507, 0, 0, 683, 258, 529, 642, 631, 223, + 626, 528, 413, 345, 346, 222, 0, 481, 284, 309, + 0, 0, 274, 437, 1002, 1003, 272, 684, 847, 654, + 228, 0, 653, 430, 616, 627, 414, 402, 227, 625, + 412, 401, 353, 855, 856, 296, 324, 932, 931, 930, + 323, 325, 928, 929, 927, 215, 640, 658, 0, 216, + 0, 524, 643, 685, 475, 220, 244, 245, 248, 0, + 295, 299, 307, 310, 320, 321, 331, 386, 441, 469, + 465, 474, 0, 610, 634, 648, 660, 666, 667, 669, + 670, 671, 672, 673, 676, 674, 429, 329, 520, 352, + 392, 0, 0, 447, 496, 251, 638, 521, 240, 604, + 418, 427, 259, 261, 260, 235, 512, 609, 246, 266, + 938, 960, 949, 813, 814, 939, 940, 964, 941, 816, + 817, 961, 962, 810, 811, 815, 963, 965, 686, 687, + 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, + 698, 699, 700, 701, 702, 703, 681, 537, 543, 538, + 539, 540, 541, 542, 0, 544, 952, 799, 798, 0, + 805, 806, 0, 835, 836, 838, 844, 845, 846, 857, + 904, 905, 913, 915, 916, 914, 917, 918, 919, 922, + 923, 924, 925, 920, 921, 926, 818, 822, 819, 820, + 821, 833, 823, 824, 825, 826, 827, 828, 829, 830, + 831, 832, 834, 975, 976, 977, 978, 979, 980, 850, + 854, 853, 851, 852, 848, 849, 876, 875, 877, 878, + 879, 880, 881, 882, 884, 883, 885, 886, 887, 888, + 889, 890, 858, 859, 862, 863, 861, 860, 864, 873, + 874, 865, 866, 867, 868, 869, 870, 872, 871, 891, + 892, 893, 894, 895, 897, 896, 900, 901, 899, 898, + 903, 902, 797, 204, 229, 387, 0, 478, 304, 682, + 650, 508, 645, 214, 231, 966, 278, 967, 0, 0, + 971, 0, 0, 0, 973, 972, 0, 974, 936, 935, + 0, 0, 968, 969, 0, 970, 0, 0, 206, 208, + 217, 230, 242, 247, 254, 277, 292, 294, 301, 314, + 327, 328, 337, 338, 341, 347, 399, 406, 407, 408, + 409, 431, 432, 433, 436, 439, 440, 443, 445, 446, + 449, 454, 458, 459, 460, 462, 464, 466, 479, 484, + 498, 499, 500, 501, 502, 505, 506, 513, 514, 515, + 516, 517, 525, 526, 531, 532, 533, 534, 545, 618, + 620, 637, 657, 664, 504, 404, 452, 476, 611, 0, + 0, 981, 982, 983, 984, 985, 986, 987, 988, 316, + 632, 665, 629, 677, 659, 461, 397, 0, 0, 400, + 297, 322, 339, 0, 649, 527, 236, 490, 306, 265, + 1056, 0, 219, 257, 239, 275, 290, 293, 343, 411, + 421, 451, 457, 312, 287, 255, 483, 252, 509, 548, + 549, 550, 552, 415, 282, 456, 0, 0, 395, 606, + 607, 335, 91, 557, 0, 809, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 438, 0, 0, 0, 796, + 0, 0, 0, 286, 801, 0, 0, 0, 385, 283, + 0, 0, 212, 530, 0, 453, 0, 211, 0, 511, + 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, + 450, 547, 444, 1768, 389, 0, 0, 522, 422, 0, + 0, 0, 0, 0, 0, 0, 0, 803, 804, 0, + 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, + 210, 435, 523, 302, 0, 101, 0, 0, 1057, 536, + 991, 780, 957, 995, 1058, 1009, 1010, 1011, 996, 0, + 249, 997, 998, 256, 999, 0, 956, 839, 841, 840, + 906, 907, 908, 909, 910, 911, 912, 842, 843, 837, + 1004, 641, 1012, 1013, 0, 281, 340, 288, 280, 612, + 0, 0, 0, 0, 0, 0, 628, 0, 0, 238, + 0, 0, 0, 0, 0, 0, 0, 776, 793, 0, + 807, 0, 0, 0, 0, 291, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, + 0, 0, 0, 790, 791, 0, 0, 0, 0, 951, + 0, 792, 0, 0, 800, 1014, 1015, 1016, 1017, 1018, + 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, + 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, + 1049, 1050, 1051, 1052, 1053, 1054, 1055, 802, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, + 423, 273, 0, 477, 0, 319, 334, 0, 0, 0, + 0, 0, 0, 0, 950, 0, 0, 661, 0, 0, + 948, 0, 0, 0, 0, 384, 0, 349, 205, 233, + 0, 0, 434, 485, 497, 0, 0, 0, 0, 1001, + 0, 495, 448, 636, 243, 300, 482, 455, 493, 463, + 303, 0, 0, 494, 391, 617, 473, 633, 662, 663, + 279, 428, 647, 551, 655, 680, 234, 276, 442, 535, + 639, 519, 417, 613, 614, 348, 518, 311, 209, 388, + 668, 232, 503, 390, 253, 241, 619, 644, 315, 267, + 305, 480, 675, 221, 546, 630, 250, 507, 0, 0, + 683, 258, 529, 642, 631, 223, 626, 528, 413, 345, + 346, 222, 0, 481, 284, 309, 0, 0, 274, 437, + 1002, 1003, 272, 684, 847, 654, 228, 0, 653, 430, + 616, 627, 414, 402, 227, 625, 412, 401, 353, 855, + 856, 296, 324, 932, 931, 930, 323, 325, 928, 929, + 927, 215, 640, 658, 0, 216, 0, 524, 643, 685, + 475, 220, 244, 245, 248, 0, 295, 299, 307, 310, + 320, 321, 331, 386, 441, 469, 465, 474, 0, 610, + 634, 648, 660, 666, 667, 669, 670, 671, 672, 673, + 676, 674, 429, 329, 520, 352, 392, 0, 0, 447, + 496, 251, 638, 521, 240, 604, 418, 427, 259, 261, + 260, 235, 512, 609, 246, 266, 938, 960, 949, 813, + 814, 939, 940, 964, 941, 816, 817, 961, 962, 810, + 811, 815, 963, 965, 686, 687, 688, 689, 690, 691, + 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, + 702, 703, 681, 537, 543, 538, 539, 540, 541, 542, + 0, 544, 952, 799, 798, 0, 805, 806, 0, 835, + 836, 838, 844, 845, 846, 857, 904, 905, 913, 915, + 916, 914, 917, 918, 919, 922, 923, 924, 925, 920, + 921, 926, 818, 822, 819, 820, 821, 833, 823, 824, + 825, 826, 827, 828, 829, 830, 831, 832, 834, 975, + 976, 977, 978, 979, 980, 850, 854, 853, 851, 852, + 848, 849, 876, 875, 877, 878, 879, 880, 881, 882, + 884, 883, 885, 886, 887, 888, 889, 890, 858, 859, + 862, 863, 861, 860, 864, 873, 874, 865, 866, 867, + 868, 869, 870, 872, 871, 891, 892, 893, 894, 895, + 897, 896, 900, 901, 899, 898, 903, 902, 797, 204, + 229, 387, 100, 478, 304, 682, 650, 508, 645, 214, + 231, 966, 278, 967, 0, 0, 971, 0, 0, 0, + 973, 972, 0, 974, 936, 935, 0, 0, 968, 969, + 0, 970, 0, 0, 206, 208, 217, 230, 242, 247, + 254, 277, 292, 294, 301, 314, 327, 328, 337, 338, + 341, 347, 399, 406, 407, 408, 409, 431, 432, 433, + 436, 439, 440, 443, 445, 446, 449, 454, 458, 459, + 460, 462, 464, 466, 479, 484, 498, 499, 500, 501, + 502, 505, 506, 513, 514, 515, 516, 517, 525, 526, + 531, 532, 533, 534, 545, 618, 620, 637, 657, 664, + 504, 404, 452, 476, 611, 0, 0, 981, 982, 983, + 984, 985, 986, 987, 988, 316, 632, 665, 629, 677, + 659, 461, 397, 0, 0, 400, 297, 322, 339, 0, + 649, 527, 236, 490, 306, 265, 1056, 0, 219, 257, + 239, 275, 290, 293, 343, 411, 421, 451, 457, 312, + 287, 255, 483, 252, 509, 548, 549, 550, 552, 415, + 282, 456, 0, 0, 395, 606, 607, 335, 557, 0, + 809, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 438, 0, 0, 0, 796, 0, 0, 0, 286, 801, + 0, 0, 0, 385, 283, 0, 0, 212, 530, 0, + 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, + 289, 285, 264, 336, 405, 450, 547, 444, 808, 389, + 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, + 0, 0, 803, 804, 0, 0, 0, 0, 0, 0, + 0, 0, 342, 262, 344, 210, 435, 523, 302, 0, + 101, 0, 0, 1057, 536, 991, 780, 957, 995, 1058, + 1009, 1010, 1011, 996, 0, 249, 997, 998, 256, 999, + 0, 956, 839, 841, 840, 906, 907, 908, 909, 910, + 911, 912, 842, 843, 837, 1004, 641, 1012, 1013, 0, + 281, 340, 288, 280, 612, 0, 0, 0, 0, 0, + 0, 628, 0, 0, 238, 0, 0, 0, 0, 0, + 0, 0, 776, 793, 0, 807, 0, 0, 0, 0, + 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 416, 0, 0, 0, 790, 791, + 0, 0, 0, 0, 951, 0, 792, 0, 0, 800, + 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, + 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, + 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, + 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 802, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 313, 0, 423, 273, 0, 477, 0, + 319, 334, 0, 0, 0, 0, 0, 0, 0, 950, + 0, 0, 661, 0, 0, 948, 0, 0, 0, 0, + 384, 0, 349, 205, 233, 0, 0, 434, 485, 497, + 0, 0, 0, 0, 1001, 0, 495, 448, 636, 243, + 300, 482, 455, 493, 463, 303, 4215, 0, 494, 391, 617, 473, 633, 662, 663, 279, 428, 647, 551, 655, 680, 234, 276, 442, 535, 639, 519, 417, 613, 614, 348, 518, 311, 209, 388, 668, 232, 503, 390, 253, 241, 619, 644, 315, 267, 305, 480, 675, 221, 546, 630, 250, 507, 0, 0, 683, 258, 529, 642, 631, 223, 626, 528, 413, 345, 346, 222, 0, 481, 284, - 309, 0, 0, 274, 437, 621, 622, 272, 684, 237, - 654, 228, 1335, 653, 430, 616, 627, 414, 402, 227, - 625, 412, 401, 353, 374, 375, 296, 324, 470, 394, - 471, 323, 325, 425, 424, 426, 215, 640, 658, 0, + 309, 0, 0, 274, 437, 1002, 1003, 272, 684, 847, + 654, 228, 0, 653, 430, 616, 627, 414, 402, 227, + 625, 412, 401, 353, 855, 856, 296, 324, 932, 931, + 930, 323, 325, 928, 929, 927, 215, 640, 658, 0, 216, 0, 524, 643, 685, 475, 220, 244, 245, 248, - 1353, 295, 299, 307, 310, 320, 321, 331, 386, 441, - 469, 465, 474, 1449, 610, 634, 648, 660, 666, 667, + 0, 295, 299, 307, 310, 320, 321, 331, 386, 441, + 469, 465, 474, 0, 610, 634, 648, 660, 666, 667, 669, 670, 671, 672, 673, 676, 674, 429, 329, 520, - 352, 392, 1438, 1486, 447, 496, 251, 638, 521, 240, + 352, 392, 0, 0, 447, 496, 251, 638, 521, 240, 604, 418, 427, 259, 261, 260, 235, 512, 609, 246, - 266, 207, 1347, 1352, 1345, 0, 270, 271, 1419, 605, - 1348, 1346, 1408, 1409, 1349, 1477, 1478, 1479, 1463, 686, + 266, 938, 960, 949, 813, 814, 939, 940, 964, 941, + 816, 817, 961, 962, 810, 811, 815, 963, 965, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 681, 537, 543, - 538, 539, 540, 541, 542, 0, 544, 1442, 1341, 0, - 1350, 1351, 419, 1451, 623, 624, 704, 403, 510, 635, - 354, 368, 371, 360, 380, 0, 381, 356, 357, 362, - 365, 366, 367, 372, 373, 377, 383, 263, 218, 410, - 420, 608, 330, 224, 225, 226, 553, 554, 555, 556, - 651, 652, 656, 213, 486, 487, 488, 489, 308, 646, - 326, 492, 491, 350, 351, 398, 472, 569, 571, 582, - 586, 588, 590, 596, 599, 570, 572, 583, 587, 589, - 591, 597, 600, 559, 561, 563, 565, 578, 577, 574, - 602, 603, 580, 585, 564, 576, 581, 594, 601, 598, - 558, 562, 566, 575, 593, 592, 573, 584, 595, 579, - 567, 560, 568, 1412, 204, 229, 387, 1482, 478, 304, - 682, 650, 508, 645, 214, 231, 1344, 278, 1357, 1366, - 0, 1373, 1381, 1382, 1396, 1399, 1400, 1401, 1402, 1420, - 1421, 1423, 1432, 1434, 1437, 1439, 1446, 1464, 1485, 206, + 538, 539, 540, 541, 542, 0, 544, 952, 799, 798, + 0, 805, 806, 0, 835, 836, 838, 844, 845, 846, + 857, 904, 905, 913, 915, 916, 914, 917, 918, 919, + 922, 923, 924, 925, 920, 921, 926, 818, 822, 819, + 820, 821, 833, 823, 824, 825, 826, 827, 828, 829, + 830, 831, 832, 834, 975, 976, 977, 978, 979, 980, + 850, 854, 853, 851, 852, 848, 849, 876, 875, 877, + 878, 879, 880, 881, 882, 884, 883, 885, 886, 887, + 888, 889, 890, 858, 859, 862, 863, 861, 860, 864, + 873, 874, 865, 866, 867, 868, 869, 870, 872, 871, + 891, 892, 893, 894, 895, 897, 896, 900, 901, 899, + 898, 903, 902, 797, 204, 229, 387, 0, 478, 304, + 682, 650, 508, 645, 214, 231, 966, 278, 967, 0, + 0, 971, 0, 0, 0, 973, 972, 0, 974, 936, + 935, 0, 0, 968, 969, 0, 970, 0, 0, 206, 208, 217, 230, 242, 247, 254, 277, 292, 294, 301, 314, 327, 328, 337, 338, 341, 347, 399, 406, 407, 408, 409, 431, 432, 433, 436, 439, 440, 443, 445, @@ -3799,12 +4086,12 @@ var yyAct = [...]int{ 484, 498, 499, 500, 501, 502, 505, 506, 513, 514, 515, 516, 517, 525, 526, 531, 532, 533, 534, 545, 618, 620, 637, 657, 664, 504, 404, 452, 476, 611, - 1429, 1390, 317, 318, 467, 468, 332, 333, 678, 679, - 316, 632, 665, 629, 677, 659, 461, 397, 1411, 1417, - 400, 297, 322, 339, 1426, 649, 527, 236, 490, 306, - 265, 1445, 1447, 219, 257, 239, 275, 290, 293, 343, + 0, 0, 981, 982, 983, 984, 985, 986, 987, 988, + 316, 632, 665, 629, 677, 659, 461, 397, 0, 0, + 400, 297, 322, 339, 0, 649, 527, 236, 490, 306, + 265, 1056, 0, 219, 257, 239, 275, 290, 293, 343, 411, 421, 451, 457, 312, 287, 255, 483, 252, 509, - 548, 549, 550, 552, 415, 282, 456, 1407, 1436, 395, + 548, 549, 550, 552, 415, 282, 456, 0, 0, 395, 606, 607, 335, 557, 0, 809, 0, 0, 0, 0, 0, 0, 0, 0, 0, 438, 0, 0, 0, 796, 0, 0, 0, 286, 801, 0, 0, 0, 385, 283, @@ -3813,12 +4100,12 @@ var yyAct = [...]int{ 450, 547, 444, 808, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 803, 804, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, - 210, 435, 523, 302, 0, 101, 0, 0, 1057, 536, + 210, 435, 523, 302, 0, 101, 0, 1805, 1057, 536, 991, 780, 957, 995, 1058, 1009, 1010, 1011, 996, 0, 249, 997, 998, 256, 999, 0, 956, 839, 841, 840, 906, 907, 908, 909, 910, 911, 912, 842, 843, 837, 1004, 641, 1012, 1013, 0, 281, 340, 288, 280, 612, - 0, 0, 2294, 2295, 2296, 0, 628, 0, 0, 238, + 0, 0, 0, 0, 0, 0, 628, 0, 0, 238, 0, 0, 0, 0, 0, 0, 0, 776, 793, 0, 807, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, @@ -3890,17 +4177,17 @@ var yyAct = [...]int{ 289, 285, 264, 336, 405, 450, 547, 444, 808, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 803, 804, 0, 0, 0, 0, 0, 0, - 2515, 0, 342, 262, 344, 210, 435, 523, 302, 0, + 0, 0, 342, 262, 344, 210, 435, 523, 302, 0, 101, 0, 0, 1057, 536, 991, 780, 957, 995, 1058, 1009, 1010, 1011, 996, 0, 249, 997, 998, 256, 999, 0, 956, 839, 841, 840, 906, 907, 908, 909, 910, - 911, 912, 842, 843, 837, 1004, 641, 1012, 1013, 2516, + 911, 912, 842, 843, 837, 1004, 641, 1012, 1013, 0, 281, 340, 288, 280, 612, 0, 0, 0, 0, 0, 0, 628, 0, 0, 238, 0, 0, 0, 0, 0, 0, 0, 776, 793, 0, 807, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, 0, 0, 0, 790, 791, - 0, 0, 0, 0, 951, 0, 792, 0, 0, 800, + 2450, 0, 0, 0, 951, 0, 792, 0, 0, 800, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, @@ -3960,809 +4247,422 @@ var yyAct = [...]int{ 265, 1056, 0, 219, 257, 239, 275, 290, 293, 343, 411, 421, 451, 457, 312, 287, 255, 483, 252, 509, 548, 549, 550, 552, 415, 282, 456, 0, 0, 395, - 606, 607, 335, 91, 557, 0, 809, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 438, 0, 0, 0, - 796, 0, 0, 0, 286, 801, 0, 0, 0, 385, - 283, 0, 0, 212, 530, 0, 453, 0, 211, 0, - 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, - 405, 450, 547, 444, 1767, 389, 0, 0, 522, 422, - 0, 0, 0, 0, 0, 0, 0, 0, 803, 804, - 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, - 344, 210, 435, 523, 302, 0, 101, 0, 0, 1057, - 536, 991, 780, 957, 995, 1058, 1009, 1010, 1011, 996, - 0, 249, 997, 998, 256, 999, 0, 956, 839, 841, - 840, 906, 907, 908, 909, 910, 911, 912, 842, 843, - 837, 1004, 641, 1012, 1013, 0, 281, 340, 288, 280, - 612, 0, 0, 0, 0, 0, 0, 628, 0, 0, - 238, 0, 0, 0, 0, 0, 0, 0, 776, 793, - 0, 807, 0, 0, 0, 0, 291, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 416, 0, 0, 0, 790, 791, 0, 0, 0, 0, - 951, 0, 792, 0, 0, 800, 1014, 1015, 1016, 1017, - 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, - 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, - 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, - 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 802, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, - 0, 423, 273, 0, 477, 0, 319, 334, 0, 0, - 0, 0, 0, 0, 0, 950, 0, 0, 661, 0, - 0, 948, 0, 0, 0, 0, 384, 0, 349, 205, - 233, 0, 0, 434, 485, 497, 0, 0, 0, 0, - 1001, 0, 495, 448, 636, 243, 300, 482, 455, 493, - 463, 303, 0, 0, 494, 391, 617, 473, 633, 662, - 663, 279, 428, 647, 551, 655, 680, 234, 276, 442, - 535, 639, 519, 417, 613, 614, 348, 518, 311, 209, - 388, 668, 232, 503, 390, 253, 241, 619, 644, 315, - 267, 305, 480, 675, 221, 546, 630, 250, 507, 0, - 0, 683, 258, 529, 642, 631, 223, 626, 528, 413, - 345, 346, 222, 0, 481, 284, 309, 0, 0, 274, - 437, 1002, 1003, 272, 684, 847, 654, 228, 0, 653, - 430, 616, 627, 414, 402, 227, 625, 412, 401, 353, - 855, 856, 296, 324, 932, 931, 930, 323, 325, 928, - 929, 927, 215, 640, 658, 0, 216, 0, 524, 643, - 685, 475, 220, 244, 245, 248, 0, 295, 299, 307, - 310, 320, 321, 331, 386, 441, 469, 465, 474, 0, - 610, 634, 648, 660, 666, 667, 669, 670, 671, 672, - 673, 676, 674, 429, 329, 520, 352, 392, 0, 0, - 447, 496, 251, 638, 521, 240, 604, 418, 427, 259, - 261, 260, 235, 512, 609, 246, 266, 938, 960, 949, - 813, 814, 939, 940, 964, 941, 816, 817, 961, 962, - 810, 811, 815, 963, 965, 686, 687, 688, 689, 690, - 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, - 701, 702, 703, 681, 537, 543, 538, 539, 540, 541, - 542, 0, 544, 952, 799, 798, 0, 805, 806, 0, - 835, 836, 838, 844, 845, 846, 857, 904, 905, 913, - 915, 916, 914, 917, 918, 919, 922, 923, 924, 925, - 920, 921, 926, 818, 822, 819, 820, 821, 833, 823, - 824, 825, 826, 827, 828, 829, 830, 831, 832, 834, - 975, 976, 977, 978, 979, 980, 850, 854, 853, 851, - 852, 848, 849, 876, 875, 877, 878, 879, 880, 881, - 882, 884, 883, 885, 886, 887, 888, 889, 890, 858, - 859, 862, 863, 861, 860, 864, 873, 874, 865, 866, - 867, 868, 869, 870, 872, 871, 891, 892, 893, 894, - 895, 897, 896, 900, 901, 899, 898, 903, 902, 797, - 204, 229, 387, 100, 478, 304, 682, 650, 508, 645, - 214, 231, 966, 278, 967, 0, 0, 971, 0, 0, - 0, 973, 972, 0, 974, 936, 935, 0, 0, 968, - 969, 0, 970, 0, 0, 206, 208, 217, 230, 242, - 247, 254, 277, 292, 294, 301, 314, 327, 328, 337, - 338, 341, 347, 399, 406, 407, 408, 409, 431, 432, - 433, 436, 439, 440, 443, 445, 446, 449, 454, 458, - 459, 460, 462, 464, 466, 479, 484, 498, 499, 500, - 501, 502, 505, 506, 513, 514, 515, 516, 517, 525, - 526, 531, 532, 533, 534, 545, 618, 620, 637, 657, - 664, 504, 404, 452, 476, 611, 0, 0, 981, 982, - 983, 984, 985, 986, 987, 988, 316, 632, 665, 629, - 677, 659, 461, 397, 0, 0, 400, 297, 322, 339, - 0, 649, 527, 236, 490, 306, 265, 1056, 0, 219, - 257, 239, 275, 290, 293, 343, 411, 421, 451, 457, - 312, 287, 255, 483, 252, 509, 548, 549, 550, 552, - 415, 282, 456, 0, 0, 395, 606, 607, 335, 557, - 0, 809, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 438, 0, 0, 0, 796, 0, 0, 0, 286, - 801, 0, 0, 0, 385, 283, 0, 0, 212, 530, - 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, - 298, 289, 285, 264, 336, 405, 450, 547, 444, 808, - 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, - 0, 0, 0, 803, 804, 0, 0, 0, 0, 0, - 0, 0, 0, 342, 262, 344, 210, 435, 523, 302, - 0, 101, 0, 0, 1057, 536, 991, 780, 957, 995, - 1058, 1009, 1010, 1011, 996, 0, 249, 997, 998, 256, - 999, 0, 956, 839, 841, 840, 906, 907, 908, 909, - 910, 911, 912, 842, 843, 837, 1004, 641, 1012, 1013, - 0, 281, 340, 288, 280, 612, 0, 0, 0, 0, - 0, 0, 628, 0, 0, 238, 0, 0, 0, 0, - 0, 0, 0, 776, 793, 0, 807, 0, 0, 0, - 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 416, 0, 0, 0, 790, - 791, 0, 0, 0, 0, 951, 0, 792, 0, 0, - 800, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, - 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, - 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, - 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, - 1053, 1054, 1055, 802, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 313, 0, 423, 273, 0, 477, - 0, 319, 334, 0, 0, 0, 0, 0, 0, 0, - 950, 0, 0, 661, 0, 0, 948, 0, 0, 0, - 0, 384, 0, 349, 205, 233, 0, 0, 434, 485, - 497, 0, 0, 0, 0, 1001, 0, 495, 448, 636, - 243, 300, 482, 455, 493, 463, 303, 4207, 0, 494, - 391, 617, 473, 633, 662, 663, 279, 428, 647, 551, - 655, 680, 234, 276, 442, 535, 639, 519, 417, 613, - 614, 348, 518, 311, 209, 388, 668, 232, 503, 390, - 253, 241, 619, 644, 315, 267, 305, 480, 675, 221, - 546, 630, 250, 507, 0, 0, 683, 258, 529, 642, - 631, 223, 626, 528, 413, 345, 346, 222, 0, 481, - 284, 309, 0, 0, 274, 437, 1002, 1003, 272, 684, - 847, 654, 228, 0, 653, 430, 616, 627, 414, 402, - 227, 625, 412, 401, 353, 855, 856, 296, 324, 932, - 931, 930, 323, 325, 928, 929, 927, 215, 640, 658, - 0, 216, 0, 524, 643, 685, 475, 220, 244, 245, - 248, 0, 295, 299, 307, 310, 320, 321, 331, 386, - 441, 469, 465, 474, 0, 610, 634, 648, 660, 666, - 667, 669, 670, 671, 672, 673, 676, 674, 429, 329, - 520, 352, 392, 0, 0, 447, 496, 251, 638, 521, - 240, 604, 418, 427, 259, 261, 260, 235, 512, 609, - 246, 266, 938, 960, 949, 813, 814, 939, 940, 964, - 941, 816, 817, 961, 962, 810, 811, 815, 963, 965, - 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, - 696, 697, 698, 699, 700, 701, 702, 703, 681, 537, - 543, 538, 539, 540, 541, 542, 0, 544, 952, 799, - 798, 0, 805, 806, 0, 835, 836, 838, 844, 845, - 846, 857, 904, 905, 913, 915, 916, 914, 917, 918, - 919, 922, 923, 924, 925, 920, 921, 926, 818, 822, - 819, 820, 821, 833, 823, 824, 825, 826, 827, 828, - 829, 830, 831, 832, 834, 975, 976, 977, 978, 979, - 980, 850, 854, 853, 851, 852, 848, 849, 876, 875, - 877, 878, 879, 880, 881, 882, 884, 883, 885, 886, - 887, 888, 889, 890, 858, 859, 862, 863, 861, 860, - 864, 873, 874, 865, 866, 867, 868, 869, 870, 872, - 871, 891, 892, 893, 894, 895, 897, 896, 900, 901, - 899, 898, 903, 902, 797, 204, 229, 387, 0, 478, - 304, 682, 650, 508, 645, 214, 231, 966, 278, 967, - 0, 0, 971, 0, 0, 0, 973, 972, 0, 974, - 936, 935, 0, 0, 968, 969, 0, 970, 0, 0, - 206, 208, 217, 230, 242, 247, 254, 277, 292, 294, - 301, 314, 327, 328, 337, 338, 341, 347, 399, 406, - 407, 408, 409, 431, 432, 433, 436, 439, 440, 443, - 445, 446, 449, 454, 458, 459, 460, 462, 464, 466, - 479, 484, 498, 499, 500, 501, 502, 505, 506, 513, - 514, 515, 516, 517, 525, 526, 531, 532, 533, 534, - 545, 618, 620, 637, 657, 664, 504, 404, 452, 476, - 611, 0, 0, 981, 982, 983, 984, 985, 986, 987, - 988, 316, 632, 665, 629, 677, 659, 461, 397, 0, - 0, 400, 297, 322, 339, 0, 649, 527, 236, 490, - 306, 265, 1056, 0, 219, 257, 239, 275, 290, 293, - 343, 411, 421, 451, 457, 312, 287, 255, 483, 252, - 509, 548, 549, 550, 552, 415, 282, 456, 0, 0, - 395, 606, 607, 335, 557, 0, 809, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 438, 0, 0, 0, - 796, 0, 0, 0, 286, 801, 0, 0, 0, 385, - 283, 0, 0, 212, 530, 0, 453, 0, 211, 0, - 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, - 405, 450, 547, 444, 808, 389, 0, 0, 522, 422, - 0, 0, 0, 0, 0, 0, 0, 0, 803, 804, - 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, - 344, 210, 435, 523, 302, 0, 101, 0, 1804, 1057, - 536, 991, 780, 957, 995, 1058, 1009, 1010, 1011, 996, - 0, 249, 997, 998, 256, 999, 0, 956, 839, 841, - 840, 906, 907, 908, 909, 910, 911, 912, 842, 843, - 837, 1004, 641, 1012, 1013, 0, 281, 340, 288, 280, - 612, 0, 0, 0, 0, 0, 0, 628, 0, 0, - 238, 0, 0, 0, 0, 0, 0, 0, 776, 793, - 0, 807, 0, 0, 0, 0, 291, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 416, 0, 0, 0, 790, 791, 0, 0, 0, 0, - 951, 0, 792, 0, 0, 800, 1014, 1015, 1016, 1017, - 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, - 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, - 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, - 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 802, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, - 0, 423, 273, 0, 477, 0, 319, 334, 0, 0, - 0, 0, 0, 0, 0, 950, 0, 0, 661, 0, - 0, 948, 0, 0, 0, 0, 384, 0, 349, 205, - 233, 0, 0, 434, 485, 497, 0, 0, 0, 0, - 1001, 0, 495, 448, 636, 243, 300, 482, 455, 493, - 463, 303, 0, 0, 494, 391, 617, 473, 633, 662, - 663, 279, 428, 647, 551, 655, 680, 234, 276, 442, - 535, 639, 519, 417, 613, 614, 348, 518, 311, 209, - 388, 668, 232, 503, 390, 253, 241, 619, 644, 315, - 267, 305, 480, 675, 221, 546, 630, 250, 507, 0, - 0, 683, 258, 529, 642, 631, 223, 626, 528, 413, - 345, 346, 222, 0, 481, 284, 309, 0, 0, 274, - 437, 1002, 1003, 272, 684, 847, 654, 228, 0, 653, - 430, 616, 627, 414, 402, 227, 625, 412, 401, 353, - 855, 856, 296, 324, 932, 931, 930, 323, 325, 928, - 929, 927, 215, 640, 658, 0, 216, 0, 524, 643, - 685, 475, 220, 244, 245, 248, 0, 295, 299, 307, - 310, 320, 321, 331, 386, 441, 469, 465, 474, 0, - 610, 634, 648, 660, 666, 667, 669, 670, 671, 672, - 673, 676, 674, 429, 329, 520, 352, 392, 0, 0, - 447, 496, 251, 638, 521, 240, 604, 418, 427, 259, - 261, 260, 235, 512, 609, 246, 266, 938, 960, 949, - 813, 814, 939, 940, 964, 941, 816, 817, 961, 962, - 810, 811, 815, 963, 965, 686, 687, 688, 689, 690, - 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, - 701, 702, 703, 681, 537, 543, 538, 539, 540, 541, - 542, 0, 544, 952, 799, 798, 0, 805, 806, 0, - 835, 836, 838, 844, 845, 846, 857, 904, 905, 913, - 915, 916, 914, 917, 918, 919, 922, 923, 924, 925, - 920, 921, 926, 818, 822, 819, 820, 821, 833, 823, - 824, 825, 826, 827, 828, 829, 830, 831, 832, 834, - 975, 976, 977, 978, 979, 980, 850, 854, 853, 851, - 852, 848, 849, 876, 875, 877, 878, 879, 880, 881, - 882, 884, 883, 885, 886, 887, 888, 889, 890, 858, - 859, 862, 863, 861, 860, 864, 873, 874, 865, 866, - 867, 868, 869, 870, 872, 871, 891, 892, 893, 894, - 895, 897, 896, 900, 901, 899, 898, 903, 902, 797, - 204, 229, 387, 0, 478, 304, 682, 650, 508, 645, - 214, 231, 966, 278, 967, 0, 0, 971, 0, 0, - 0, 973, 972, 0, 974, 936, 935, 0, 0, 968, - 969, 0, 970, 0, 0, 206, 208, 217, 230, 242, - 247, 254, 277, 292, 294, 301, 314, 327, 328, 337, - 338, 341, 347, 399, 406, 407, 408, 409, 431, 432, - 433, 436, 439, 440, 443, 445, 446, 449, 454, 458, - 459, 460, 462, 464, 466, 479, 484, 498, 499, 500, - 501, 502, 505, 506, 513, 514, 515, 516, 517, 525, - 526, 531, 532, 533, 534, 545, 618, 620, 637, 657, - 664, 504, 404, 452, 476, 611, 0, 0, 981, 982, - 983, 984, 985, 986, 987, 988, 316, 632, 665, 629, - 677, 659, 461, 397, 0, 0, 400, 297, 322, 339, - 0, 649, 527, 236, 490, 306, 265, 1056, 0, 219, - 257, 239, 275, 290, 293, 343, 411, 421, 451, 457, - 312, 287, 255, 483, 252, 509, 548, 549, 550, 552, - 415, 282, 456, 0, 0, 395, 606, 607, 335, 557, - 0, 809, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 438, 0, 0, 0, 796, 0, 0, 0, 286, - 801, 0, 0, 0, 385, 283, 0, 0, 212, 530, - 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, - 298, 289, 285, 264, 336, 405, 450, 547, 444, 808, - 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, - 0, 0, 0, 803, 804, 0, 0, 0, 0, 0, - 0, 0, 0, 342, 262, 344, 210, 435, 523, 302, - 0, 101, 0, 0, 1057, 536, 991, 780, 957, 995, - 1058, 1009, 1010, 1011, 996, 0, 249, 997, 998, 256, - 999, 0, 956, 839, 841, 840, 906, 907, 908, 909, - 910, 911, 912, 842, 843, 837, 1004, 641, 1012, 1013, - 0, 281, 340, 288, 280, 612, 0, 0, 0, 0, - 0, 0, 628, 0, 0, 238, 0, 0, 0, 0, - 0, 0, 0, 776, 793, 0, 807, 0, 0, 0, - 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 416, 0, 0, 0, 790, - 791, 1110, 0, 0, 0, 951, 0, 792, 0, 0, - 800, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, - 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, - 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, - 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, - 1053, 1054, 1055, 802, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 313, 0, 423, 273, 0, 477, - 0, 319, 334, 0, 0, 0, 0, 0, 0, 0, - 950, 0, 0, 661, 0, 0, 948, 0, 0, 0, - 0, 384, 0, 349, 205, 233, 0, 0, 434, 485, - 497, 0, 0, 0, 0, 1001, 0, 495, 448, 636, - 243, 300, 482, 455, 493, 463, 303, 0, 0, 494, - 391, 617, 473, 633, 662, 663, 279, 428, 647, 551, - 655, 680, 234, 276, 442, 535, 639, 519, 417, 613, - 614, 348, 518, 311, 209, 388, 668, 232, 503, 390, - 253, 241, 619, 644, 315, 267, 305, 480, 675, 221, - 546, 630, 250, 507, 0, 0, 683, 258, 529, 642, - 631, 223, 626, 528, 413, 345, 346, 222, 0, 481, - 284, 309, 0, 0, 274, 437, 1002, 1003, 272, 684, - 847, 654, 228, 0, 653, 430, 616, 627, 414, 402, - 227, 625, 412, 401, 353, 855, 856, 296, 324, 932, - 931, 930, 323, 325, 928, 929, 927, 215, 640, 658, - 0, 216, 0, 524, 643, 685, 475, 220, 244, 245, - 248, 0, 295, 299, 307, 310, 320, 321, 331, 386, - 441, 469, 465, 474, 0, 610, 634, 648, 660, 666, - 667, 669, 670, 671, 672, 673, 676, 674, 429, 329, - 520, 352, 392, 0, 0, 447, 496, 251, 638, 521, - 240, 604, 418, 427, 259, 261, 260, 235, 512, 609, - 246, 266, 938, 960, 949, 813, 814, 939, 940, 964, - 941, 816, 817, 961, 962, 810, 811, 815, 963, 965, - 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, - 696, 697, 698, 699, 700, 701, 702, 703, 681, 537, - 543, 538, 539, 540, 541, 542, 0, 544, 952, 799, - 798, 0, 805, 806, 0, 835, 836, 838, 844, 845, - 846, 857, 904, 905, 913, 915, 916, 914, 917, 918, - 919, 922, 923, 924, 925, 920, 921, 926, 818, 822, - 819, 820, 821, 833, 823, 824, 825, 826, 827, 828, - 829, 830, 831, 832, 834, 975, 976, 977, 978, 979, - 980, 850, 854, 853, 851, 852, 848, 849, 876, 875, - 877, 878, 879, 880, 881, 882, 884, 883, 885, 886, - 887, 888, 889, 890, 858, 859, 862, 863, 861, 860, - 864, 873, 874, 865, 866, 867, 868, 869, 870, 872, - 871, 891, 892, 893, 894, 895, 897, 896, 900, 901, - 899, 898, 903, 902, 797, 204, 229, 387, 0, 478, - 304, 682, 650, 508, 645, 214, 231, 966, 278, 967, - 0, 0, 971, 0, 0, 0, 973, 972, 0, 974, - 936, 935, 0, 0, 968, 969, 0, 970, 0, 0, - 206, 208, 217, 230, 242, 247, 254, 277, 292, 294, - 301, 314, 327, 328, 337, 338, 341, 347, 399, 406, - 407, 408, 409, 431, 432, 433, 436, 439, 440, 443, - 445, 446, 449, 454, 458, 459, 460, 462, 464, 466, - 479, 484, 498, 499, 500, 501, 502, 505, 506, 513, - 514, 515, 516, 517, 525, 526, 531, 532, 533, 534, - 545, 618, 620, 637, 657, 664, 504, 404, 452, 476, - 611, 0, 0, 981, 982, 983, 984, 985, 986, 987, - 988, 316, 632, 665, 629, 677, 659, 461, 397, 0, - 0, 400, 297, 322, 339, 0, 649, 527, 236, 490, - 306, 265, 1056, 0, 219, 257, 239, 275, 290, 293, - 343, 411, 421, 451, 457, 312, 287, 255, 483, 252, - 509, 548, 549, 550, 552, 415, 282, 456, 0, 0, - 395, 606, 607, 335, 557, 0, 809, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 438, 0, 0, 0, - 796, 0, 0, 0, 286, 801, 0, 0, 0, 385, - 283, 0, 0, 212, 530, 0, 453, 0, 211, 0, - 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, - 405, 450, 547, 444, 808, 389, 0, 0, 522, 422, - 0, 0, 0, 0, 0, 0, 0, 0, 803, 804, - 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, - 344, 210, 435, 523, 302, 0, 101, 0, 0, 1057, - 536, 991, 780, 957, 995, 1058, 1009, 1010, 1011, 996, - 0, 249, 997, 998, 256, 999, 0, 956, 839, 841, - 840, 906, 907, 908, 909, 910, 911, 912, 842, 843, - 837, 1004, 641, 1012, 1013, 0, 281, 340, 288, 280, - 612, 0, 0, 0, 0, 0, 0, 628, 0, 0, - 238, 0, 0, 0, 0, 0, 0, 0, 776, 793, - 0, 807, 0, 0, 0, 0, 291, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 416, 0, 0, 0, 790, 791, 0, 0, 0, 0, - 951, 0, 792, 0, 0, 800, 1014, 1015, 1016, 1017, - 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, - 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, - 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, - 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 802, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, - 0, 423, 273, 0, 477, 0, 319, 334, 0, 0, - 0, 0, 0, 0, 0, 950, 0, 0, 661, 0, - 0, 948, 0, 0, 0, 0, 384, 0, 349, 205, - 233, 0, 0, 434, 485, 497, 0, 0, 0, 0, - 1001, 0, 495, 448, 636, 243, 300, 482, 455, 493, - 463, 303, 0, 0, 494, 391, 617, 473, 633, 662, - 663, 279, 428, 647, 551, 655, 680, 234, 276, 442, - 535, 639, 519, 417, 613, 614, 348, 518, 311, 209, - 388, 668, 232, 503, 390, 253, 241, 619, 644, 315, - 267, 305, 480, 675, 221, 546, 630, 250, 507, 0, - 0, 683, 258, 529, 642, 631, 223, 626, 528, 413, - 345, 346, 222, 0, 481, 284, 309, 0, 0, 274, - 437, 1002, 1003, 272, 684, 847, 654, 228, 0, 653, - 430, 616, 627, 414, 402, 227, 625, 412, 401, 353, - 855, 856, 296, 324, 932, 931, 930, 323, 325, 928, - 929, 927, 215, 640, 658, 0, 216, 0, 524, 643, - 685, 475, 220, 244, 245, 248, 0, 295, 299, 307, - 310, 320, 321, 331, 386, 441, 469, 465, 474, 0, - 610, 634, 648, 660, 666, 667, 669, 670, 671, 672, - 673, 676, 674, 429, 329, 520, 352, 392, 0, 0, - 447, 496, 251, 638, 521, 240, 604, 418, 427, 259, - 261, 260, 235, 512, 609, 246, 266, 938, 960, 949, - 813, 814, 939, 940, 964, 941, 816, 817, 961, 962, - 810, 811, 815, 963, 965, 686, 687, 688, 689, 690, - 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, - 701, 702, 703, 681, 537, 543, 538, 539, 540, 541, - 542, 0, 544, 952, 799, 798, 0, 805, 806, 0, - 835, 836, 838, 844, 845, 846, 857, 904, 905, 913, - 915, 916, 914, 917, 918, 919, 922, 923, 924, 925, - 920, 921, 926, 818, 822, 819, 820, 821, 833, 823, - 824, 825, 826, 827, 828, 829, 830, 831, 832, 834, - 975, 976, 977, 978, 979, 980, 850, 854, 853, 851, - 852, 848, 849, 876, 875, 877, 878, 879, 880, 881, - 882, 884, 883, 885, 886, 887, 888, 889, 890, 858, - 859, 862, 863, 861, 860, 864, 873, 874, 865, 866, - 867, 868, 869, 870, 872, 871, 891, 892, 893, 894, - 895, 897, 896, 900, 901, 899, 898, 903, 902, 797, - 204, 229, 387, 0, 478, 304, 682, 650, 508, 645, - 214, 231, 966, 278, 967, 0, 0, 971, 0, 0, - 0, 973, 972, 0, 974, 936, 935, 0, 0, 968, - 969, 0, 970, 0, 0, 206, 208, 217, 230, 242, - 247, 254, 277, 292, 294, 301, 314, 327, 328, 337, - 338, 341, 347, 399, 406, 407, 408, 409, 431, 432, - 433, 436, 439, 440, 443, 445, 446, 449, 454, 458, - 459, 460, 462, 464, 466, 479, 484, 498, 499, 500, - 501, 502, 505, 506, 513, 514, 515, 516, 517, 525, - 526, 531, 532, 533, 534, 545, 618, 620, 637, 657, - 664, 504, 404, 452, 476, 611, 0, 0, 981, 982, - 983, 984, 985, 986, 987, 988, 316, 632, 665, 629, - 677, 659, 461, 397, 0, 0, 400, 297, 322, 339, - 0, 649, 527, 236, 490, 306, 265, 1056, 0, 219, - 257, 239, 275, 290, 293, 343, 411, 421, 451, 457, - 312, 287, 255, 483, 252, 509, 548, 549, 550, 552, - 415, 282, 456, 0, 0, 395, 606, 607, 335, 557, - 0, 809, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 438, 0, 0, 0, 796, 0, 0, 0, 286, - 801, 0, 0, 0, 385, 283, 0, 0, 212, 530, - 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, - 298, 289, 285, 264, 336, 405, 450, 547, 444, 808, - 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, - 0, 0, 0, 803, 804, 0, 0, 0, 0, 0, - 0, 0, 0, 342, 262, 344, 210, 435, 523, 302, - 0, 101, 0, 0, 1057, 536, 991, 780, 957, 995, - 1058, 1009, 1010, 1011, 996, 0, 249, 997, 998, 256, - 999, 0, 956, 839, 841, 840, 906, 907, 908, 909, - 910, 911, 912, 842, 843, 837, 1004, 641, 1012, 1013, - 0, 281, 340, 288, 280, 612, 0, 0, 0, 0, - 0, 0, 628, 0, 0, 238, 0, 0, 0, 0, - 0, 0, 0, 776, 793, 0, 807, 0, 0, 0, - 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 416, 0, 0, 0, 790, - 791, 0, 0, 0, 0, 951, 0, 792, 0, 0, - 800, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, - 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, - 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, - 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, - 1053, 1054, 1055, 3252, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 313, 0, 423, 273, 0, 477, - 0, 319, 334, 0, 0, 0, 0, 0, 0, 0, - 950, 0, 0, 661, 0, 0, 948, 0, 0, 0, - 0, 384, 0, 349, 205, 233, 0, 0, 434, 485, - 497, 0, 0, 0, 0, 1001, 0, 495, 448, 636, - 243, 300, 482, 455, 493, 463, 303, 0, 0, 494, - 391, 617, 473, 633, 662, 663, 279, 428, 647, 551, - 655, 680, 234, 276, 442, 535, 639, 519, 417, 613, - 614, 348, 518, 311, 209, 388, 668, 232, 503, 390, - 253, 241, 619, 644, 315, 267, 305, 480, 675, 221, - 546, 630, 250, 507, 0, 0, 683, 258, 529, 642, - 631, 223, 626, 528, 413, 345, 346, 222, 0, 481, - 284, 309, 0, 0, 274, 437, 1002, 1003, 272, 684, - 847, 654, 228, 0, 653, 430, 616, 627, 414, 402, - 227, 625, 412, 401, 353, 855, 856, 296, 324, 932, - 931, 930, 323, 325, 928, 929, 927, 215, 640, 658, - 0, 216, 0, 524, 643, 685, 475, 220, 244, 245, - 248, 0, 295, 299, 307, 310, 320, 321, 331, 386, - 441, 469, 465, 474, 0, 610, 634, 648, 660, 666, - 667, 669, 670, 671, 672, 673, 676, 674, 429, 329, - 520, 352, 392, 0, 0, 447, 496, 251, 638, 521, - 240, 604, 418, 427, 259, 261, 260, 235, 512, 609, - 246, 266, 938, 960, 949, 813, 814, 939, 940, 964, - 941, 816, 817, 961, 962, 810, 811, 815, 963, 965, - 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, - 696, 697, 698, 699, 700, 701, 702, 703, 681, 537, - 543, 538, 539, 540, 541, 542, 0, 544, 952, 799, - 798, 0, 805, 806, 0, 835, 836, 838, 844, 845, - 846, 857, 904, 905, 913, 915, 916, 914, 917, 918, - 919, 922, 923, 924, 925, 920, 921, 926, 818, 822, - 819, 820, 821, 833, 823, 824, 825, 826, 827, 828, - 829, 830, 831, 832, 834, 975, 976, 977, 978, 979, - 980, 850, 854, 853, 851, 852, 848, 849, 876, 875, - 877, 878, 879, 880, 881, 882, 884, 883, 885, 886, - 887, 888, 889, 890, 858, 859, 862, 863, 861, 860, - 864, 873, 874, 865, 866, 867, 868, 869, 870, 872, - 871, 891, 892, 893, 894, 895, 897, 896, 900, 901, - 899, 898, 903, 902, 797, 204, 229, 387, 0, 478, - 304, 682, 650, 508, 645, 214, 231, 966, 278, 967, - 0, 0, 971, 0, 0, 0, 973, 972, 0, 974, - 936, 935, 0, 0, 968, 969, 0, 970, 0, 0, - 206, 208, 217, 230, 242, 247, 254, 277, 292, 294, - 301, 314, 327, 328, 337, 338, 341, 347, 399, 406, - 407, 408, 409, 431, 432, 433, 436, 439, 440, 443, - 445, 446, 449, 454, 458, 459, 460, 462, 464, 466, - 479, 484, 498, 499, 500, 501, 502, 505, 506, 513, - 514, 515, 516, 517, 525, 526, 531, 532, 533, 534, - 545, 618, 620, 637, 657, 664, 504, 404, 452, 476, - 611, 0, 0, 981, 982, 983, 984, 985, 986, 987, - 988, 316, 632, 665, 629, 677, 659, 461, 397, 0, - 0, 400, 297, 322, 339, 0, 649, 527, 236, 490, - 306, 265, 1056, 0, 219, 257, 239, 275, 290, 293, - 343, 411, 421, 451, 457, 312, 287, 255, 483, 252, - 509, 548, 549, 550, 552, 415, 282, 456, 0, 0, - 395, 606, 607, 335, 557, 0, 809, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 438, 0, 0, 0, - 796, 0, 0, 0, 286, 801, 0, 0, 0, 385, - 283, 0, 0, 212, 530, 0, 453, 0, 211, 0, - 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, - 405, 450, 547, 444, 808, 389, 0, 0, 522, 422, - 0, 0, 0, 0, 0, 0, 0, 0, 803, 804, - 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, - 344, 210, 435, 523, 302, 0, 101, 0, 0, 1057, - 536, 991, 780, 957, 995, 1058, 1009, 1010, 1011, 996, - 0, 249, 997, 998, 256, 999, 0, 956, 839, 841, - 840, 906, 907, 908, 909, 910, 911, 912, 842, 843, - 837, 1004, 641, 1012, 1013, 0, 281, 340, 288, 280, - 612, 0, 0, 0, 0, 0, 0, 628, 0, 0, - 238, 0, 0, 0, 0, 0, 0, 0, 776, 793, - 0, 807, 0, 0, 0, 0, 291, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 416, 0, 0, 0, 790, 791, 0, 0, 0, 0, - 951, 0, 792, 0, 0, 800, 1014, 1015, 1016, 1017, - 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, - 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, - 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, - 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 3248, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, - 0, 423, 273, 0, 477, 0, 319, 334, 0, 0, - 0, 0, 0, 0, 0, 950, 0, 0, 661, 0, - 0, 948, 0, 0, 0, 0, 384, 0, 349, 205, - 233, 0, 0, 434, 485, 497, 0, 0, 0, 0, - 1001, 0, 495, 448, 636, 243, 300, 482, 455, 493, - 463, 303, 0, 0, 494, 391, 617, 473, 633, 662, - 663, 279, 428, 647, 551, 655, 680, 234, 276, 442, - 535, 639, 519, 417, 613, 614, 348, 518, 311, 209, - 388, 668, 232, 503, 390, 253, 241, 619, 644, 315, - 267, 305, 480, 675, 221, 546, 630, 250, 507, 0, - 0, 683, 258, 529, 642, 631, 223, 626, 528, 413, - 345, 346, 222, 0, 481, 284, 309, 0, 0, 274, - 437, 1002, 1003, 272, 684, 847, 654, 228, 0, 653, - 430, 616, 627, 414, 402, 227, 625, 412, 401, 353, - 855, 856, 296, 324, 932, 931, 930, 323, 325, 928, - 929, 927, 215, 640, 658, 0, 216, 0, 524, 643, - 685, 475, 220, 244, 245, 248, 0, 295, 299, 307, - 310, 320, 321, 331, 386, 441, 469, 465, 474, 0, - 610, 634, 648, 660, 666, 667, 669, 670, 671, 672, - 673, 676, 674, 429, 329, 520, 352, 392, 0, 0, - 447, 496, 251, 638, 521, 240, 604, 418, 427, 259, - 261, 260, 235, 512, 609, 246, 266, 938, 960, 949, - 813, 814, 939, 940, 964, 941, 816, 817, 961, 962, - 810, 811, 815, 963, 965, 686, 687, 688, 689, 690, - 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, - 701, 702, 703, 681, 537, 543, 538, 539, 540, 541, - 542, 0, 544, 952, 799, 798, 0, 805, 806, 0, - 835, 836, 838, 844, 845, 846, 857, 904, 905, 913, - 915, 916, 914, 917, 918, 919, 922, 923, 924, 925, - 920, 921, 926, 818, 822, 819, 820, 821, 833, 823, - 824, 825, 826, 827, 828, 829, 830, 831, 832, 834, - 975, 976, 977, 978, 979, 980, 850, 854, 853, 851, - 852, 848, 849, 876, 875, 877, 878, 879, 880, 881, - 882, 884, 883, 885, 886, 887, 888, 889, 890, 858, - 859, 862, 863, 861, 860, 864, 873, 874, 865, 866, - 867, 868, 869, 870, 872, 871, 891, 892, 893, 894, - 895, 897, 896, 900, 901, 899, 898, 903, 902, 797, - 204, 229, 387, 0, 478, 304, 682, 650, 508, 645, - 214, 231, 966, 278, 967, 0, 0, 971, 0, 0, - 0, 973, 972, 0, 974, 936, 935, 0, 0, 968, - 969, 0, 970, 0, 0, 206, 208, 217, 230, 242, - 247, 254, 277, 292, 294, 301, 314, 327, 328, 337, - 338, 341, 347, 399, 406, 407, 408, 409, 431, 432, - 433, 436, 439, 440, 443, 445, 446, 449, 454, 458, - 459, 460, 462, 464, 466, 479, 484, 498, 499, 500, - 501, 502, 505, 506, 513, 514, 515, 516, 517, 525, - 526, 531, 532, 533, 534, 545, 618, 620, 637, 657, - 664, 504, 404, 452, 476, 611, 0, 0, 981, 982, - 983, 984, 985, 986, 987, 988, 316, 632, 665, 629, - 677, 659, 461, 397, 0, 0, 400, 297, 322, 339, - 0, 649, 527, 236, 490, 306, 265, 1056, 0, 219, - 257, 239, 275, 290, 293, 343, 411, 421, 451, 457, - 312, 287, 255, 483, 252, 509, 548, 549, 550, 552, - 415, 282, 456, 0, 0, 395, 606, 607, 335, 557, - 0, 809, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 438, 0, 0, 0, 796, 0, 0, 0, 286, - 801, 0, 0, 0, 385, 283, 0, 0, 212, 530, - 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, - 298, 289, 285, 264, 336, 405, 450, 547, 444, 808, - 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, - 0, 0, 0, 803, 804, 0, 0, 0, 0, 0, - 0, 0, 0, 342, 262, 344, 210, 435, 523, 302, - 0, 101, 0, 0, 1057, 536, 991, 1131, 957, 995, - 1058, 1009, 1010, 1011, 996, 0, 249, 997, 998, 256, - 999, 0, 956, 839, 841, 840, 906, 907, 908, 909, - 910, 911, 912, 842, 843, 837, 1004, 641, 1012, 1013, - 0, 281, 340, 288, 280, 612, 0, 0, 0, 0, - 0, 0, 628, 0, 0, 238, 0, 0, 0, 0, - 0, 0, 0, 0, 793, 0, 807, 0, 0, 0, - 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 416, 0, 0, 0, 790, - 791, 0, 0, 0, 0, 951, 0, 792, 0, 0, - 800, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, - 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, - 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, - 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, - 1053, 1054, 1055, 802, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 313, 0, 423, 273, 0, 477, - 0, 319, 334, 0, 0, 0, 0, 0, 0, 0, - 950, 0, 0, 661, 0, 0, 948, 0, 0, 0, - 0, 384, 0, 349, 205, 233, 0, 0, 434, 485, - 497, 0, 0, 0, 0, 1001, 0, 495, 448, 636, - 243, 300, 482, 455, 493, 463, 303, 0, 0, 494, - 391, 617, 473, 633, 662, 663, 279, 428, 647, 551, - 655, 680, 234, 276, 442, 535, 639, 519, 417, 613, - 614, 348, 518, 311, 209, 388, 668, 232, 503, 390, - 253, 241, 619, 644, 315, 267, 305, 480, 675, 221, - 546, 630, 250, 507, 0, 0, 683, 258, 529, 642, - 631, 223, 626, 528, 413, 345, 346, 222, 0, 481, - 284, 309, 0, 0, 274, 437, 1002, 1003, 272, 684, - 847, 654, 228, 0, 653, 430, 616, 627, 414, 402, - 227, 625, 412, 401, 353, 855, 856, 296, 324, 932, - 931, 930, 323, 325, 928, 929, 927, 215, 640, 658, - 0, 216, 0, 524, 643, 685, 475, 220, 244, 245, - 248, 0, 295, 299, 307, 310, 320, 321, 331, 386, - 441, 469, 465, 474, 0, 610, 634, 648, 660, 666, - 667, 669, 670, 671, 672, 673, 676, 674, 429, 329, - 520, 352, 392, 0, 0, 447, 496, 251, 638, 521, - 240, 604, 418, 427, 259, 261, 260, 235, 512, 609, - 246, 266, 938, 960, 949, 813, 814, 939, 940, 964, - 941, 816, 817, 961, 962, 810, 811, 815, 963, 965, - 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, - 696, 697, 698, 699, 700, 701, 702, 703, 681, 537, - 543, 538, 539, 540, 541, 542, 0, 544, 952, 799, - 798, 0, 805, 806, 0, 835, 836, 838, 844, 845, - 846, 857, 904, 905, 913, 915, 916, 914, 917, 918, - 919, 922, 923, 924, 925, 920, 921, 926, 818, 822, - 819, 820, 821, 833, 823, 824, 825, 826, 827, 828, - 829, 830, 831, 832, 834, 975, 976, 977, 978, 979, - 980, 850, 854, 853, 851, 852, 848, 849, 876, 875, - 877, 878, 879, 880, 881, 882, 884, 883, 885, 886, - 887, 888, 889, 890, 858, 859, 862, 863, 861, 860, - 864, 873, 874, 865, 866, 867, 868, 869, 870, 872, - 871, 891, 892, 893, 894, 895, 897, 896, 900, 901, - 899, 898, 903, 902, 797, 204, 229, 387, 0, 478, - 304, 682, 650, 508, 645, 214, 231, 966, 278, 967, - 0, 0, 971, 0, 0, 0, 973, 972, 0, 974, - 936, 935, 0, 0, 968, 969, 0, 970, 0, 0, - 206, 208, 217, 230, 242, 247, 254, 277, 292, 294, - 301, 314, 327, 328, 337, 338, 341, 347, 399, 406, - 407, 408, 409, 431, 432, 433, 436, 439, 440, 443, - 445, 446, 449, 454, 458, 459, 460, 462, 464, 466, - 479, 484, 498, 499, 500, 501, 502, 505, 506, 513, - 514, 515, 516, 517, 525, 526, 531, 532, 533, 534, - 545, 618, 620, 637, 657, 664, 504, 404, 452, 476, - 611, 0, 0, 981, 982, 983, 984, 985, 986, 987, - 988, 316, 632, 665, 629, 677, 659, 461, 397, 0, - 0, 400, 297, 322, 339, 0, 649, 527, 236, 490, - 306, 265, 1056, 0, 219, 257, 239, 275, 290, 293, - 343, 411, 421, 451, 457, 312, 287, 255, 483, 252, - 509, 548, 549, 550, 552, 415, 282, 456, 0, 0, - 395, 606, 607, 335, 557, 0, 809, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 438, 0, 0, 0, - 796, 0, 0, 0, 286, 801, 0, 0, 0, 385, - 283, 0, 0, 212, 530, 0, 453, 0, 211, 0, - 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, - 405, 450, 547, 444, 808, 389, 0, 0, 522, 422, - 0, 0, 0, 0, 0, 0, 0, 0, 803, 804, - 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, - 344, 210, 435, 523, 302, 0, 101, 0, 0, 1057, - 536, 991, 1131, 957, 995, 1058, 1009, 1010, 1011, 996, - 0, 249, 997, 998, 256, 999, 0, 956, 839, 841, - 840, 906, 907, 908, 909, 910, 911, 912, 842, 843, - 837, 1004, 641, 1012, 1013, 0, 281, 340, 288, 280, - 612, 0, 0, 0, 0, 0, 0, 628, 0, 0, - 238, 0, 0, 0, 0, 0, 0, 0, 0, 793, - 0, 807, 0, 0, 0, 0, 291, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 416, 0, 0, 0, 790, 791, 0, 0, 0, 0, - 951, 0, 792, 0, 0, 800, 1014, 1015, 1016, 1017, - 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, - 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, - 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, - 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 2185, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, - 0, 423, 273, 0, 477, 0, 319, 334, 0, 0, - 0, 0, 0, 0, 0, 950, 0, 0, 661, 0, - 0, 948, 0, 0, 0, 0, 384, 0, 349, 205, - 233, 0, 0, 434, 485, 497, 0, 0, 0, 0, - 1001, 0, 495, 448, 636, 243, 300, 482, 455, 493, - 463, 303, 0, 0, 494, 391, 617, 473, 633, 662, - 663, 279, 428, 647, 551, 655, 680, 234, 276, 442, - 535, 639, 519, 417, 613, 614, 348, 518, 311, 209, - 388, 668, 232, 503, 390, 253, 241, 619, 644, 315, - 267, 305, 480, 675, 221, 546, 630, 250, 507, 0, - 0, 683, 258, 529, 642, 631, 223, 626, 528, 413, - 345, 346, 222, 0, 481, 284, 309, 0, 0, 274, - 437, 1002, 1003, 272, 684, 847, 654, 228, 0, 653, - 430, 616, 627, 414, 402, 227, 625, 412, 401, 353, - 855, 856, 296, 324, 932, 931, 930, 323, 325, 928, - 929, 927, 215, 640, 658, 0, 216, 0, 524, 643, - 685, 475, 220, 244, 245, 248, 0, 295, 299, 307, - 310, 320, 321, 331, 386, 441, 469, 465, 474, 0, - 610, 634, 648, 660, 666, 667, 669, 670, 671, 672, - 673, 676, 674, 429, 329, 520, 352, 392, 0, 0, - 447, 496, 251, 638, 521, 240, 604, 418, 427, 259, - 261, 260, 235, 512, 609, 246, 266, 938, 960, 949, - 813, 814, 939, 940, 964, 941, 816, 817, 961, 962, - 810, 811, 815, 963, 965, 686, 687, 688, 689, 690, - 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, - 701, 702, 703, 681, 537, 543, 538, 539, 540, 541, - 542, 0, 544, 952, 799, 798, 0, 805, 806, 0, - 835, 836, 838, 844, 845, 846, 857, 904, 905, 913, - 915, 916, 914, 917, 918, 919, 922, 923, 924, 925, - 920, 921, 926, 818, 822, 819, 820, 821, 833, 823, - 824, 825, 826, 827, 828, 829, 830, 831, 832, 834, - 975, 976, 977, 978, 979, 980, 850, 854, 853, 851, - 852, 848, 849, 876, 875, 877, 878, 879, 880, 881, - 882, 884, 883, 885, 886, 887, 888, 889, 890, 858, - 859, 862, 863, 861, 860, 864, 873, 874, 865, 866, - 867, 868, 869, 870, 872, 871, 891, 892, 893, 894, - 895, 897, 896, 900, 901, 899, 898, 903, 902, 797, - 204, 229, 387, 0, 478, 304, 682, 650, 508, 645, - 214, 231, 966, 278, 967, 0, 0, 971, 0, 0, - 0, 973, 972, 0, 974, 936, 935, 0, 0, 968, - 969, 0, 970, 0, 0, 206, 208, 217, 230, 242, - 247, 254, 277, 292, 294, 301, 314, 327, 328, 337, - 338, 341, 347, 399, 406, 407, 408, 409, 431, 432, - 433, 436, 439, 440, 443, 445, 446, 449, 454, 458, - 459, 460, 462, 464, 466, 479, 484, 498, 499, 500, - 501, 502, 505, 506, 513, 514, 515, 516, 517, 525, - 526, 531, 532, 533, 534, 545, 618, 620, 637, 657, - 664, 504, 404, 452, 476, 611, 0, 0, 981, 982, - 983, 984, 985, 986, 987, 988, 316, 632, 665, 629, - 677, 659, 461, 397, 0, 0, 400, 297, 322, 339, - 0, 649, 527, 236, 490, 306, 265, 1056, 0, 219, - 257, 239, 275, 290, 293, 343, 411, 421, 451, 457, - 312, 287, 255, 483, 252, 509, 548, 549, 550, 552, - 415, 282, 456, 0, 0, 395, 606, 607, 335, 557, - 0, 809, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 438, 0, 0, 0, 796, 0, 0, 0, 286, - 801, 0, 0, 0, 385, 283, 0, 0, 212, 530, - 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, - 298, 289, 285, 264, 336, 405, 450, 547, 444, 808, - 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, - 0, 0, 0, 803, 804, 0, 0, 0, 0, 0, - 0, 0, 0, 342, 262, 344, 210, 435, 523, 302, - 0, 101, 0, 0, 1057, 536, 991, 1131, 957, 995, - 1058, 1009, 1010, 1011, 996, 0, 249, 997, 998, 256, - 999, 0, 956, 839, 841, 840, 906, 907, 908, 909, - 910, 911, 912, 842, 843, 837, 1004, 641, 1012, 1013, - 0, 281, 340, 288, 280, 612, 0, 0, 0, 0, - 0, 0, 628, 0, 0, 238, 0, 0, 0, 0, - 0, 0, 0, 0, 793, 0, 807, 0, 0, 0, - 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 416, 0, 0, 0, 790, - 791, 0, 0, 0, 0, 951, 0, 792, 0, 0, - 800, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, - 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, - 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, - 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, - 1053, 1054, 1055, 2183, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 313, 0, 423, 273, 0, 477, - 0, 319, 334, 0, 0, 0, 0, 0, 0, 0, - 950, 0, 0, 661, 0, 0, 948, 0, 0, 0, - 0, 384, 0, 349, 205, 233, 0, 0, 434, 485, - 497, 0, 0, 0, 0, 1001, 0, 495, 448, 636, - 243, 300, 482, 455, 493, 463, 303, 0, 0, 494, - 391, 617, 473, 633, 662, 663, 279, 428, 647, 551, - 655, 680, 234, 276, 442, 535, 639, 519, 417, 613, - 614, 348, 518, 311, 209, 388, 668, 232, 503, 390, - 253, 241, 619, 644, 315, 267, 305, 480, 675, 221, - 546, 630, 250, 507, 0, 0, 683, 258, 529, 642, - 631, 223, 626, 528, 413, 345, 346, 222, 0, 481, - 284, 309, 0, 0, 274, 437, 1002, 1003, 272, 684, - 847, 654, 228, 0, 653, 430, 616, 627, 414, 402, - 227, 625, 412, 401, 353, 855, 856, 296, 324, 932, - 931, 930, 323, 325, 928, 929, 927, 215, 640, 658, - 0, 216, 0, 524, 643, 685, 475, 220, 244, 245, - 248, 0, 295, 299, 307, 310, 320, 321, 331, 386, - 441, 469, 465, 474, 0, 610, 634, 648, 660, 666, - 667, 669, 670, 671, 672, 673, 676, 674, 429, 329, - 520, 352, 392, 0, 0, 447, 496, 251, 638, 521, - 240, 604, 418, 427, 259, 261, 260, 235, 512, 609, - 246, 266, 938, 960, 949, 813, 814, 939, 940, 964, - 941, 816, 817, 961, 962, 810, 811, 815, 963, 965, - 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, - 696, 697, 698, 699, 700, 701, 702, 703, 681, 537, - 543, 538, 539, 540, 541, 542, 0, 544, 952, 799, - 798, 0, 805, 806, 0, 835, 836, 838, 844, 845, - 846, 857, 904, 905, 913, 915, 916, 914, 917, 918, - 919, 922, 923, 924, 925, 920, 921, 926, 818, 822, - 819, 820, 821, 833, 823, 824, 825, 826, 827, 828, - 829, 830, 831, 832, 834, 975, 976, 977, 978, 979, - 980, 850, 854, 853, 851, 852, 848, 849, 876, 875, - 877, 878, 879, 880, 881, 882, 884, 883, 885, 886, - 887, 888, 889, 890, 858, 859, 862, 863, 861, 860, - 864, 873, 874, 865, 866, 867, 868, 869, 870, 872, - 871, 891, 892, 893, 894, 895, 897, 896, 900, 901, - 899, 898, 903, 902, 797, 204, 229, 387, 0, 478, - 304, 682, 650, 508, 645, 214, 231, 966, 278, 967, - 0, 0, 971, 0, 0, 0, 973, 972, 0, 974, - 936, 935, 0, 0, 968, 969, 0, 970, 0, 0, - 206, 208, 217, 230, 242, 247, 254, 277, 292, 294, - 301, 314, 327, 328, 337, 338, 341, 347, 399, 406, - 407, 408, 409, 431, 432, 433, 436, 439, 440, 443, - 445, 446, 449, 454, 458, 459, 460, 462, 464, 466, - 479, 484, 498, 499, 500, 501, 502, 505, 506, 513, - 514, 515, 516, 517, 525, 526, 531, 532, 533, 534, - 545, 618, 620, 637, 657, 664, 504, 404, 452, 476, - 611, 0, 0, 981, 982, 983, 984, 985, 986, 987, - 988, 316, 632, 665, 629, 677, 659, 461, 397, 0, - 0, 400, 297, 322, 339, 0, 649, 527, 236, 490, - 306, 265, 1056, 0, 219, 257, 239, 275, 290, 293, - 343, 411, 421, 451, 457, 312, 287, 255, 483, 252, - 509, 548, 549, 550, 552, 415, 282, 456, 557, 0, - 395, 606, 607, 335, 0, 0, 0, 0, 0, 0, - 438, 0, 0, 0, 0, 0, 0, 0, 286, 0, + 606, 607, 335, 557, 0, 809, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 438, 0, 0, 0, 796, + 0, 0, 0, 286, 801, 0, 0, 0, 385, 283, + 0, 0, 212, 530, 0, 453, 0, 211, 0, 511, + 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, + 450, 547, 444, 808, 389, 0, 0, 522, 422, 0, + 0, 0, 0, 0, 0, 0, 0, 803, 804, 0, + 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, + 210, 435, 523, 302, 0, 101, 0, 0, 1057, 536, + 991, 780, 957, 995, 1058, 1009, 1010, 1011, 996, 0, + 249, 997, 998, 256, 999, 0, 956, 839, 841, 840, + 906, 907, 908, 909, 910, 911, 912, 842, 843, 837, + 1004, 641, 1012, 1013, 0, 281, 340, 288, 280, 612, + 0, 0, 0, 0, 0, 0, 628, 0, 0, 238, + 0, 0, 0, 0, 0, 0, 0, 776, 793, 0, + 807, 0, 0, 0, 0, 291, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, + 0, 0, 0, 790, 791, 1113, 0, 0, 0, 951, + 0, 792, 0, 0, 800, 1014, 1015, 1016, 1017, 1018, + 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, + 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, + 1049, 1050, 1051, 1052, 1053, 1054, 1055, 802, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, + 423, 273, 0, 477, 0, 319, 334, 0, 0, 0, + 0, 0, 0, 0, 950, 0, 0, 661, 0, 0, + 948, 0, 0, 0, 0, 384, 0, 349, 205, 233, + 0, 0, 434, 485, 497, 0, 0, 0, 0, 1001, + 0, 495, 448, 636, 243, 300, 482, 455, 493, 463, + 303, 0, 0, 494, 391, 617, 473, 633, 662, 663, + 279, 428, 647, 551, 655, 680, 234, 276, 442, 535, + 639, 519, 417, 613, 614, 348, 518, 311, 209, 388, + 668, 232, 503, 390, 253, 241, 619, 644, 315, 267, + 305, 480, 675, 221, 546, 630, 250, 507, 0, 0, + 683, 258, 529, 642, 631, 223, 626, 528, 413, 345, + 346, 222, 0, 481, 284, 309, 0, 0, 274, 437, + 1002, 1003, 272, 684, 847, 654, 228, 0, 653, 430, + 616, 627, 414, 402, 227, 625, 412, 401, 353, 855, + 856, 296, 324, 932, 931, 930, 323, 325, 928, 929, + 927, 215, 640, 658, 0, 216, 0, 524, 643, 685, + 475, 220, 244, 245, 248, 0, 295, 299, 307, 310, + 320, 321, 331, 386, 441, 469, 465, 474, 0, 610, + 634, 648, 660, 666, 667, 669, 670, 671, 672, 673, + 676, 674, 429, 329, 520, 352, 392, 0, 0, 447, + 496, 251, 638, 521, 240, 604, 418, 427, 259, 261, + 260, 235, 512, 609, 246, 266, 938, 960, 949, 813, + 814, 939, 940, 964, 941, 816, 817, 961, 962, 810, + 811, 815, 963, 965, 686, 687, 688, 689, 690, 691, + 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, + 702, 703, 681, 537, 543, 538, 539, 540, 541, 542, + 0, 544, 952, 799, 798, 0, 805, 806, 0, 835, + 836, 838, 844, 845, 846, 857, 904, 905, 913, 915, + 916, 914, 917, 918, 919, 922, 923, 924, 925, 920, + 921, 926, 818, 822, 819, 820, 821, 833, 823, 824, + 825, 826, 827, 828, 829, 830, 831, 832, 834, 975, + 976, 977, 978, 979, 980, 850, 854, 853, 851, 852, + 848, 849, 876, 875, 877, 878, 879, 880, 881, 882, + 884, 883, 885, 886, 887, 888, 889, 890, 858, 859, + 862, 863, 861, 860, 864, 873, 874, 865, 866, 867, + 868, 869, 870, 872, 871, 891, 892, 893, 894, 895, + 897, 896, 900, 901, 899, 898, 903, 902, 797, 204, + 229, 387, 0, 478, 304, 682, 650, 508, 645, 214, + 231, 966, 278, 967, 0, 0, 971, 0, 0, 0, + 973, 972, 0, 974, 936, 935, 0, 0, 968, 969, + 0, 970, 0, 0, 206, 208, 217, 230, 242, 247, + 254, 277, 292, 294, 301, 314, 327, 328, 337, 338, + 341, 347, 399, 406, 407, 408, 409, 431, 432, 433, + 436, 439, 440, 443, 445, 446, 449, 454, 458, 459, + 460, 462, 464, 466, 479, 484, 498, 499, 500, 501, + 502, 505, 506, 513, 514, 515, 516, 517, 525, 526, + 531, 532, 533, 534, 545, 618, 620, 637, 657, 664, + 504, 404, 452, 476, 611, 0, 0, 981, 982, 983, + 984, 985, 986, 987, 988, 316, 632, 665, 629, 677, + 659, 461, 397, 0, 0, 400, 297, 322, 339, 0, + 649, 527, 236, 490, 306, 265, 1056, 0, 219, 257, + 239, 275, 290, 293, 343, 411, 421, 451, 457, 312, + 287, 255, 483, 252, 509, 548, 549, 550, 552, 415, + 282, 456, 0, 0, 395, 606, 607, 335, 557, 0, + 809, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 438, 0, 0, 0, 796, 0, 0, 0, 286, 801, + 0, 0, 0, 385, 283, 0, 0, 212, 530, 0, + 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, + 289, 285, 264, 336, 405, 450, 547, 444, 808, 389, + 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, + 0, 0, 803, 804, 0, 0, 0, 0, 0, 0, + 0, 0, 342, 262, 344, 210, 435, 523, 302, 0, + 101, 0, 0, 1057, 536, 991, 780, 957, 995, 1058, + 1009, 1010, 1011, 996, 0, 249, 997, 998, 256, 999, + 0, 956, 839, 841, 840, 906, 907, 908, 909, 910, + 911, 912, 842, 843, 837, 1004, 641, 1012, 1013, 0, + 281, 340, 288, 280, 612, 0, 0, 0, 0, 0, + 0, 628, 0, 0, 238, 0, 0, 0, 0, 0, + 0, 0, 776, 793, 0, 807, 0, 0, 0, 0, + 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 416, 0, 0, 0, 790, 791, + 1109, 0, 0, 0, 951, 0, 792, 0, 0, 800, + 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, + 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, + 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, + 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 802, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 313, 0, 423, 273, 0, 477, 0, + 319, 334, 0, 0, 0, 0, 0, 0, 0, 950, + 0, 0, 661, 0, 0, 948, 0, 0, 0, 0, + 384, 0, 349, 205, 233, 0, 0, 434, 485, 497, + 0, 0, 0, 0, 1001, 0, 495, 448, 636, 243, + 300, 482, 455, 493, 463, 303, 0, 0, 494, 391, + 617, 473, 633, 662, 663, 279, 428, 647, 551, 655, + 680, 234, 276, 442, 535, 639, 519, 417, 613, 614, + 348, 518, 311, 209, 388, 668, 232, 503, 390, 253, + 241, 619, 644, 315, 267, 305, 480, 675, 221, 546, + 630, 250, 507, 0, 0, 683, 258, 529, 642, 631, + 223, 626, 528, 413, 345, 346, 222, 0, 481, 284, + 309, 0, 0, 274, 437, 1002, 1003, 272, 684, 847, + 654, 228, 0, 653, 430, 616, 627, 414, 402, 227, + 625, 412, 401, 353, 855, 856, 296, 324, 932, 931, + 930, 323, 325, 928, 929, 927, 215, 640, 658, 0, + 216, 0, 524, 643, 685, 475, 220, 244, 245, 248, + 0, 295, 299, 307, 310, 320, 321, 331, 386, 441, + 469, 465, 474, 0, 610, 634, 648, 660, 666, 667, + 669, 670, 671, 672, 673, 676, 674, 429, 329, 520, + 352, 392, 0, 0, 447, 496, 251, 638, 521, 240, + 604, 418, 427, 259, 261, 260, 235, 512, 609, 246, + 266, 938, 960, 949, 813, 814, 939, 940, 964, 941, + 816, 817, 961, 962, 810, 811, 815, 963, 965, 686, + 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, + 697, 698, 699, 700, 701, 702, 703, 681, 537, 543, + 538, 539, 540, 541, 542, 0, 544, 952, 799, 798, + 0, 805, 806, 0, 835, 836, 838, 844, 845, 846, + 857, 904, 905, 913, 915, 916, 914, 917, 918, 919, + 922, 923, 924, 925, 920, 921, 926, 818, 822, 819, + 820, 821, 833, 823, 824, 825, 826, 827, 828, 829, + 830, 831, 832, 834, 975, 976, 977, 978, 979, 980, + 850, 854, 853, 851, 852, 848, 849, 876, 875, 877, + 878, 879, 880, 881, 882, 884, 883, 885, 886, 887, + 888, 889, 890, 858, 859, 862, 863, 861, 860, 864, + 873, 874, 865, 866, 867, 868, 869, 870, 872, 871, + 891, 892, 893, 894, 895, 897, 896, 900, 901, 899, + 898, 903, 902, 797, 204, 229, 387, 0, 478, 304, + 682, 650, 508, 645, 214, 231, 966, 278, 967, 0, + 0, 971, 0, 0, 0, 973, 972, 0, 974, 936, + 935, 0, 0, 968, 969, 0, 970, 0, 0, 206, + 208, 217, 230, 242, 247, 254, 277, 292, 294, 301, + 314, 327, 328, 337, 338, 341, 347, 399, 406, 407, + 408, 409, 431, 432, 433, 436, 439, 440, 443, 445, + 446, 449, 454, 458, 459, 460, 462, 464, 466, 479, + 484, 498, 499, 500, 501, 502, 505, 506, 513, 514, + 515, 516, 517, 525, 526, 531, 532, 533, 534, 545, + 618, 620, 637, 657, 664, 504, 404, 452, 476, 611, + 0, 0, 981, 982, 983, 984, 985, 986, 987, 988, + 316, 632, 665, 629, 677, 659, 461, 397, 0, 0, + 400, 297, 322, 339, 0, 649, 527, 236, 490, 306, + 265, 1056, 0, 219, 257, 239, 275, 290, 293, 343, + 411, 421, 451, 457, 312, 287, 255, 483, 252, 509, + 548, 549, 550, 552, 415, 282, 456, 0, 0, 395, + 606, 607, 335, 557, 0, 809, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 438, 0, 0, 0, 796, + 0, 0, 0, 286, 801, 0, 0, 0, 385, 283, + 0, 0, 212, 530, 0, 453, 0, 211, 0, 511, + 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, + 450, 547, 444, 808, 389, 0, 0, 522, 422, 0, + 0, 0, 0, 0, 0, 0, 0, 803, 804, 0, + 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, + 210, 435, 523, 302, 0, 101, 0, 0, 1057, 536, + 991, 780, 957, 995, 1058, 1009, 1010, 1011, 996, 0, + 249, 997, 998, 256, 999, 0, 956, 839, 841, 840, + 906, 907, 908, 909, 910, 911, 912, 842, 843, 837, + 1004, 641, 1012, 1013, 0, 281, 340, 288, 280, 612, + 0, 0, 0, 0, 0, 0, 628, 0, 0, 238, + 0, 0, 0, 0, 0, 0, 0, 776, 793, 0, + 807, 0, 0, 0, 0, 291, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, + 0, 0, 0, 790, 791, 0, 0, 0, 0, 951, + 0, 792, 0, 0, 800, 1014, 1015, 1016, 1017, 1018, + 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, + 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, + 1049, 1050, 1051, 1052, 1053, 1054, 1055, 802, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, + 423, 273, 0, 477, 0, 319, 334, 0, 0, 0, + 0, 0, 0, 0, 950, 0, 0, 661, 0, 0, + 948, 0, 0, 0, 0, 384, 0, 349, 205, 233, + 0, 0, 434, 485, 497, 0, 0, 0, 0, 1001, + 0, 495, 448, 636, 243, 300, 482, 455, 493, 463, + 303, 0, 0, 494, 391, 617, 473, 633, 662, 663, + 279, 428, 647, 551, 655, 680, 234, 276, 442, 535, + 639, 519, 417, 613, 614, 348, 518, 311, 209, 388, + 668, 232, 503, 390, 253, 241, 619, 644, 315, 267, + 305, 480, 675, 221, 546, 630, 250, 507, 0, 0, + 683, 258, 529, 642, 631, 223, 626, 528, 413, 345, + 346, 222, 0, 481, 284, 309, 0, 0, 274, 437, + 1002, 1003, 272, 684, 847, 654, 228, 0, 653, 430, + 616, 627, 414, 402, 227, 625, 412, 401, 353, 855, + 856, 296, 324, 932, 931, 930, 323, 325, 928, 929, + 927, 215, 640, 658, 0, 216, 0, 524, 643, 685, + 475, 220, 244, 245, 248, 0, 295, 299, 307, 310, + 320, 321, 331, 386, 441, 469, 465, 474, 0, 610, + 634, 648, 660, 666, 667, 669, 670, 671, 672, 673, + 676, 674, 429, 329, 520, 352, 392, 0, 0, 447, + 496, 251, 638, 521, 240, 604, 418, 427, 259, 261, + 260, 235, 512, 609, 246, 266, 938, 960, 949, 813, + 814, 939, 940, 964, 941, 816, 817, 961, 962, 810, + 811, 815, 963, 965, 686, 687, 688, 689, 690, 691, + 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, + 702, 703, 681, 537, 543, 538, 539, 540, 541, 542, + 0, 544, 952, 799, 798, 0, 805, 806, 0, 835, + 836, 838, 844, 845, 846, 857, 904, 905, 913, 915, + 916, 914, 917, 918, 919, 922, 923, 924, 925, 920, + 921, 926, 818, 822, 819, 820, 821, 833, 823, 824, + 825, 826, 827, 828, 829, 830, 831, 832, 834, 975, + 976, 977, 978, 979, 980, 850, 854, 853, 851, 852, + 848, 849, 876, 875, 877, 878, 879, 880, 881, 882, + 884, 883, 885, 886, 887, 888, 889, 890, 858, 859, + 862, 863, 861, 860, 864, 873, 874, 865, 866, 867, + 868, 869, 870, 872, 871, 891, 892, 893, 894, 895, + 897, 896, 900, 901, 899, 898, 903, 902, 797, 204, + 229, 387, 0, 478, 304, 682, 650, 508, 645, 214, + 231, 966, 278, 967, 0, 0, 971, 0, 0, 0, + 973, 972, 0, 974, 936, 935, 0, 0, 968, 969, + 0, 970, 0, 0, 206, 208, 217, 230, 242, 247, + 254, 277, 292, 294, 301, 314, 327, 328, 337, 338, + 341, 347, 399, 406, 407, 408, 409, 431, 432, 433, + 436, 439, 440, 443, 445, 446, 449, 454, 458, 459, + 460, 462, 464, 466, 479, 484, 498, 499, 500, 501, + 502, 505, 506, 513, 514, 515, 516, 517, 525, 526, + 531, 532, 533, 534, 545, 618, 620, 637, 657, 664, + 504, 404, 452, 476, 611, 0, 0, 981, 982, 983, + 984, 985, 986, 987, 988, 316, 632, 665, 629, 677, + 659, 461, 397, 0, 0, 400, 297, 322, 339, 0, + 649, 527, 236, 490, 306, 265, 1056, 0, 219, 257, + 239, 275, 290, 293, 343, 411, 421, 451, 457, 312, + 287, 255, 483, 252, 509, 548, 549, 550, 552, 415, + 282, 456, 0, 0, 395, 606, 607, 335, 557, 0, + 809, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 438, 0, 0, 0, 796, 0, 0, 0, 286, 801, + 0, 0, 0, 385, 283, 0, 0, 212, 530, 0, + 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, + 289, 285, 264, 336, 405, 450, 547, 444, 808, 389, + 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, + 0, 0, 803, 804, 0, 0, 0, 0, 0, 0, + 0, 0, 342, 262, 344, 210, 435, 523, 302, 0, + 101, 0, 0, 1057, 536, 991, 780, 957, 995, 1058, + 1009, 1010, 1011, 996, 0, 249, 997, 998, 256, 999, + 0, 956, 839, 841, 840, 906, 907, 908, 909, 910, + 911, 912, 842, 843, 837, 1004, 641, 1012, 1013, 0, + 281, 340, 288, 280, 612, 0, 0, 0, 0, 0, + 0, 628, 0, 0, 238, 0, 0, 0, 0, 0, + 0, 0, 776, 793, 0, 807, 0, 0, 0, 0, + 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 416, 0, 0, 0, 790, 791, + 0, 0, 0, 0, 951, 0, 792, 0, 0, 800, + 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, + 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, + 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, + 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 3259, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 313, 0, 423, 273, 0, 477, 0, + 319, 334, 0, 0, 0, 0, 0, 0, 0, 950, + 0, 0, 661, 0, 0, 948, 0, 0, 0, 0, + 384, 0, 349, 205, 233, 0, 0, 434, 485, 497, + 0, 0, 0, 0, 1001, 0, 495, 448, 636, 243, + 300, 482, 455, 493, 463, 303, 0, 0, 494, 391, + 617, 473, 633, 662, 663, 279, 428, 647, 551, 655, + 680, 234, 276, 442, 535, 639, 519, 417, 613, 614, + 348, 518, 311, 209, 388, 668, 232, 503, 390, 253, + 241, 619, 644, 315, 267, 305, 480, 675, 221, 546, + 630, 250, 507, 0, 0, 683, 258, 529, 642, 631, + 223, 626, 528, 413, 345, 346, 222, 0, 481, 284, + 309, 0, 0, 274, 437, 1002, 1003, 272, 684, 847, + 654, 228, 0, 653, 430, 616, 627, 414, 402, 227, + 625, 412, 401, 353, 855, 856, 296, 324, 932, 931, + 930, 323, 325, 928, 929, 927, 215, 640, 658, 0, + 216, 0, 524, 643, 685, 475, 220, 244, 245, 248, + 0, 295, 299, 307, 310, 320, 321, 331, 386, 441, + 469, 465, 474, 0, 610, 634, 648, 660, 666, 667, + 669, 670, 671, 672, 673, 676, 674, 429, 329, 520, + 352, 392, 0, 0, 447, 496, 251, 638, 521, 240, + 604, 418, 427, 259, 261, 260, 235, 512, 609, 246, + 266, 938, 960, 949, 813, 814, 939, 940, 964, 941, + 816, 817, 961, 962, 810, 811, 815, 963, 965, 686, + 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, + 697, 698, 699, 700, 701, 702, 703, 681, 537, 543, + 538, 539, 540, 541, 542, 0, 544, 952, 799, 798, + 0, 805, 806, 0, 835, 836, 838, 844, 845, 846, + 857, 904, 905, 913, 915, 916, 914, 917, 918, 919, + 922, 923, 924, 925, 920, 921, 926, 818, 822, 819, + 820, 821, 833, 823, 824, 825, 826, 827, 828, 829, + 830, 831, 832, 834, 975, 976, 977, 978, 979, 980, + 850, 854, 853, 851, 852, 848, 849, 876, 875, 877, + 878, 879, 880, 881, 882, 884, 883, 885, 886, 887, + 888, 889, 890, 858, 859, 862, 863, 861, 860, 864, + 873, 874, 865, 866, 867, 868, 869, 870, 872, 871, + 891, 892, 893, 894, 895, 897, 896, 900, 901, 899, + 898, 903, 902, 797, 204, 229, 387, 0, 478, 304, + 682, 650, 508, 645, 214, 231, 966, 278, 967, 0, + 0, 971, 0, 0, 0, 973, 972, 0, 974, 936, + 935, 0, 0, 968, 969, 0, 970, 0, 0, 206, + 208, 217, 230, 242, 247, 254, 277, 292, 294, 301, + 314, 327, 328, 337, 338, 341, 347, 399, 406, 407, + 408, 409, 431, 432, 433, 436, 439, 440, 443, 445, + 446, 449, 454, 458, 459, 460, 462, 464, 466, 479, + 484, 498, 499, 500, 501, 502, 505, 506, 513, 514, + 515, 516, 517, 525, 526, 531, 532, 533, 534, 545, + 618, 620, 637, 657, 664, 504, 404, 452, 476, 611, + 0, 0, 981, 982, 983, 984, 985, 986, 987, 988, + 316, 632, 665, 629, 677, 659, 461, 397, 0, 0, + 400, 297, 322, 339, 0, 649, 527, 236, 490, 306, + 265, 1056, 0, 219, 257, 239, 275, 290, 293, 343, + 411, 421, 451, 457, 312, 287, 255, 483, 252, 509, + 548, 549, 550, 552, 415, 282, 456, 0, 0, 395, + 606, 607, 335, 557, 0, 809, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 438, 0, 0, 0, 796, + 0, 0, 0, 286, 801, 0, 0, 0, 385, 283, + 0, 0, 212, 530, 0, 453, 0, 211, 0, 511, + 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, + 450, 547, 444, 808, 389, 0, 0, 522, 422, 0, + 0, 0, 0, 0, 0, 0, 0, 803, 804, 0, + 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, + 210, 435, 523, 302, 0, 101, 0, 0, 1057, 536, + 991, 780, 957, 995, 1058, 1009, 1010, 1011, 996, 0, + 249, 997, 998, 256, 999, 0, 956, 839, 841, 840, + 906, 907, 908, 909, 910, 911, 912, 842, 843, 837, + 1004, 641, 1012, 1013, 0, 281, 340, 288, 280, 612, + 0, 0, 0, 0, 0, 0, 628, 0, 0, 238, + 0, 0, 0, 0, 0, 0, 0, 776, 793, 0, + 807, 0, 0, 0, 0, 291, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, + 0, 0, 0, 790, 791, 0, 0, 0, 0, 951, + 0, 792, 0, 0, 800, 1014, 1015, 1016, 1017, 1018, + 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, + 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, + 1049, 1050, 1051, 1052, 1053, 1054, 1055, 3255, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, + 423, 273, 0, 477, 0, 319, 334, 0, 0, 0, + 0, 0, 0, 0, 950, 0, 0, 661, 0, 0, + 948, 0, 0, 0, 0, 384, 0, 349, 205, 233, + 0, 0, 434, 485, 497, 0, 0, 0, 0, 1001, + 0, 495, 448, 636, 243, 300, 482, 455, 493, 463, + 303, 0, 0, 494, 391, 617, 473, 633, 662, 663, + 279, 428, 647, 551, 655, 680, 234, 276, 442, 535, + 639, 519, 417, 613, 614, 348, 518, 311, 209, 388, + 668, 232, 503, 390, 253, 241, 619, 644, 315, 267, + 305, 480, 675, 221, 546, 630, 250, 507, 0, 0, + 683, 258, 529, 642, 631, 223, 626, 528, 413, 345, + 346, 222, 0, 481, 284, 309, 0, 0, 274, 437, + 1002, 1003, 272, 684, 847, 654, 228, 0, 653, 430, + 616, 627, 414, 402, 227, 625, 412, 401, 353, 855, + 856, 296, 324, 932, 931, 930, 323, 325, 928, 929, + 927, 215, 640, 658, 0, 216, 0, 524, 643, 685, + 475, 220, 244, 245, 248, 0, 295, 299, 307, 310, + 320, 321, 331, 386, 441, 469, 465, 474, 0, 610, + 634, 648, 660, 666, 667, 669, 670, 671, 672, 673, + 676, 674, 429, 329, 520, 352, 392, 0, 0, 447, + 496, 251, 638, 521, 240, 604, 418, 427, 259, 261, + 260, 235, 512, 609, 246, 266, 938, 960, 949, 813, + 814, 939, 940, 964, 941, 816, 817, 961, 962, 810, + 811, 815, 963, 965, 686, 687, 688, 689, 690, 691, + 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, + 702, 703, 681, 537, 543, 538, 539, 540, 541, 542, + 0, 544, 952, 799, 798, 0, 805, 806, 0, 835, + 836, 838, 844, 845, 846, 857, 904, 905, 913, 915, + 916, 914, 917, 918, 919, 922, 923, 924, 925, 920, + 921, 926, 818, 822, 819, 820, 821, 833, 823, 824, + 825, 826, 827, 828, 829, 830, 831, 832, 834, 975, + 976, 977, 978, 979, 980, 850, 854, 853, 851, 852, + 848, 849, 876, 875, 877, 878, 879, 880, 881, 882, + 884, 883, 885, 886, 887, 888, 889, 890, 858, 859, + 862, 863, 861, 860, 864, 873, 874, 865, 866, 867, + 868, 869, 870, 872, 871, 891, 892, 893, 894, 895, + 897, 896, 900, 901, 899, 898, 903, 902, 797, 204, + 229, 387, 0, 478, 304, 682, 650, 508, 645, 214, + 231, 966, 278, 967, 0, 0, 971, 0, 0, 0, + 973, 972, 0, 974, 936, 935, 0, 0, 968, 969, + 0, 970, 0, 0, 206, 208, 217, 230, 242, 247, + 254, 277, 292, 294, 301, 314, 327, 328, 337, 338, + 341, 347, 399, 406, 407, 408, 409, 431, 432, 433, + 436, 439, 440, 443, 445, 446, 449, 454, 458, 459, + 460, 462, 464, 466, 479, 484, 498, 499, 500, 501, + 502, 505, 506, 513, 514, 515, 516, 517, 525, 526, + 531, 532, 533, 534, 545, 618, 620, 637, 657, 664, + 504, 404, 452, 476, 611, 0, 0, 981, 982, 983, + 984, 985, 986, 987, 988, 316, 632, 665, 629, 677, + 659, 461, 397, 0, 0, 400, 297, 322, 339, 0, + 649, 527, 236, 490, 306, 265, 1056, 0, 219, 257, + 239, 275, 290, 293, 343, 411, 421, 451, 457, 312, + 287, 255, 483, 252, 509, 548, 549, 550, 552, 415, + 282, 456, 0, 0, 395, 606, 607, 335, 557, 0, + 809, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 438, 0, 0, 0, 796, 0, 0, 0, 286, 801, 0, 0, 0, 385, 283, 0, 0, 212, 530, 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, - 289, 285, 264, 336, 405, 450, 547, 444, 0, 389, + 289, 285, 264, 336, 405, 450, 547, 444, 808, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 803, 804, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, 435, 523, 302, 0, - 0, 0, 0, 0, 536, 756, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, - 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, - 376, 382, 355, 364, 0, 0, 641, 0, 0, 0, + 101, 0, 0, 1057, 536, 991, 1132, 957, 995, 1058, + 1009, 1010, 1011, 996, 0, 249, 997, 998, 256, 999, + 0, 956, 839, 841, 840, 906, 907, 908, 909, 910, + 911, 912, 842, 843, 837, 1004, 641, 1012, 1013, 0, 281, 340, 288, 280, 612, 0, 0, 0, 0, 0, - 0, 628, 0, 0, 238, 0, 1174, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 628, 0, 0, 238, 0, 0, 0, 0, 0, + 0, 0, 0, 793, 0, 807, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 416, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 416, 0, 0, 0, 790, 791, + 0, 0, 0, 0, 951, 0, 792, 0, 0, 800, + 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, + 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, + 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, + 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 802, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, 423, 273, 0, 477, 0, - 319, 334, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1173, 661, 0, 0, 0, 0, 0, 1170, 1171, - 384, 1139, 349, 205, 233, 1164, 1168, 434, 485, 497, - 0, 0, 0, 0, 269, 0, 495, 448, 636, 243, + 319, 334, 0, 0, 0, 0, 0, 0, 0, 950, + 0, 0, 661, 0, 0, 948, 0, 0, 0, 0, + 384, 0, 349, 205, 233, 0, 0, 434, 485, 497, + 0, 0, 0, 0, 1001, 0, 495, 448, 636, 243, 300, 482, 455, 493, 463, 303, 0, 0, 494, 391, 617, 473, 633, 662, 663, 279, 428, 647, 551, 655, 680, 234, 276, 442, 535, 639, 519, 417, 613, 614, @@ -4770,35 +4670,35 @@ var yyAct = [...]int{ 241, 619, 644, 315, 267, 305, 480, 675, 221, 546, 630, 250, 507, 0, 0, 683, 258, 529, 642, 631, 223, 626, 528, 413, 345, 346, 222, 0, 481, 284, - 309, 0, 0, 274, 437, 621, 622, 272, 684, 237, + 309, 0, 0, 274, 437, 1002, 1003, 272, 684, 847, 654, 228, 0, 653, 430, 616, 627, 414, 402, 227, - 625, 412, 401, 353, 374, 375, 296, 324, 470, 394, - 471, 323, 325, 425, 424, 426, 215, 640, 658, 0, + 625, 412, 401, 353, 855, 856, 296, 324, 932, 931, + 930, 323, 325, 928, 929, 927, 215, 640, 658, 0, 216, 0, 524, 643, 685, 475, 220, 244, 245, 248, 0, 295, 299, 307, 310, 320, 321, 331, 386, 441, 469, 465, 474, 0, 610, 634, 648, 660, 666, 667, 669, 670, 671, 672, 673, 676, 674, 429, 329, 520, 352, 392, 0, 0, 447, 496, 251, 638, 521, 240, 604, 418, 427, 259, 261, 260, 235, 512, 609, 246, - 266, 207, 0, 0, 0, 0, 270, 271, 0, 605, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 686, + 266, 938, 960, 949, 813, 814, 939, 940, 964, 941, + 816, 817, 961, 962, 810, 811, 815, 963, 965, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 681, 537, 543, - 538, 539, 540, 541, 542, 0, 544, 0, 0, 0, - 0, 0, 419, 0, 623, 624, 704, 403, 510, 635, - 354, 368, 371, 360, 380, 0, 381, 356, 357, 362, - 365, 366, 367, 372, 373, 377, 383, 263, 218, 410, - 420, 608, 330, 224, 225, 226, 553, 554, 555, 556, - 651, 652, 656, 213, 486, 487, 488, 489, 308, 646, - 326, 492, 491, 350, 351, 398, 472, 569, 571, 582, - 586, 588, 590, 596, 599, 570, 572, 583, 587, 589, - 591, 597, 600, 559, 561, 563, 565, 578, 577, 574, - 602, 603, 580, 585, 564, 576, 581, 594, 601, 598, - 558, 562, 566, 575, 593, 592, 573, 584, 595, 579, - 567, 560, 568, 0, 204, 229, 387, 0, 478, 304, - 682, 650, 508, 645, 214, 231, 0, 278, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, + 538, 539, 540, 541, 542, 0, 544, 952, 799, 798, + 0, 805, 806, 0, 835, 836, 838, 844, 845, 846, + 857, 904, 905, 913, 915, 916, 914, 917, 918, 919, + 922, 923, 924, 925, 920, 921, 926, 818, 822, 819, + 820, 821, 833, 823, 824, 825, 826, 827, 828, 829, + 830, 831, 832, 834, 975, 976, 977, 978, 979, 980, + 850, 854, 853, 851, 852, 848, 849, 876, 875, 877, + 878, 879, 880, 881, 882, 884, 883, 885, 886, 887, + 888, 889, 890, 858, 859, 862, 863, 861, 860, 864, + 873, 874, 865, 866, 867, 868, 869, 870, 872, 871, + 891, 892, 893, 894, 895, 897, 896, 900, 901, 899, + 898, 903, 902, 797, 204, 229, 387, 0, 478, 304, + 682, 650, 508, 645, 214, 231, 966, 278, 967, 0, + 0, 971, 0, 0, 0, 973, 972, 0, 974, 936, + 935, 0, 0, 968, 969, 0, 970, 0, 0, 206, 208, 217, 230, 242, 247, 254, 277, 292, 294, 301, 314, 327, 328, 337, 338, 341, 347, 399, 406, 407, 408, 409, 431, 432, 433, 436, 439, 440, 443, 445, @@ -4806,40 +4706,118 @@ var yyAct = [...]int{ 484, 498, 499, 500, 501, 502, 505, 506, 513, 514, 515, 516, 517, 525, 526, 531, 532, 533, 534, 545, 618, 620, 637, 657, 664, 504, 404, 452, 476, 611, - 0, 0, 317, 318, 467, 468, 332, 333, 678, 679, + 0, 0, 981, 982, 983, 984, 985, 986, 987, 988, 316, 632, 665, 629, 677, 659, 461, 397, 0, 0, 400, 297, 322, 339, 0, 649, 527, 236, 490, 306, - 265, 0, 0, 219, 257, 239, 275, 290, 293, 343, + 265, 1056, 0, 219, 257, 239, 275, 290, 293, 343, 411, 421, 451, 457, 312, 287, 255, 483, 252, 509, - 548, 549, 550, 552, 415, 282, 456, 91, 557, 395, - 606, 607, 335, 0, 0, 0, 0, 0, 0, 0, - 438, 0, 0, 0, 0, 0, 0, 0, 286, 0, + 548, 549, 550, 552, 415, 282, 456, 0, 0, 395, + 606, 607, 335, 557, 0, 809, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 438, 0, 0, 0, 796, + 0, 0, 0, 286, 801, 0, 0, 0, 385, 283, + 0, 0, 212, 530, 0, 453, 0, 211, 0, 511, + 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, + 450, 547, 444, 808, 389, 0, 0, 522, 422, 0, + 0, 0, 0, 0, 0, 0, 0, 803, 804, 0, + 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, + 210, 435, 523, 302, 0, 101, 0, 0, 1057, 536, + 991, 1132, 957, 995, 1058, 1009, 1010, 1011, 996, 0, + 249, 997, 998, 256, 999, 0, 956, 839, 841, 840, + 906, 907, 908, 909, 910, 911, 912, 842, 843, 837, + 1004, 641, 1012, 1013, 0, 281, 340, 288, 280, 612, + 0, 0, 0, 0, 0, 0, 628, 0, 0, 238, + 0, 0, 0, 0, 0, 0, 0, 0, 793, 0, + 807, 0, 0, 0, 0, 291, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, + 0, 0, 0, 790, 791, 0, 0, 0, 0, 951, + 0, 792, 0, 0, 800, 1014, 1015, 1016, 1017, 1018, + 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, + 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, + 1049, 1050, 1051, 1052, 1053, 1054, 1055, 2188, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, + 423, 273, 0, 477, 0, 319, 334, 0, 0, 0, + 0, 0, 0, 0, 950, 0, 0, 661, 0, 0, + 948, 0, 0, 0, 0, 384, 0, 349, 205, 233, + 0, 0, 434, 485, 497, 0, 0, 0, 0, 1001, + 0, 495, 448, 636, 243, 300, 482, 455, 493, 463, + 303, 0, 0, 494, 391, 617, 473, 633, 662, 663, + 279, 428, 647, 551, 655, 680, 234, 276, 442, 535, + 639, 519, 417, 613, 614, 348, 518, 311, 209, 388, + 668, 232, 503, 390, 253, 241, 619, 644, 315, 267, + 305, 480, 675, 221, 546, 630, 250, 507, 0, 0, + 683, 258, 529, 642, 631, 223, 626, 528, 413, 345, + 346, 222, 0, 481, 284, 309, 0, 0, 274, 437, + 1002, 1003, 272, 684, 847, 654, 228, 0, 653, 430, + 616, 627, 414, 402, 227, 625, 412, 401, 353, 855, + 856, 296, 324, 932, 931, 930, 323, 325, 928, 929, + 927, 215, 640, 658, 0, 216, 0, 524, 643, 685, + 475, 220, 244, 245, 248, 0, 295, 299, 307, 310, + 320, 321, 331, 386, 441, 469, 465, 474, 0, 610, + 634, 648, 660, 666, 667, 669, 670, 671, 672, 673, + 676, 674, 429, 329, 520, 352, 392, 0, 0, 447, + 496, 251, 638, 521, 240, 604, 418, 427, 259, 261, + 260, 235, 512, 609, 246, 266, 938, 960, 949, 813, + 814, 939, 940, 964, 941, 816, 817, 961, 962, 810, + 811, 815, 963, 965, 686, 687, 688, 689, 690, 691, + 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, + 702, 703, 681, 537, 543, 538, 539, 540, 541, 542, + 0, 544, 952, 799, 798, 0, 805, 806, 0, 835, + 836, 838, 844, 845, 846, 857, 904, 905, 913, 915, + 916, 914, 917, 918, 919, 922, 923, 924, 925, 920, + 921, 926, 818, 822, 819, 820, 821, 833, 823, 824, + 825, 826, 827, 828, 829, 830, 831, 832, 834, 975, + 976, 977, 978, 979, 980, 850, 854, 853, 851, 852, + 848, 849, 876, 875, 877, 878, 879, 880, 881, 882, + 884, 883, 885, 886, 887, 888, 889, 890, 858, 859, + 862, 863, 861, 860, 864, 873, 874, 865, 866, 867, + 868, 869, 870, 872, 871, 891, 892, 893, 894, 895, + 897, 896, 900, 901, 899, 898, 903, 902, 797, 204, + 229, 387, 0, 478, 304, 682, 650, 508, 645, 214, + 231, 966, 278, 967, 0, 0, 971, 0, 0, 0, + 973, 972, 0, 974, 936, 935, 0, 0, 968, 969, + 0, 970, 0, 0, 206, 208, 217, 230, 242, 247, + 254, 277, 292, 294, 301, 314, 327, 328, 337, 338, + 341, 347, 399, 406, 407, 408, 409, 431, 432, 433, + 436, 439, 440, 443, 445, 446, 449, 454, 458, 459, + 460, 462, 464, 466, 479, 484, 498, 499, 500, 501, + 502, 505, 506, 513, 514, 515, 516, 517, 525, 526, + 531, 532, 533, 534, 545, 618, 620, 637, 657, 664, + 504, 404, 452, 476, 611, 0, 0, 981, 982, 983, + 984, 985, 986, 987, 988, 316, 632, 665, 629, 677, + 659, 461, 397, 0, 0, 400, 297, 322, 339, 0, + 649, 527, 236, 490, 306, 265, 1056, 0, 219, 257, + 239, 275, 290, 293, 343, 411, 421, 451, 457, 312, + 287, 255, 483, 252, 509, 548, 549, 550, 552, 415, + 282, 456, 0, 0, 395, 606, 607, 335, 557, 0, + 809, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 438, 0, 0, 0, 796, 0, 0, 0, 286, 801, 0, 0, 0, 385, 283, 0, 0, 212, 530, 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, - 289, 285, 264, 336, 405, 450, 547, 444, 103, 389, + 289, 285, 264, 336, 405, 450, 547, 444, 808, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 803, 804, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, 435, 523, 302, 0, - 101, 0, 0, 0, 536, 202, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, - 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, - 376, 382, 355, 364, 0, 0, 641, 0, 0, 0, + 101, 0, 0, 1057, 536, 991, 1132, 957, 995, 1058, + 1009, 1010, 1011, 996, 0, 249, 997, 998, 256, 999, + 0, 956, 839, 841, 840, 906, 907, 908, 909, 910, + 911, 912, 842, 843, 837, 1004, 641, 1012, 1013, 0, 281, 340, 288, 280, 612, 0, 0, 0, 0, 0, 0, 628, 0, 0, 238, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 793, 0, 807, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 416, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 416, 0, 0, 0, 790, 791, + 0, 0, 0, 0, 951, 0, 792, 0, 0, 800, + 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, + 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, + 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, + 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, + 1054, 1055, 2186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, 423, 273, 0, 477, 0, - 319, 334, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 661, 0, 0, 0, 0, 0, 0, 0, + 319, 334, 0, 0, 0, 0, 0, 0, 0, 950, + 0, 0, 661, 0, 0, 948, 0, 0, 0, 0, 384, 0, 349, 205, 233, 0, 0, 434, 485, 497, - 0, 0, 0, 0, 269, 0, 495, 448, 636, 243, + 0, 0, 0, 0, 1001, 0, 495, 448, 636, 243, 300, 482, 455, 493, 463, 303, 0, 0, 494, 391, 617, 473, 633, 662, 663, 279, 428, 647, 551, 655, 680, 234, 276, 442, 535, 639, 519, 417, 613, 614, @@ -4847,35 +4825,35 @@ var yyAct = [...]int{ 241, 619, 644, 315, 267, 305, 480, 675, 221, 546, 630, 250, 507, 0, 0, 683, 258, 529, 642, 631, 223, 626, 528, 413, 345, 346, 222, 0, 481, 284, - 309, 0, 0, 274, 437, 621, 622, 272, 684, 237, + 309, 0, 0, 274, 437, 1002, 1003, 272, 684, 847, 654, 228, 0, 653, 430, 616, 627, 414, 402, 227, - 625, 412, 401, 353, 374, 375, 296, 324, 470, 394, - 471, 323, 325, 425, 424, 426, 215, 640, 658, 0, + 625, 412, 401, 353, 855, 856, 296, 324, 932, 931, + 930, 323, 325, 928, 929, 927, 215, 640, 658, 0, 216, 0, 524, 643, 685, 475, 220, 244, 245, 248, 0, 295, 299, 307, 310, 320, 321, 331, 386, 441, 469, 465, 474, 0, 610, 634, 648, 660, 666, 667, 669, 670, 671, 672, 673, 676, 674, 429, 329, 520, 352, 392, 0, 0, 447, 496, 251, 638, 521, 240, 604, 418, 427, 259, 261, 260, 235, 512, 609, 246, - 266, 207, 0, 0, 0, 0, 270, 271, 0, 605, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 686, + 266, 938, 960, 949, 813, 814, 939, 940, 964, 941, + 816, 817, 961, 962, 810, 811, 815, 963, 965, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 681, 537, 543, - 538, 539, 540, 541, 542, 0, 544, 0, 0, 0, - 0, 0, 419, 0, 623, 624, 704, 403, 510, 635, - 354, 368, 371, 360, 380, 0, 381, 356, 357, 362, - 365, 366, 367, 372, 373, 377, 383, 263, 218, 410, - 420, 608, 330, 224, 225, 226, 553, 554, 555, 556, - 651, 652, 656, 213, 486, 487, 488, 489, 308, 646, - 326, 492, 491, 350, 351, 398, 472, 569, 571, 582, - 586, 588, 590, 596, 599, 570, 572, 583, 587, 589, - 591, 597, 600, 559, 561, 563, 565, 578, 577, 574, - 602, 603, 580, 585, 564, 576, 581, 594, 601, 598, - 558, 562, 566, 575, 593, 592, 573, 584, 595, 579, - 567, 560, 568, 0, 204, 229, 387, 100, 478, 304, - 682, 650, 508, 645, 214, 231, 0, 278, 0, 0, - 0, 0, 0, 0, 2502, 0, 0, 2501, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, + 538, 539, 540, 541, 542, 0, 544, 952, 799, 798, + 0, 805, 806, 0, 835, 836, 838, 844, 845, 846, + 857, 904, 905, 913, 915, 916, 914, 917, 918, 919, + 922, 923, 924, 925, 920, 921, 926, 818, 822, 819, + 820, 821, 833, 823, 824, 825, 826, 827, 828, 829, + 830, 831, 832, 834, 975, 976, 977, 978, 979, 980, + 850, 854, 853, 851, 852, 848, 849, 876, 875, 877, + 878, 879, 880, 881, 882, 884, 883, 885, 886, 887, + 888, 889, 890, 858, 859, 862, 863, 861, 860, 864, + 873, 874, 865, 866, 867, 868, 869, 870, 872, 871, + 891, 892, 893, 894, 895, 897, 896, 900, 901, 899, + 898, 903, 902, 797, 204, 229, 387, 0, 478, 304, + 682, 650, 508, 645, 214, 231, 966, 278, 967, 0, + 0, 971, 0, 0, 0, 973, 972, 0, 974, 936, + 935, 0, 0, 968, 969, 0, 970, 0, 0, 206, 208, 217, 230, 242, 247, 254, 277, 292, 294, 301, 314, 327, 328, 337, 338, 341, 347, 399, 406, 407, 408, 409, 431, 432, 433, 436, 439, 440, 443, 445, @@ -4883,10 +4861,10 @@ var yyAct = [...]int{ 484, 498, 499, 500, 501, 502, 505, 506, 513, 514, 515, 516, 517, 525, 526, 531, 532, 533, 534, 545, 618, 620, 637, 657, 664, 504, 404, 452, 476, 611, - 0, 0, 317, 318, 467, 468, 332, 333, 678, 679, + 0, 0, 981, 982, 983, 984, 985, 986, 987, 988, 316, 632, 665, 629, 677, 659, 461, 397, 0, 0, 400, 297, 322, 339, 0, 649, 527, 236, 490, 306, - 265, 0, 0, 219, 257, 239, 275, 290, 293, 343, + 265, 1056, 0, 219, 257, 239, 275, 290, 293, 343, 411, 421, 451, 457, 312, 287, 255, 483, 252, 509, 548, 549, 550, 552, 415, 282, 456, 557, 0, 395, 606, 607, 335, 0, 0, 0, 0, 0, 0, 438, @@ -4897,13 +4875,13 @@ var yyAct = [...]int{ 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, 435, 523, 302, 0, 0, - 0, 0, 0, 536, 756, 0, 0, 0, 0, 4390, + 0, 0, 0, 536, 756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, 0, 0, 0, 281, 340, 288, 280, 612, 0, 0, 0, 0, 0, 0, - 628, 0, 0, 238, 0, 0, 0, 0, 0, 0, - 0, 4388, 0, 0, 0, 0, 0, 0, 0, 291, + 628, 0, 0, 238, 0, 1175, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4913,9 +4891,9 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, 423, 273, 0, 477, 0, 319, - 334, 0, 0, 0, 4389, 4257, 4387, 0, 0, 0, - 0, 661, 0, 0, 0, 0, 0, 0, 0, 384, - 0, 349, 205, 233, 0, 0, 434, 485, 497, 0, + 334, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1174, 661, 0, 0, 0, 0, 0, 1171, 1172, 384, + 1140, 349, 205, 233, 1165, 1169, 434, 485, 497, 0, 0, 0, 0, 269, 0, 495, 448, 636, 243, 300, 482, 455, 493, 463, 303, 0, 0, 494, 391, 617, 473, 633, 662, 663, 279, 428, 647, 551, 655, 680, @@ -4974,7 +4952,7 @@ var yyAct = [...]int{ 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, 435, 523, 302, 0, 101, - 0, 1804, 0, 536, 756, 0, 0, 0, 0, 0, + 0, 0, 0, 536, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, 0, 0, 0, 281, @@ -5028,7 +5006,7 @@ var yyAct = [...]int{ 562, 566, 575, 593, 592, 573, 584, 595, 579, 567, 560, 568, 0, 204, 229, 387, 100, 478, 304, 682, 650, 508, 645, 214, 231, 0, 278, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2508, 0, 0, 2507, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 208, 217, 230, 242, 247, 254, 277, 292, 294, 301, 314, 327, 328, 337, 338, 341, 347, 399, 406, 407, 408, @@ -5044,22 +5022,99 @@ var yyAct = [...]int{ 421, 451, 457, 312, 287, 255, 483, 252, 509, 548, 549, 550, 552, 415, 282, 456, 557, 0, 395, 606, 607, 335, 0, 0, 0, 0, 0, 0, 438, 0, - 0, 1846, 0, 0, 0, 0, 286, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 286, 0, 0, 0, 0, 385, 283, 0, 0, 212, 530, 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, 450, 547, 444, 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, 435, 523, 302, 0, 0, 0, - 0, 1848, 536, 756, 0, 0, 0, 0, 0, 0, + 0, 0, 536, 756, 0, 0, 0, 0, 4398, 0, + 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, + 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, + 355, 364, 0, 0, 641, 0, 0, 0, 281, 340, + 288, 280, 612, 0, 0, 0, 0, 0, 0, 628, + 0, 0, 238, 0, 0, 0, 0, 0, 0, 0, + 4396, 0, 0, 0, 0, 0, 0, 0, 291, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 416, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 313, 0, 423, 273, 0, 477, 0, 319, 334, + 0, 0, 0, 4397, 4265, 4395, 0, 0, 0, 0, + 661, 0, 0, 0, 0, 0, 0, 0, 384, 0, + 349, 205, 233, 0, 0, 434, 485, 497, 0, 0, + 0, 0, 269, 0, 495, 448, 636, 243, 300, 482, + 455, 493, 463, 303, 0, 0, 494, 391, 617, 473, + 633, 662, 663, 279, 428, 647, 551, 655, 680, 234, + 276, 442, 535, 639, 519, 417, 613, 614, 348, 518, + 311, 209, 388, 668, 232, 503, 390, 253, 241, 619, + 644, 315, 267, 305, 480, 675, 221, 546, 630, 250, + 507, 0, 0, 683, 258, 529, 642, 631, 223, 626, + 528, 413, 345, 346, 222, 0, 481, 284, 309, 0, + 0, 274, 437, 621, 622, 272, 684, 237, 654, 228, + 0, 653, 430, 616, 627, 414, 402, 227, 625, 412, + 401, 353, 374, 375, 296, 324, 470, 394, 471, 323, + 325, 425, 424, 426, 215, 640, 658, 0, 216, 0, + 524, 643, 685, 475, 220, 244, 245, 248, 0, 295, + 299, 307, 310, 320, 321, 331, 386, 441, 469, 465, + 474, 0, 610, 634, 648, 660, 666, 667, 669, 670, + 671, 672, 673, 676, 674, 429, 329, 520, 352, 392, + 0, 0, 447, 496, 251, 638, 521, 240, 604, 418, + 427, 259, 261, 260, 235, 512, 609, 246, 266, 207, + 0, 0, 0, 0, 270, 271, 0, 605, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 686, 687, 688, + 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, + 699, 700, 701, 702, 703, 681, 537, 543, 538, 539, + 540, 541, 542, 0, 544, 0, 0, 0, 0, 0, + 419, 0, 623, 624, 704, 403, 510, 635, 354, 368, + 371, 360, 380, 0, 381, 356, 357, 362, 365, 366, + 367, 372, 373, 377, 383, 263, 218, 410, 420, 608, + 330, 224, 225, 226, 553, 554, 555, 556, 651, 652, + 656, 213, 486, 487, 488, 489, 308, 646, 326, 492, + 491, 350, 351, 398, 472, 569, 571, 582, 586, 588, + 590, 596, 599, 570, 572, 583, 587, 589, 591, 597, + 600, 559, 561, 563, 565, 578, 577, 574, 602, 603, + 580, 585, 564, 576, 581, 594, 601, 598, 558, 562, + 566, 575, 593, 592, 573, 584, 595, 579, 567, 560, + 568, 0, 204, 229, 387, 0, 478, 304, 682, 650, + 508, 645, 214, 231, 0, 278, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 206, 208, 217, + 230, 242, 247, 254, 277, 292, 294, 301, 314, 327, + 328, 337, 338, 341, 347, 399, 406, 407, 408, 409, + 431, 432, 433, 436, 439, 440, 443, 445, 446, 449, + 454, 458, 459, 460, 462, 464, 466, 479, 484, 498, + 499, 500, 501, 502, 505, 506, 513, 514, 515, 516, + 517, 525, 526, 531, 532, 533, 534, 545, 618, 620, + 637, 657, 664, 504, 404, 452, 476, 611, 0, 0, + 317, 318, 467, 468, 332, 333, 678, 679, 316, 632, + 665, 629, 677, 659, 461, 397, 0, 0, 400, 297, + 322, 339, 0, 649, 527, 236, 490, 306, 265, 0, + 0, 219, 257, 239, 275, 290, 293, 343, 411, 421, + 451, 457, 312, 287, 255, 483, 252, 509, 548, 549, + 550, 552, 415, 282, 456, 91, 557, 395, 606, 607, + 335, 0, 0, 0, 0, 0, 0, 0, 438, 0, + 0, 0, 0, 0, 0, 0, 286, 0, 0, 0, + 0, 385, 283, 0, 0, 212, 530, 0, 453, 0, + 211, 0, 511, 268, 396, 393, 615, 298, 289, 285, + 264, 336, 405, 450, 547, 444, 103, 389, 0, 0, + 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 342, 262, 344, 210, 435, 523, 302, 0, 101, 0, + 1805, 0, 536, 756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, 0, 0, 0, 281, 340, 288, 280, 612, 0, 0, 0, 0, 0, 0, 628, - 0, 0, 238, 0, 0, 0, 1529, 0, 1530, 1531, + 0, 0, 238, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1844, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5103,7 +5158,7 @@ var yyAct = [...]int{ 600, 559, 561, 563, 565, 578, 577, 574, 602, 603, 580, 585, 564, 576, 581, 594, 601, 598, 558, 562, 566, 575, 593, 592, 573, 584, 595, 579, 567, 560, - 568, 0, 204, 229, 387, 0, 478, 304, 682, 650, + 568, 0, 204, 229, 387, 100, 478, 304, 682, 650, 508, 645, 214, 231, 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 208, 217, @@ -5121,30 +5176,30 @@ var yyAct = [...]int{ 451, 457, 312, 287, 255, 483, 252, 509, 548, 549, 550, 552, 415, 282, 456, 557, 0, 395, 606, 607, 335, 0, 0, 0, 0, 0, 0, 438, 0, 0, - 0, 0, 0, 0, 0, 286, 0, 0, 0, 0, + 1848, 0, 0, 0, 0, 286, 0, 0, 0, 0, 385, 283, 0, 0, 212, 530, 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, 450, 547, 444, 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, 435, 523, 302, 0, 0, 0, 0, - 0, 536, 756, 0, 0, 0, 0, 0, 0, 0, + 1850, 536, 756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, 0, 0, 0, 281, 340, 288, 280, 612, 0, 0, 0, 0, 0, 0, 628, 0, - 0, 238, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 238, 0, 0, 0, 1530, 0, 1531, 1532, 0, 0, 0, 0, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 416, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1846, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 313, 0, 423, 273, 0, 477, 0, 319, 334, 4251, - 4252, 4253, 0, 0, 0, 0, 0, 0, 0, 661, + 313, 0, 423, 273, 0, 477, 0, 319, 334, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 661, 0, 0, 0, 0, 0, 0, 0, 384, 0, 349, 205, 233, 0, 0, 434, 485, 497, 0, 0, 0, 0, 269, 0, 495, 448, 636, 243, 300, 482, 455, @@ -5204,8 +5259,8 @@ var yyAct = [...]int{ 405, 450, 547, 444, 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, - 344, 210, 435, 523, 302, 0, 101, 0, 0, 0, - 536, 202, 0, 0, 0, 0, 0, 0, 0, 0, + 344, 210, 435, 523, 302, 0, 0, 0, 0, 0, + 536, 756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, 0, 0, 0, 281, 340, 288, 280, @@ -5220,8 +5275,8 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, - 0, 423, 273, 0, 477, 0, 319, 334, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 661, 0, + 0, 423, 273, 0, 477, 0, 319, 334, 4259, 4260, + 4261, 0, 0, 0, 0, 0, 0, 0, 661, 0, 0, 0, 0, 0, 0, 0, 384, 0, 349, 205, 233, 0, 0, 434, 485, 497, 0, 0, 0, 0, 269, 0, 495, 448, 636, 243, 300, 482, 455, 493, @@ -5259,7 +5314,7 @@ var yyAct = [...]int{ 593, 592, 573, 584, 595, 579, 567, 560, 568, 0, 204, 229, 387, 0, 478, 304, 682, 650, 508, 645, 214, 231, 0, 278, 0, 0, 0, 0, 0, 0, - 2502, 0, 0, 2501, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 208, 217, 230, 242, 247, 254, 277, 292, 294, 301, 314, 327, 328, 337, 338, 341, 347, 399, 406, 407, 408, 409, 431, 432, @@ -5274,14 +5329,14 @@ var yyAct = [...]int{ 257, 239, 275, 290, 293, 343, 411, 421, 451, 457, 312, 287, 255, 483, 252, 509, 548, 549, 550, 552, 415, 282, 456, 557, 0, 395, 606, 607, 335, 0, - 0, 0, 0, 0, 0, 438, 0, 0, 2434, 0, + 0, 0, 0, 0, 0, 438, 0, 0, 0, 0, 0, 0, 0, 286, 0, 0, 0, 0, 385, 283, 0, 0, 212, 530, 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, 450, 547, 444, 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, - 210, 435, 523, 302, 0, 0, 0, 0, 2023, 536, + 210, 435, 523, 302, 0, 101, 0, 0, 0, 536, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, @@ -5302,7 +5357,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 384, 0, 349, 205, 233, 0, 0, 434, 485, 497, 0, 0, 0, 0, 269, 0, 495, 448, 636, 243, 300, 482, 455, 493, 463, - 303, 0, 2432, 494, 391, 617, 473, 633, 662, 663, + 303, 0, 0, 494, 391, 617, 473, 633, 662, 663, 279, 428, 647, 551, 655, 680, 234, 276, 442, 535, 639, 519, 417, 613, 614, 348, 518, 311, 209, 388, 668, 232, 503, 390, 253, 241, 619, 644, 315, 267, @@ -5335,8 +5390,8 @@ var yyAct = [...]int{ 576, 581, 594, 601, 598, 558, 562, 566, 575, 593, 592, 573, 584, 595, 579, 567, 560, 568, 0, 204, 229, 387, 0, 478, 304, 682, 650, 508, 645, 214, - 231, 0, 278, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 231, 0, 278, 0, 0, 0, 0, 0, 0, 2508, + 0, 0, 2507, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 208, 217, 230, 242, 247, 254, 277, 292, 294, 301, 314, 327, 328, 337, 338, 341, 347, 399, 406, 407, 408, 409, 431, 432, 433, @@ -5351,14 +5406,14 @@ var yyAct = [...]int{ 239, 275, 290, 293, 343, 411, 421, 451, 457, 312, 287, 255, 483, 252, 509, 548, 549, 550, 552, 415, 282, 456, 557, 0, 395, 606, 607, 335, 0, 0, - 0, 0, 0, 0, 438, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 438, 0, 0, 2437, 0, 0, 0, 0, 286, 0, 0, 0, 0, 385, 283, 0, 0, 212, 530, 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, 450, 547, 444, 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, - 435, 523, 302, 0, 0, 0, 0, 0, 536, 756, + 435, 523, 302, 0, 0, 0, 0, 2026, 536, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, @@ -5366,7 +5421,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 628, 0, 0, 238, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, - 0, 0, 0, 1133, 0, 0, 0, 0, 416, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5376,10 +5431,10 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 313, 0, 423, 273, 0, 477, 0, 319, 334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 661, 0, 0, 0, - 0, 0, 0, 0, 384, 1139, 349, 205, 233, 1137, + 0, 0, 0, 0, 384, 0, 349, 205, 233, 0, 0, 434, 485, 497, 0, 0, 0, 0, 269, 0, 495, 448, 636, 243, 300, 482, 455, 493, 463, 303, - 0, 0, 494, 391, 617, 473, 633, 662, 663, 279, + 0, 2435, 494, 391, 617, 473, 633, 662, 663, 279, 428, 647, 551, 655, 680, 234, 276, 442, 535, 639, 519, 417, 613, 614, 348, 518, 311, 209, 388, 668, 232, 503, 390, 253, 241, 619, 644, 315, 267, 305, @@ -5428,14 +5483,14 @@ var yyAct = [...]int{ 275, 290, 293, 343, 411, 421, 451, 457, 312, 287, 255, 483, 252, 509, 548, 549, 550, 552, 415, 282, 456, 557, 0, 395, 606, 607, 335, 0, 0, 0, - 0, 0, 0, 438, 0, 0, 2434, 0, 0, 0, + 0, 0, 0, 438, 0, 0, 0, 0, 0, 0, 0, 286, 0, 0, 0, 0, 385, 283, 0, 0, 212, 530, 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, 450, 547, 444, 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, 435, - 523, 302, 0, 0, 0, 0, 2023, 536, 202, 0, + 523, 302, 0, 0, 0, 0, 0, 536, 756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, @@ -5443,7 +5498,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 628, 0, 0, 238, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 416, 0, 0, + 0, 0, 1134, 0, 0, 0, 0, 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5453,7 +5508,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 313, 0, 423, 273, 0, 477, 0, 319, 334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 661, 0, 0, 0, 0, - 0, 0, 0, 384, 0, 349, 205, 233, 0, 0, + 0, 0, 0, 384, 1140, 349, 205, 233, 1138, 0, 434, 485, 497, 0, 0, 0, 0, 269, 0, 495, 448, 636, 243, 300, 482, 455, 493, 463, 303, 0, 0, 494, 391, 617, 473, 633, 662, 663, 279, 428, @@ -5505,14 +5560,14 @@ var yyAct = [...]int{ 290, 293, 343, 411, 421, 451, 457, 312, 287, 255, 483, 252, 509, 548, 549, 550, 552, 415, 282, 456, 557, 0, 395, 606, 607, 335, 0, 0, 0, 0, - 0, 0, 438, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 438, 0, 0, 2437, 0, 0, 0, 0, 286, 0, 0, 0, 0, 385, 283, 0, 0, 212, 530, 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, 450, 547, 444, 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, 435, 523, - 302, 0, 0, 0, 1804, 0, 536, 756, 0, 0, + 302, 0, 0, 0, 0, 2026, 536, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, 0, @@ -5529,7 +5584,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, 423, 273, 0, 477, 0, 319, 334, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 661, 0, 0, 0, 3817, 0, + 0, 0, 0, 0, 661, 0, 0, 0, 0, 0, 0, 0, 384, 0, 349, 205, 233, 0, 0, 434, 485, 497, 0, 0, 0, 0, 269, 0, 495, 448, 636, 243, 300, 482, 455, 493, 463, 303, 0, 0, @@ -5589,7 +5644,7 @@ var yyAct = [...]int{ 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, 435, 523, 302, - 0, 0, 0, 0, 2194, 536, 756, 0, 0, 0, + 0, 0, 0, 1805, 0, 536, 756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, 0, 0, @@ -5599,14 +5654,14 @@ var yyAct = [...]int{ 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2195, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, 423, 273, 0, 477, 0, 319, 334, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 661, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 661, 0, 0, 0, 3825, 0, 0, 0, 384, 0, 349, 205, 233, 0, 0, 434, 485, 497, 0, 0, 0, 0, 269, 0, 495, 448, 636, 243, 300, 482, 455, 493, 463, 303, 0, 0, 494, @@ -5666,7 +5721,7 @@ var yyAct = [...]int{ 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, 435, 523, 302, 0, - 0, 0, 0, 2968, 536, 756, 0, 0, 0, 0, + 0, 0, 0, 2197, 536, 756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, 0, 0, 0, @@ -5675,7 +5730,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2969, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5743,8 +5798,8 @@ var yyAct = [...]int{ 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, 435, 523, 302, 0, 0, - 0, 0, 0, 536, 756, 0, 0, 0, 0, 2935, - 0, 0, 0, 0, 249, 0, 0, 256, 2936, 0, + 0, 0, 2974, 536, 756, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, 0, 0, 0, 281, 340, 288, 280, 612, 0, 0, 0, 0, 0, 0, @@ -5752,7 +5807,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5813,15 +5868,15 @@ var yyAct = [...]int{ 421, 451, 457, 312, 287, 255, 483, 252, 509, 548, 549, 550, 552, 415, 282, 456, 557, 0, 395, 606, 607, 335, 0, 0, 0, 0, 0, 0, 438, 0, - 0, 0, 0, 0, 0, 0, 286, 1867, 0, 0, + 0, 0, 0, 0, 0, 0, 286, 0, 0, 0, 0, 385, 283, 0, 0, 212, 530, 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, 450, 547, 444, 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, 435, 523, 302, 0, 0, 0, - 0, 1866, 536, 756, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, + 0, 0, 536, 756, 0, 0, 0, 0, 2941, 0, + 0, 0, 0, 249, 0, 0, 256, 2942, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, 0, 0, 0, 281, 340, 288, 280, 612, 0, 0, 0, 0, 0, 0, 628, @@ -5890,14 +5945,14 @@ var yyAct = [...]int{ 451, 457, 312, 287, 255, 483, 252, 509, 548, 549, 550, 552, 415, 282, 456, 557, 0, 395, 606, 607, 335, 0, 0, 0, 0, 0, 0, 438, 0, 0, - 0, 0, 0, 0, 0, 286, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 286, 1870, 0, 0, 0, 385, 283, 0, 0, 212, 530, 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, 450, 547, 444, 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, 435, 523, 302, 0, 0, 0, 0, - 0, 536, 758, 759, 760, 0, 0, 0, 0, 0, + 1869, 536, 756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, 0, 0, 0, 281, 340, 288, @@ -5974,7 +6029,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, 435, 523, 302, 0, 0, 0, 0, 0, - 536, 756, 0, 0, 0, 0, 0, 0, 0, 0, + 536, 758, 759, 760, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, 0, 0, 0, 281, 340, 288, 280, @@ -5990,7 +6045,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, 423, 273, 0, 477, 0, 319, 334, 0, 0, - 0, 0, 4257, 0, 0, 0, 0, 0, 661, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 661, 0, 0, 0, 0, 0, 0, 0, 384, 0, 349, 205, 233, 0, 0, 434, 485, 497, 0, 0, 0, 0, 269, 0, 495, 448, 636, 243, 300, 482, 455, 493, @@ -6067,8 +6122,8 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, 423, 273, 0, 477, 0, 319, 334, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 661, 0, 0, - 0, 4173, 0, 0, 0, 384, 0, 349, 205, 233, + 0, 4265, 0, 0, 0, 0, 0, 661, 0, 0, + 0, 0, 0, 0, 0, 384, 0, 349, 205, 233, 0, 0, 434, 485, 497, 0, 0, 0, 0, 269, 0, 495, 448, 636, 243, 300, 482, 455, 493, 463, 303, 0, 0, 494, 391, 617, 473, 633, 662, 663, @@ -6127,7 +6182,7 @@ var yyAct = [...]int{ 547, 444, 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, - 435, 523, 302, 0, 0, 0, 0, 2023, 536, 202, + 435, 523, 302, 0, 0, 0, 0, 0, 536, 756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, @@ -6145,7 +6200,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 313, 0, 423, 273, 0, 477, 0, 319, 334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 661, 0, 0, 0, - 0, 0, 0, 0, 384, 0, 349, 205, 233, 0, + 4181, 0, 0, 0, 384, 0, 349, 205, 233, 0, 0, 434, 485, 497, 0, 0, 0, 0, 269, 0, 495, 448, 636, 243, 300, 482, 455, 493, 463, 303, 0, 0, 494, 391, 617, 473, 633, 662, 663, 279, @@ -6204,7 +6259,7 @@ var yyAct = [...]int{ 444, 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, 435, - 523, 302, 0, 0, 0, 0, 0, 536, 756, 0, + 523, 302, 0, 0, 0, 0, 2026, 536, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, @@ -6221,7 +6276,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, 423, 273, 0, 477, 0, 319, 334, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 661, 0, 0, 0, 3817, + 0, 0, 0, 0, 0, 661, 0, 0, 0, 0, 0, 0, 0, 384, 0, 349, 205, 233, 0, 0, 434, 485, 497, 0, 0, 0, 0, 269, 0, 495, 448, 636, 243, 300, 482, 455, 493, 463, 303, 0, @@ -6269,88 +6324,11 @@ var yyAct = [...]int{ 533, 534, 545, 618, 620, 637, 657, 664, 504, 404, 452, 476, 611, 0, 0, 317, 318, 467, 468, 332, 333, 678, 679, 316, 632, 665, 629, 677, 659, 461, - 397, 0, 0, 400, 297, 322, 339, 0, 649, 527, - 236, 490, 306, 265, 0, 0, 219, 257, 239, 275, - 290, 293, 343, 411, 421, 451, 457, 312, 287, 255, - 483, 252, 509, 548, 549, 550, 552, 415, 282, 456, - 557, 0, 395, 606, 607, 335, 0, 0, 0, 0, - 0, 0, 438, 0, 0, 0, 0, 0, 0, 0, - 286, 0, 0, 0, 0, 385, 283, 0, 0, 212, - 530, 0, 453, 0, 211, 0, 511, 268, 396, 393, - 615, 298, 289, 285, 264, 336, 405, 450, 547, 444, - 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 342, 262, 344, 210, 435, 523, - 302, 0, 101, 0, 0, 0, 536, 756, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, - 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, - 363, 369, 376, 382, 355, 364, 0, 0, 641, 0, - 0, 0, 281, 340, 288, 280, 612, 0, 0, 0, - 0, 0, 0, 628, 0, 0, 238, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 416, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 313, 0, 423, 273, 0, - 477, 0, 319, 334, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 661, 0, 0, 0, 0, 0, - 0, 0, 384, 0, 349, 205, 233, 0, 0, 434, - 485, 497, 0, 0, 0, 0, 269, 0, 495, 448, - 636, 243, 300, 482, 455, 493, 463, 303, 0, 0, - 494, 391, 617, 473, 633, 662, 663, 279, 428, 647, - 551, 655, 680, 234, 276, 442, 535, 639, 519, 417, - 613, 614, 348, 518, 311, 209, 388, 668, 232, 503, - 390, 253, 241, 619, 644, 315, 267, 305, 480, 675, - 221, 546, 630, 250, 507, 0, 0, 683, 258, 529, - 642, 631, 223, 626, 528, 413, 345, 346, 222, 0, - 481, 284, 309, 0, 0, 274, 437, 621, 622, 272, - 684, 237, 654, 228, 0, 653, 430, 616, 627, 414, - 402, 227, 625, 412, 401, 353, 374, 375, 296, 324, - 470, 394, 471, 323, 325, 425, 424, 426, 215, 640, - 658, 0, 216, 0, 524, 643, 685, 475, 220, 244, - 245, 248, 0, 295, 299, 307, 310, 320, 321, 331, - 386, 441, 469, 465, 474, 0, 610, 634, 648, 660, - 666, 667, 669, 670, 671, 672, 673, 676, 674, 429, - 329, 520, 352, 392, 0, 0, 447, 496, 251, 638, - 521, 240, 604, 418, 427, 259, 261, 260, 235, 512, - 609, 246, 266, 207, 0, 0, 0, 0, 270, 271, - 0, 605, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 686, 687, 688, 689, 690, 691, 692, 693, 694, - 695, 696, 697, 698, 699, 700, 701, 702, 703, 681, - 537, 543, 538, 539, 540, 541, 542, 0, 544, 0, - 0, 0, 0, 0, 419, 0, 623, 624, 704, 403, - 510, 635, 354, 368, 371, 360, 380, 0, 381, 356, - 357, 362, 365, 366, 367, 372, 373, 377, 383, 263, - 218, 410, 420, 608, 330, 224, 225, 226, 553, 554, - 555, 556, 651, 652, 656, 213, 486, 487, 488, 489, - 308, 646, 326, 492, 491, 350, 351, 398, 472, 569, - 571, 582, 586, 588, 590, 596, 599, 570, 572, 583, - 587, 589, 591, 597, 600, 559, 561, 563, 565, 578, - 577, 574, 602, 603, 580, 585, 564, 576, 581, 594, - 601, 598, 558, 562, 566, 575, 593, 592, 573, 584, - 595, 579, 567, 560, 568, 0, 204, 229, 387, 0, - 478, 304, 682, 650, 508, 645, 214, 231, 0, 278, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 206, 208, 217, 230, 242, 247, 254, 277, 292, - 294, 301, 314, 327, 328, 337, 338, 341, 347, 399, - 406, 407, 408, 409, 431, 432, 433, 436, 439, 440, - 443, 445, 446, 449, 454, 458, 459, 460, 462, 464, - 466, 479, 484, 498, 499, 500, 501, 502, 505, 506, - 513, 514, 515, 516, 517, 525, 526, 531, 532, 533, - 534, 545, 618, 620, 637, 657, 664, 504, 404, 452, - 476, 611, 0, 0, 317, 318, 467, 468, 332, 333, - 678, 679, 316, 632, 665, 629, 677, 659, 461, 397, - 0, 0, 400, 297, 322, 339, 0, 649, 527, 236, - 490, 306, 265, 0, 0, 219, 257, 239, 275, 290, - 293, 343, 411, 421, 451, 457, 312, 287, 255, 483, - 252, 509, 548, 549, 550, 552, 415, 282, 456, 0, - 557, 395, 606, 607, 335, 2503, 0, 0, 0, 0, + 397, 0, 0, 400, 297, 322, 339, 0, 649, 527, + 236, 490, 306, 265, 0, 0, 219, 257, 239, 275, + 290, 293, 343, 411, 421, 451, 457, 312, 287, 255, + 483, 252, 509, 548, 549, 550, 552, 415, 282, 456, + 557, 0, 395, 606, 607, 335, 0, 0, 0, 0, 0, 0, 438, 0, 0, 0, 0, 0, 0, 0, 286, 0, 0, 0, 0, 385, 283, 0, 0, 212, 530, 0, 453, 0, 211, 0, 511, 268, 396, 393, @@ -6358,7 +6336,7 @@ var yyAct = [...]int{ 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, 435, 523, - 302, 0, 0, 0, 0, 0, 536, 202, 0, 0, + 302, 0, 0, 0, 0, 0, 536, 756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, 0, @@ -6375,7 +6353,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, 423, 273, 0, 477, 0, 319, 334, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 661, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 661, 0, 0, 0, 3825, 0, 0, 0, 384, 0, 349, 205, 233, 0, 0, 434, 485, 497, 0, 0, 0, 0, 269, 0, 495, 448, 636, 243, 300, 482, 455, 493, 463, 303, 0, 0, @@ -6435,7 +6413,84 @@ var yyAct = [...]int{ 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, 435, 523, 302, - 0, 0, 0, 0, 1848, 536, 756, 0, 0, 0, + 0, 101, 0, 0, 0, 536, 756, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, + 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, + 369, 376, 382, 355, 364, 0, 0, 641, 0, 0, + 0, 281, 340, 288, 280, 612, 0, 0, 0, 0, + 0, 0, 628, 0, 0, 238, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 416, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 313, 0, 423, 273, 0, 477, + 0, 319, 334, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 661, 0, 0, 0, 0, 0, 0, + 0, 384, 0, 349, 205, 233, 0, 0, 434, 485, + 497, 0, 0, 0, 0, 269, 0, 495, 448, 636, + 243, 300, 482, 455, 493, 463, 303, 0, 0, 494, + 391, 617, 473, 633, 662, 663, 279, 428, 647, 551, + 655, 680, 234, 276, 442, 535, 639, 519, 417, 613, + 614, 348, 518, 311, 209, 388, 668, 232, 503, 390, + 253, 241, 619, 644, 315, 267, 305, 480, 675, 221, + 546, 630, 250, 507, 0, 0, 683, 258, 529, 642, + 631, 223, 626, 528, 413, 345, 346, 222, 0, 481, + 284, 309, 0, 0, 274, 437, 621, 622, 272, 684, + 237, 654, 228, 0, 653, 430, 616, 627, 414, 402, + 227, 625, 412, 401, 353, 374, 375, 296, 324, 470, + 394, 471, 323, 325, 425, 424, 426, 215, 640, 658, + 0, 216, 0, 524, 643, 685, 475, 220, 244, 245, + 248, 0, 295, 299, 307, 310, 320, 321, 331, 386, + 441, 469, 465, 474, 0, 610, 634, 648, 660, 666, + 667, 669, 670, 671, 672, 673, 676, 674, 429, 329, + 520, 352, 392, 0, 0, 447, 496, 251, 638, 521, + 240, 604, 418, 427, 259, 261, 260, 235, 512, 609, + 246, 266, 207, 0, 0, 0, 0, 270, 271, 0, + 605, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, + 696, 697, 698, 699, 700, 701, 702, 703, 681, 537, + 543, 538, 539, 540, 541, 542, 0, 544, 0, 0, + 0, 0, 0, 419, 0, 623, 624, 704, 403, 510, + 635, 354, 368, 371, 360, 380, 0, 381, 356, 357, + 362, 365, 366, 367, 372, 373, 377, 383, 263, 218, + 410, 420, 608, 330, 224, 225, 226, 553, 554, 555, + 556, 651, 652, 656, 213, 486, 487, 488, 489, 308, + 646, 326, 492, 491, 350, 351, 398, 472, 569, 571, + 582, 586, 588, 590, 596, 599, 570, 572, 583, 587, + 589, 591, 597, 600, 559, 561, 563, 565, 578, 577, + 574, 602, 603, 580, 585, 564, 576, 581, 594, 601, + 598, 558, 562, 566, 575, 593, 592, 573, 584, 595, + 579, 567, 560, 568, 0, 204, 229, 387, 0, 478, + 304, 682, 650, 508, 645, 214, 231, 0, 278, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 206, 208, 217, 230, 242, 247, 254, 277, 292, 294, + 301, 314, 327, 328, 337, 338, 341, 347, 399, 406, + 407, 408, 409, 431, 432, 433, 436, 439, 440, 443, + 445, 446, 449, 454, 458, 459, 460, 462, 464, 466, + 479, 484, 498, 499, 500, 501, 502, 505, 506, 513, + 514, 515, 516, 517, 525, 526, 531, 532, 533, 534, + 545, 618, 620, 637, 657, 664, 504, 404, 452, 476, + 611, 0, 0, 317, 318, 467, 468, 332, 333, 678, + 679, 316, 632, 665, 629, 677, 659, 461, 397, 0, + 0, 400, 297, 322, 339, 0, 649, 527, 236, 490, + 306, 265, 0, 0, 219, 257, 239, 275, 290, 293, + 343, 411, 421, 451, 457, 312, 287, 255, 483, 252, + 509, 548, 549, 550, 552, 415, 282, 456, 0, 557, + 395, 606, 607, 335, 2509, 0, 0, 0, 0, 0, + 0, 438, 0, 0, 0, 0, 0, 0, 0, 286, + 0, 0, 0, 0, 385, 283, 0, 0, 212, 530, + 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, + 298, 289, 285, 264, 336, 405, 450, 547, 444, 0, + 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 342, 262, 344, 210, 435, 523, 302, + 0, 0, 0, 0, 0, 536, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, 0, 0, @@ -6512,7 +6567,7 @@ var yyAct = [...]int{ 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, 435, 523, 302, 0, - 0, 0, 0, 0, 536, 202, 0, 0, 0, 0, + 0, 0, 0, 1850, 536, 756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, 0, 0, 0, @@ -6564,7 +6619,7 @@ var yyAct = [...]int{ 591, 597, 600, 559, 561, 563, 565, 578, 577, 574, 602, 603, 580, 585, 564, 576, 581, 594, 601, 598, 558, 562, 566, 575, 593, 592, 573, 584, 595, 579, - 567, 560, 568, 0, 204, 229, 387, 2141, 478, 304, + 567, 560, 568, 0, 204, 229, 387, 0, 478, 304, 682, 650, 508, 645, 214, 231, 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, @@ -6589,7 +6644,7 @@ var yyAct = [...]int{ 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, 435, 523, 302, 0, 0, - 0, 0, 2132, 536, 756, 0, 0, 0, 0, 0, + 0, 0, 0, 536, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, 0, 0, 0, 281, @@ -6641,7 +6696,7 @@ var yyAct = [...]int{ 597, 600, 559, 561, 563, 565, 578, 577, 574, 602, 603, 580, 585, 564, 576, 581, 594, 601, 598, 558, 562, 566, 575, 593, 592, 573, 584, 595, 579, 567, - 560, 568, 0, 204, 229, 387, 0, 478, 304, 682, + 560, 568, 0, 204, 229, 387, 2144, 478, 304, 682, 650, 508, 645, 214, 231, 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 208, @@ -6660,13 +6715,13 @@ var yyAct = [...]int{ 549, 550, 552, 415, 282, 456, 557, 0, 395, 606, 607, 335, 0, 0, 0, 0, 0, 0, 438, 0, 0, 0, 0, 0, 0, 0, 286, 0, 0, 0, - 0, 385, 283, 0, 1990, 212, 530, 0, 453, 0, + 0, 385, 283, 0, 0, 212, 530, 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, 450, 547, 444, 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, 435, 523, 302, 0, 0, 0, - 0, 0, 536, 756, 0, 0, 0, 0, 0, 0, + 0, 2135, 536, 756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, 0, 0, 0, 281, 340, @@ -6737,7 +6792,7 @@ var yyAct = [...]int{ 550, 552, 415, 282, 456, 557, 0, 395, 606, 607, 335, 0, 0, 0, 0, 0, 0, 438, 0, 0, 0, 0, 0, 0, 0, 286, 0, 0, 0, 0, - 385, 283, 0, 1988, 212, 530, 0, 453, 0, 211, + 385, 283, 0, 1993, 212, 530, 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, 450, 547, 444, 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6814,7 +6869,7 @@ var yyAct = [...]int{ 552, 415, 282, 456, 557, 0, 395, 606, 607, 335, 0, 0, 0, 0, 0, 0, 438, 0, 0, 0, 0, 0, 0, 0, 286, 0, 0, 0, 0, 385, - 283, 0, 1986, 212, 530, 0, 453, 0, 211, 0, + 283, 0, 1991, 212, 530, 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, 450, 547, 444, 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6891,7 +6946,7 @@ var yyAct = [...]int{ 415, 282, 456, 557, 0, 395, 606, 607, 335, 0, 0, 0, 0, 0, 0, 438, 0, 0, 0, 0, 0, 0, 0, 286, 0, 0, 0, 0, 385, 283, - 0, 1984, 212, 530, 0, 453, 0, 211, 0, 511, + 0, 1989, 212, 530, 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, 450, 547, 444, 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6968,7 +7023,7 @@ var yyAct = [...]int{ 282, 456, 557, 0, 395, 606, 607, 335, 0, 0, 0, 0, 0, 0, 438, 0, 0, 0, 0, 0, 0, 0, 286, 0, 0, 0, 0, 385, 283, 0, - 1982, 212, 530, 0, 453, 0, 211, 0, 511, 268, + 1987, 212, 530, 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, 450, 547, 444, 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7044,7 +7099,7 @@ var yyAct = [...]int{ 255, 483, 252, 509, 548, 549, 550, 552, 415, 282, 456, 557, 0, 395, 606, 607, 335, 0, 0, 0, 0, 0, 0, 438, 0, 0, 0, 0, 0, 0, - 0, 286, 0, 0, 0, 0, 385, 283, 0, 1978, + 0, 286, 0, 0, 0, 0, 385, 283, 0, 1985, 212, 530, 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, 450, 547, 444, 0, 389, 0, 0, 522, 422, 0, 0, 0, @@ -7121,7 +7176,7 @@ var yyAct = [...]int{ 483, 252, 509, 548, 549, 550, 552, 415, 282, 456, 557, 0, 395, 606, 607, 335, 0, 0, 0, 0, 0, 0, 438, 0, 0, 0, 0, 0, 0, 0, - 286, 0, 0, 0, 0, 385, 283, 0, 1976, 212, + 286, 0, 0, 0, 0, 385, 283, 0, 1981, 212, 530, 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, 450, 547, 444, 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, @@ -7198,7 +7253,7 @@ var yyAct = [...]int{ 252, 509, 548, 549, 550, 552, 415, 282, 456, 557, 0, 395, 606, 607, 335, 0, 0, 0, 0, 0, 0, 438, 0, 0, 0, 0, 0, 0, 0, 286, - 0, 0, 0, 0, 385, 283, 0, 1974, 212, 530, + 0, 0, 0, 0, 385, 283, 0, 1979, 212, 530, 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, 450, 547, 444, 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, @@ -7275,13 +7330,13 @@ var yyAct = [...]int{ 509, 548, 549, 550, 552, 415, 282, 456, 557, 0, 395, 606, 607, 335, 0, 0, 0, 0, 0, 0, 438, 0, 0, 0, 0, 0, 0, 0, 286, 0, - 0, 0, 0, 385, 283, 0, 0, 212, 530, 0, + 0, 0, 0, 385, 283, 0, 1977, 212, 530, 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, 450, 547, 444, 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, 435, 523, 302, 0, - 1949, 0, 0, 0, 536, 756, 0, 0, 0, 0, + 0, 0, 0, 0, 536, 756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, 0, 0, 0, @@ -7351,14 +7406,14 @@ var yyAct = [...]int{ 411, 421, 451, 457, 312, 287, 255, 483, 252, 509, 548, 549, 550, 552, 415, 282, 456, 557, 0, 395, 606, 607, 335, 0, 0, 0, 0, 0, 0, 438, - 0, 0, 0, 0, 0, 0, 1852, 286, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 286, 0, 0, 0, 0, 385, 283, 0, 0, 212, 530, 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, 450, 547, 444, 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 342, 262, 344, 210, 435, 523, 302, 0, 0, - 0, 0, 0, 536, 202, 0, 0, 0, 0, 0, + 0, 342, 262, 344, 210, 435, 523, 302, 0, 1952, + 0, 0, 0, 536, 756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, 0, 0, 0, 281, @@ -7428,14 +7483,14 @@ var yyAct = [...]int{ 421, 451, 457, 312, 287, 255, 483, 252, 509, 548, 549, 550, 552, 415, 282, 456, 557, 0, 395, 606, 607, 335, 0, 0, 0, 0, 0, 0, 438, 0, - 0, 0, 0, 0, 0, 0, 286, 0, 0, 0, + 0, 0, 0, 0, 0, 1855, 286, 0, 0, 0, 0, 385, 283, 0, 0, 212, 530, 0, 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, 289, 285, 264, 336, 405, 450, 547, 444, 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 342, 262, 344, 210, 435, 523, 302, 0, 101, 0, - 0, 0, 536, 991, 0, 0, 0, 0, 0, 0, + 342, 262, 344, 210, 435, 523, 302, 0, 0, 0, + 0, 0, 536, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, 0, 0, 0, 281, 340, @@ -7511,8 +7566,8 @@ var yyAct = [...]int{ 336, 405, 450, 547, 444, 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, - 262, 344, 210, 435, 523, 302, 0, 0, 0, 0, - 0, 536, 202, 0, 0, 0, 0, 0, 0, 0, + 262, 344, 210, 435, 523, 302, 0, 101, 0, 0, + 0, 536, 991, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, 0, 0, 0, 281, 340, 288, @@ -7526,7 +7581,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1506, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, 423, 273, 0, 477, 0, 319, 334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 661, 0, 0, 0, 0, 0, 0, 0, 384, 0, 349, @@ -7575,7 +7630,7 @@ var yyAct = [...]int{ 500, 501, 502, 505, 506, 513, 514, 515, 516, 517, 525, 526, 531, 532, 533, 534, 545, 618, 620, 637, 657, 664, 504, 404, 452, 476, 611, 0, 0, 317, - 318, 467, 468, 332, 333, 678, 679, 1505, 632, 665, + 318, 467, 468, 332, 333, 678, 679, 316, 632, 665, 629, 677, 659, 461, 397, 0, 0, 400, 297, 322, 339, 0, 649, 527, 236, 490, 306, 265, 0, 0, 219, 257, 239, 275, 290, 293, 343, 411, 421, 451, @@ -7603,7 +7658,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, + 0, 0, 0, 0, 0, 0, 0, 1507, 0, 313, 0, 423, 273, 0, 477, 0, 319, 334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 661, 0, 0, 0, 0, 0, 0, 0, 384, 0, 349, 205, @@ -7644,7 +7699,7 @@ var yyAct = [...]int{ 204, 229, 387, 0, 478, 304, 682, 650, 508, 645, 214, 231, 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1084, 0, 0, 0, 206, 208, 217, 230, 242, + 0, 0, 0, 0, 0, 206, 208, 217, 230, 242, 247, 254, 277, 292, 294, 301, 314, 327, 328, 337, 338, 341, 347, 399, 406, 407, 408, 409, 431, 432, 433, 436, 439, 440, 443, 445, 446, 449, 454, 458, @@ -7652,7 +7707,7 @@ var yyAct = [...]int{ 501, 502, 505, 506, 513, 514, 515, 516, 517, 525, 526, 531, 532, 533, 534, 545, 618, 620, 637, 657, 664, 504, 404, 452, 476, 611, 0, 0, 317, 318, - 467, 468, 332, 333, 678, 679, 316, 632, 665, 629, + 467, 468, 332, 333, 678, 679, 1506, 632, 665, 629, 677, 659, 461, 397, 0, 0, 400, 297, 322, 339, 0, 649, 527, 236, 490, 306, 265, 0, 0, 219, 257, 239, 275, 290, 293, 343, 411, 421, 451, 457, @@ -7682,7 +7737,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, 423, 273, 0, 477, 0, 319, 334, 0, 0, 0, - 0, 0, 0, 0, 0, 707, 0, 661, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 661, 0, 0, 0, 0, 0, 0, 0, 384, 0, 349, 205, 233, 0, 0, 434, 485, 497, 0, 0, 0, 0, 269, 0, 495, 448, 636, 243, 300, 482, 455, 493, 463, @@ -7721,7 +7776,7 @@ var yyAct = [...]int{ 229, 387, 0, 478, 304, 682, 650, 508, 645, 214, 231, 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 206, 208, 217, 230, 242, 247, + 1084, 0, 0, 0, 206, 208, 217, 230, 242, 247, 254, 277, 292, 294, 301, 314, 327, 328, 337, 338, 341, 347, 399, 406, 407, 408, 409, 431, 432, 433, 436, 439, 440, 443, 445, 446, 449, 454, 458, 459, @@ -7742,7 +7797,7 @@ var yyAct = [...]int{ 547, 444, 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, - 435, 523, 302, 0, 0, 0, 0, 0, 536, 756, + 435, 523, 302, 0, 0, 0, 0, 0, 536, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, @@ -7759,7 +7814,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, 423, 273, 0, 477, 0, 319, 334, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 661, 0, 0, 0, + 0, 0, 0, 0, 707, 0, 661, 0, 0, 0, 0, 0, 0, 0, 384, 0, 349, 205, 233, 0, 0, 434, 485, 497, 0, 0, 0, 0, 269, 0, 495, 448, 636, 243, 300, 482, 455, 493, 463, 303, @@ -7800,7 +7855,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 208, 217, 230, 242, 247, 254, 277, 292, 294, 301, 314, 327, 328, 337, 338, 341, - 347, 399, 406, 407, 408, 409, 4264, 432, 433, 436, + 347, 399, 406, 407, 408, 409, 431, 432, 433, 436, 439, 440, 443, 445, 446, 449, 454, 458, 459, 460, 462, 464, 466, 479, 484, 498, 499, 500, 501, 502, 505, 506, 513, 514, 515, 516, 517, 525, 526, 531, @@ -7877,7 +7932,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 208, 217, 230, 242, 247, 254, 277, 292, 294, 301, 314, 327, 328, 337, 338, 341, 347, - 399, 406, 407, 408, 409, 431, 432, 433, 436, 439, + 399, 406, 407, 408, 409, 4272, 432, 433, 436, 439, 440, 443, 445, 446, 449, 454, 458, 459, 460, 462, 464, 466, 479, 484, 498, 499, 500, 501, 502, 505, 506, 513, 514, 515, 516, 517, 525, 526, 531, 532, @@ -7896,7 +7951,7 @@ var yyAct = [...]int{ 0, 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, 435, 523, - 302, 0, 0, 0, 0, 0, 536, 991, 0, 0, + 302, 0, 0, 0, 0, 0, 536, 756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, 0, @@ -7973,7 +8028,7 @@ var yyAct = [...]int{ 389, 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 342, 262, 344, 210, 435, 523, 302, - 0, 0, 0, 0, 0, 536, 202, 0, 0, 0, + 0, 0, 0, 0, 0, 536, 991, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, 376, 382, 355, 364, 0, 0, 641, 0, 0, @@ -8041,33 +8096,109 @@ var yyAct = [...]int{ 0, 400, 297, 322, 339, 0, 649, 527, 236, 490, 306, 265, 0, 0, 219, 257, 239, 275, 290, 293, 343, 411, 421, 451, 457, 312, 287, 255, 483, 252, - 509, 548, 549, 550, 552, 415, 282, 456, 0, 0, - 395, 606, 607, 335, + 509, 548, 549, 550, 552, 415, 282, 456, 557, 0, + 395, 606, 607, 335, 0, 0, 0, 0, 0, 0, + 438, 0, 0, 0, 0, 0, 0, 0, 286, 0, + 0, 0, 0, 385, 283, 0, 0, 212, 530, 0, + 453, 0, 211, 0, 511, 268, 396, 393, 615, 298, + 289, 285, 264, 336, 405, 450, 547, 444, 0, 389, + 0, 0, 522, 422, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 342, 262, 344, 210, 435, 523, 302, 0, + 0, 0, 0, 0, 536, 202, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 249, 0, 0, 256, 0, + 0, 0, 370, 379, 378, 358, 359, 361, 363, 369, + 376, 382, 355, 364, 0, 0, 641, 0, 0, 0, + 281, 340, 288, 280, 612, 0, 0, 0, 0, 0, + 0, 628, 0, 0, 238, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 416, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 313, 0, 423, 273, 0, 477, 0, + 319, 334, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 661, 0, 0, 0, 0, 0, 0, 0, + 384, 0, 349, 205, 233, 0, 0, 434, 485, 497, + 0, 0, 0, 0, 269, 0, 495, 448, 636, 243, + 300, 482, 455, 493, 463, 303, 0, 0, 494, 391, + 617, 473, 633, 662, 663, 279, 428, 647, 551, 655, + 680, 234, 276, 442, 535, 639, 519, 417, 613, 614, + 348, 518, 311, 209, 388, 668, 232, 503, 390, 253, + 241, 619, 644, 315, 267, 305, 480, 675, 221, 546, + 630, 250, 507, 0, 0, 683, 258, 529, 642, 631, + 223, 626, 528, 413, 345, 346, 222, 0, 481, 284, + 309, 0, 0, 274, 437, 621, 622, 272, 684, 237, + 654, 228, 0, 653, 430, 616, 627, 414, 402, 227, + 625, 412, 401, 353, 374, 375, 296, 324, 470, 394, + 471, 323, 325, 425, 424, 426, 215, 640, 658, 0, + 216, 0, 524, 643, 685, 475, 220, 244, 245, 248, + 0, 295, 299, 307, 310, 320, 321, 331, 386, 441, + 469, 465, 474, 0, 610, 634, 648, 660, 666, 667, + 669, 670, 671, 672, 673, 676, 674, 429, 329, 520, + 352, 392, 0, 0, 447, 496, 251, 638, 521, 240, + 604, 418, 427, 259, 261, 260, 235, 512, 609, 246, + 266, 207, 0, 0, 0, 0, 270, 271, 0, 605, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 686, + 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, + 697, 698, 699, 700, 701, 702, 703, 681, 537, 543, + 538, 539, 540, 541, 542, 0, 544, 0, 0, 0, + 0, 0, 419, 0, 623, 624, 704, 403, 510, 635, + 354, 368, 371, 360, 380, 0, 381, 356, 357, 362, + 365, 366, 367, 372, 373, 377, 383, 263, 218, 410, + 420, 608, 330, 224, 225, 226, 553, 554, 555, 556, + 651, 652, 656, 213, 486, 487, 488, 489, 308, 646, + 326, 492, 491, 350, 351, 398, 472, 569, 571, 582, + 586, 588, 590, 596, 599, 570, 572, 583, 587, 589, + 591, 597, 600, 559, 561, 563, 565, 578, 577, 574, + 602, 603, 580, 585, 564, 576, 581, 594, 601, 598, + 558, 562, 566, 575, 593, 592, 573, 584, 595, 579, + 567, 560, 568, 0, 204, 229, 387, 0, 478, 304, + 682, 650, 508, 645, 214, 231, 0, 278, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, + 208, 217, 230, 242, 247, 254, 277, 292, 294, 301, + 314, 327, 328, 337, 338, 341, 347, 399, 406, 407, + 408, 409, 431, 432, 433, 436, 439, 440, 443, 445, + 446, 449, 454, 458, 459, 460, 462, 464, 466, 479, + 484, 498, 499, 500, 501, 502, 505, 506, 513, 514, + 515, 516, 517, 525, 526, 531, 532, 533, 534, 545, + 618, 620, 637, 657, 664, 504, 404, 452, 476, 611, + 0, 0, 317, 318, 467, 468, 332, 333, 678, 679, + 316, 632, 665, 629, 677, 659, 461, 397, 0, 0, + 400, 297, 322, 339, 0, 649, 527, 236, 490, 306, + 265, 0, 0, 219, 257, 239, 275, 290, 293, 343, + 411, 421, 451, 457, 312, 287, 255, 483, 252, 509, + 548, 549, 550, 552, 415, 282, 456, 0, 0, 395, + 606, 607, 335, } var yyPact = [...]int{ - -1000, -1000, -559, -1000, 8464, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -559, -1000, 6289, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 2611, 2694, -1000, -1000, -1000, - -1000, 2795, -1000, 1092, -1000, 2290, 2216, 2587, 4447, -1000, - 61657, 530, -1000, 58581, -423, 924, 296, 40893, -1000, 262, - -1000, 253, 60119, 258, -1000, -1000, -1000, -1000, -423, 24712, - 2496, 55, 49, 61657, -1000, -1000, -1000, -1000, -346, 2761, - 2214, -1000, 474, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 57812, -1000, -1000, -1000, 1246, -1000, 2595, 2596, 2464, 980, - 1855, -1000, 2627, 2214, -1000, 24712, 2728, 2552, 23937, 23937, - 475, -1000, -1000, 333, -1000, -1000, 35510, 61657, 44738, 2636, - 60119, -1000, 2587, -1000, -1000, -1000, 187, -1000, 367, 2182, - -1000, 2172, -1000, 856, 1147, 398, 870, 865, 397, 396, - 395, 379, 377, 374, 373, 372, 406, -1000, 1008, 1008, - -233, -244, 1497, 479, 455, 455, 1114, 506, 2557, 2532, - -1000, -1000, 1008, 1008, 1008, 405, 1008, 1008, 1008, 1008, - 346, 342, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, - 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 986, - 2587, 330, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 2631, 2719, -1000, -1000, -1000, + -1000, 2855, -1000, 1167, -1000, 2301, 2219, 2663, 4499, -1000, + 62976, 798, -1000, 59900, -411, 944, 250, 42212, -1000, 255, + -1000, 234, 61438, 245, -1000, -1000, -1000, -1000, -411, 26031, + 2549, 97, 96, 62976, -1000, -1000, -1000, -1000, -345, 2821, + 2144, -1000, 488, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 59131, -1000, -1000, -1000, 1306, -1000, 2672, 2636, 2524, 1019, + 1549, -1000, 2745, 2144, -1000, 26031, 2785, 2617, 25256, 24481, + 487, -1000, -1000, 269, -1000, -1000, 36829, 62976, 46057, 2732, + 61438, -1000, 2663, -1000, -1000, -1000, 214, -1000, 420, 2185, + -1000, 2184, -1000, 1172, 1258, 437, 871, 868, 435, 434, + 433, 428, 427, 425, 424, 423, 444, -1000, 1055, 1055, + -201, -203, 2192, 485, 483, 483, 1007, 514, 2612, 2573, + -1000, -1000, 1055, 1055, 1055, 392, 1055, 1055, 1055, 1055, + 404, 400, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, + 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 910, + 2663, 336, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, @@ -8116,69 +8247,69 @@ var yyPact = [...]int{ -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 61657, 289, 61657, -1000, 872, - 529, -1000, -1000, -437, 1157, 1157, 62, 1157, 1157, 1157, - 1157, 234, 1046, 48, -1000, 227, 318, 228, 324, 1126, - 795, -1000, -1000, 319, 1126, 2001, -1000, 991, 323, 171, - -1000, 1157, 1157, -1000, 16955, 224, 16955, 16955, 321, 233, - -1000, 2571, -1000, -1000, -1000, -1000, -1000, 1460, -1000, -1000, - -1000, -1000, -31, 505, -1000, -1000, -1000, -1000, 60119, 57043, - 312, -1000, -1000, 276, 2014, 1210, 24712, 2506, 968, -1000, - -1000, 1457, 934, -1000, -1000, -1000, -1000, -1000, 871, -1000, - 27037, 27037, 27037, 27037, -1000, -1000, 2184, 56274, 2184, 2184, - 27037, 2184, 27037, 2184, 2184, 2184, 2184, 24712, 2184, 2184, - 2184, 2184, -1000, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, -1000, -1000, -1000, -1000, 2184, 869, 2184, 2184, - 2184, 2184, 2184, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 2184, 2184, 2184, 2184, 2184, 2184, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, -1000, - -1000, -1000, 1792, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 1510, 1723, 1713, 1703, -1000, 21612, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 62976, 808, 62976, -1000, 896, + 795, -1000, -1000, -416, 1181, 1181, 109, 1181, 1181, 1181, + 1181, 233, 1065, 95, -1000, 232, 308, 218, 329, 1134, + 932, -1000, -1000, 304, 1134, 1937, -1000, 1027, 313, 220, + -1000, 1181, 1181, -1000, 16724, 204, 16724, 16724, 310, 210, + -1000, 2655, -1000, -1000, -1000, -1000, -1000, 1477, -1000, -1000, + -1000, -1000, -14, 510, -1000, -1000, -1000, -1000, 61438, 58362, + 359, -1000, -1000, 339, 1953, 1571, 26031, 3651, 987, -1000, + -1000, 1455, 948, -1000, -1000, -1000, -1000, -1000, 864, -1000, + 28356, 28356, 28356, 28356, -1000, -1000, 2193, 57593, 2193, 2193, + 28356, 2193, 28356, 2193, 2193, 2193, 2193, 26031, 2193, 2193, + 2193, 2193, -1000, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, -1000, -1000, -1000, -1000, 2193, 892, 2193, 2193, + 2193, 2193, 2193, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 2193, 2193, 2193, 2193, 2193, 2193, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, -1000, + -1000, -1000, 1796, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 2817, 1666, 1653, 1640, -1000, 21381, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 2184, -1000, -1000, -1000, - 61657, -1000, 2184, 280, 60119, 60119, 383, 1447, -1000, -1000, - 2627, 2214, -1000, 2761, 2736, 474, -1000, 3749, 1842, 1857, - 1484, 2214, 1194, 2110, 61657, -1000, 2216, 201, -1000, -1000, - -1000, -341, -352, 2411, 1529, 1993, 2152, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 1414, 24712, -1000, -1000, 2782, - -1000, 32434, 861, 2781, 55505, -1000, 475, 475, 2151, 656, - 10, -1000, -1000, -1000, -1000, 1044, 40124, -1000, -1000, -1000, - -1000, -1000, 2045, 61657, -1000, -1000, 5383, 60119, -1000, 2288, - -1000, 2039, -1000, 2229, 24712, 474, 2030, -1000, -1000, -1000, - -1000, 1008, 1008, 1008, -1000, 404, 2727, 4447, 5249, -1000, - -1000, -1000, 54736, 2287, 60119, -1000, 2283, -1000, 1120, 900, - 897, 897, 60119, -1000, -1000, 60888, 60119, 1119, 1117, 60119, - 60119, 60119, 60119, -1000, 53967, -1000, 53198, 52429, 1445, 60119, - 51660, 50891, 50122, 49353, 48584, -1000, 2431, -1000, 2261, -1000, - -1000, -1000, 60888, 60119, 60119, 60888, 60119, 60888, 61657, 60119, - -1000, -1000, 414, -1000, -1000, 1437, 1433, 1429, 1008, 1008, - 1428, 1991, 1988, 1964, 1008, 1008, 1425, 1950, 43200, 1948, - 326, 1408, 1399, 1380, 1443, 1941, 246, 1926, 1407, 1356, - 1378, 60119, 2282, 61657, -1000, 313, 1088, 1005, -1000, -1000, - -1000, 1031, 2587, 2490, 2148, 504, 528, 60119, 483, 483, - 483, 60119, -1000, -1000, 17732, 61657, 284, -1000, 1900, 24712, - -1000, 1143, 1126, 1126, -1000, -1000, -1000, -1000, -1000, -1000, - 1157, 61657, 1143, -1000, -1000, -1000, 1126, 1157, 61657, 1157, - 1157, 1157, 1157, 1126, 1126, 1126, 1157, 61657, 61657, 61657, - 61657, 61657, 61657, 61657, 61657, 61657, 16955, 991, 1157, -438, - -1000, 1897, -1000, -1000, -1000, 2389, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 2193, -1000, -1000, -1000, + 62976, -1000, 2193, 272, 61438, 61438, 370, 1461, -1000, -1000, + 2745, 2144, -1000, 2821, 2862, 488, -1000, 3990, 2105, 1831, + 1504, 2144, 1073, 2140, 62976, -1000, 2219, 191, -1000, -1000, + -1000, -300, -324, 2416, 1703, 1935, 2169, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 2190, 26031, -1000, -1000, 2847, + 2844, 33753, 891, 2839, 2835, 56824, -1000, 487, 487, 2166, + 652, 75, -1000, -1000, -1000, -1000, 1111, 41443, -1000, -1000, + -1000, -1000, -1000, 2023, 62976, -1000, -1000, 7049, 61438, -1000, + 2296, -1000, 2021, -1000, 2238, 26031, 488, 1989, -1000, -1000, + -1000, -1000, 1055, 1055, 1055, -1000, 443, 2784, 4499, 5943, + -1000, -1000, -1000, 56055, 2292, 61438, -1000, 2282, -1000, 1213, + 900, 918, 918, 61438, -1000, -1000, 62207, 61438, 1211, 1210, + 61438, 61438, 61438, 61438, -1000, 55286, -1000, 54517, 53748, 1460, + 61438, 52979, 52210, 51441, 50672, 49903, -1000, 2413, -1000, 2167, + -1000, -1000, -1000, 62207, 61438, 61438, 62207, 61438, 62207, 62976, + 61438, -1000, -1000, 628, -1000, -1000, 1457, 1456, 1441, 1055, + 1055, 1440, 1934, 1933, 1932, 1055, 1055, 1435, 1931, 44519, + 1928, 324, 1430, 1426, 1418, 1480, 1917, 251, 1916, 1421, + 1374, 1413, 61438, 2281, 62976, -1000, 298, 1024, 1068, -1000, + -1000, -1000, 1106, 2663, 2546, 2156, 505, 792, 61438, 497, + 497, 497, 61438, -1000, -1000, 17501, 62976, 266, -1000, 1906, + 26031, -1000, 1150, 1134, 1134, -1000, -1000, -1000, -1000, -1000, + -1000, 1181, 62976, 1150, -1000, -1000, -1000, 1134, 1181, 62976, + 1181, 1181, 1181, 1181, 1134, 1134, 1134, 1181, 62976, 62976, + 62976, 62976, 62976, 62976, 62976, 62976, 62976, 16724, 1027, 1181, + -418, -1000, 1903, -1000, -1000, -1000, 2422, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, @@ -8194,355 +8325,356 @@ var yyPact = [...]int{ -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 16955, 16955, - -1000, -1000, 2662, 2660, -1000, -1000, -1000, 2145, -1000, 245, - 5, 256, -1000, 47815, 534, 1030, -1000, 534, -1000, -1000, - -1000, -1000, -1000, 2143, 47046, -1000, -439, -443, -449, -451, - -1000, -1000, -1000, -452, -455, -1000, -1000, -1000, 24712, 24712, - 24712, 24712, -271, 962, 1635, 27037, 2548, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 24712, 1254, 1276, 27037, 27037, 27037, - 27037, 27037, 27037, 27037, 28587, 27812, 27037, 27037, 27037, 27037, - 27037, 27037, -1000, -1000, 37817, 6546, 6546, 934, 934, 934, - 934, -1000, -188, 2138, 60888, -1000, -1000, -1000, 859, 24712, - 24712, 934, -1000, 1464, 2661, 21612, 24712, 24712, 24712, 24712, - 1067, 1210, 60888, 24712, -1000, 1484, -1000, -1000, -1000, -1000, - 1265, -1000, -1000, 1133, 2533, 2533, 2533, 2533, 24712, 24712, - 24712, 24712, 24712, 24712, 24712, 24712, 24712, 24712, 2533, 24712, - 750, 750, 910, 24712, 24712, 24712, 24712, 24712, 24712, 24712, - 24712, 20061, 24712, 24712, 27037, 24712, 24712, 24712, 1484, 24712, - 24712, 24712, 24712, 24712, 24712, 24712, 24712, 24712, 24712, 24712, - 24712, 24712, 24712, 24712, 24712, 24712, 24712, 24712, 24712, 24712, - 24712, 24712, 24712, 24712, 24712, 24712, 24712, 24712, 24712, 24712, - 24712, 24712, 24712, 24712, 24712, 24712, 24712, 24712, 24712, 24712, - 24712, 24712, 24712, 24712, 24712, 24712, 24712, 24712, 24712, 24712, - 24712, 24712, 24712, 24712, 24712, 24712, 24712, 24712, 24712, 24712, - 24712, 24712, 24712, 24712, 24712, 24712, 24712, 24712, 24712, 24712, - 24712, 24712, 24712, 24712, 24712, 24712, 24712, 24712, 1484, 24712, - 1489, 24712, 24712, 24712, 24712, 24712, 24712, 24712, 19286, 24712, - 24712, 24712, 24712, 24712, -1000, -1000, -1000, -1000, -1000, -1000, - 24712, 24712, 24712, 24712, 24712, 24712, 24712, 24712, 1484, 24712, - 24712, 24712, 24712, 24712, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 1715, 1735, 1718, 2184, 24712, -1000, - 2129, -1000, -159, 34741, 24712, 1882, 2779, 2313, 60119, -1000, - -1000, -1000, -1000, 2627, -1000, 2627, 1715, 3650, 2421, 23937, - -1000, -1000, 3650, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 1978, -1000, 316, 527, - 2258, 313, 60119, 523, 522, 520, 468, -1000, -68, 1029, - 61657, 2110, 2633, -1000, 2101, -1000, -1000, 2184, -1000, -312, - -1000, -317, 2409, 1853, 912, -1000, 1458, 24712, 24712, 2098, - -1000, 1205, 61657, -1000, -271, -1000, 46277, -1000, -1000, 16178, - 61657, 369, 61657, -1000, 33972, 45508, 336, -1000, 10, 2083, - -1000, 23, 0, 20836, 933, -1000, -1000, -1000, 1497, 29356, - 2011, 933, 150, -1000, -1000, -1000, 2229, -1000, 2229, 2229, - 2229, 2229, 2229, 912, 912, 912, 2229, -1000, -1000, -1000, - -1000, 2281, 2229, 2276, -1000, 2229, 2229, 2229, 2229, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 2270, 2270, 2270, 2268, - 2268, 2231, 2231, 439, -1000, 24712, 450, 44738, 2614, 1376, - 1290, -200, -1000, 60119, 1629, 1588, 1517, -1000, -551, 2095, - -1000, -1000, 2723, -1000, -1000, 1263, 1158, 1148, 1208, 60119, - 291, 364, -1000, 442, -1000, 44738, 60119, 1095, 897, 60119, - -1000, 60119, -1000, -1000, -1000, -1000, -1000, 60119, -1000, -1000, - 2094, -1000, 2105, 1249, 1139, 1214, 1136, 2094, -1000, -1000, - -199, 2094, -1000, 2094, -1000, 2094, -1000, 2094, -1000, 2094, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1065, - 283, -349, 60119, 291, 502, -1000, 501, 37817, -1000, -1000, - -1000, 37817, 37817, -1000, -1000, -1000, -1000, 1829, 1825, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 16724, + 16724, -1000, -1000, 2755, 2747, -1000, -1000, -1000, 2154, -1000, + 231, 70, 239, -1000, 49134, 484, 1097, -1000, 484, -1000, + -1000, -1000, -1000, -1000, 2152, 48365, -1000, -420, -421, -429, + -435, -1000, -1000, -1000, -440, -442, -1000, -1000, -1000, 26031, + 26031, 26031, 26031, -230, 970, 1417, 28356, 2639, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 26031, 1299, 1069, 28356, 28356, + 28356, 28356, 28356, 28356, 28356, 29906, 29131, 28356, 28356, 28356, + 28356, 28356, 28356, -1000, -1000, 39136, 8698, 8698, 948, 948, + 948, 948, -1000, -178, 2145, 62207, -1000, -1000, -1000, 890, + 26031, 26031, 948, -1000, 1483, 1924, 21381, 26031, 26031, 26031, + 26031, 1136, 1571, 62207, 26031, -1000, 1504, -1000, -1000, -1000, + -1000, 1334, -1000, -1000, 1117, 2586, 2586, 2586, 2586, 26031, + 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, 2586, + 26031, 282, 282, 1179, 26031, 26031, 26031, 26031, 26031, 26031, + 26031, 26031, 19830, 26031, 26031, 28356, 26031, 26031, 26031, 1504, + 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, + 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, + 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, + 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, + 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, + 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, + 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, + 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, 1504, + 26031, 1481, 26031, 26031, 26031, 26031, 26031, 26031, 26031, 19055, + 26031, 26031, 26031, 26031, 26031, -1000, -1000, -1000, -1000, -1000, + -1000, 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, 1504, + 26031, 26031, 26031, 26031, 26031, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 1890, 1874, 1622, 2193, 26031, + -1000, 2141, -1000, -139, 36060, 26031, 1882, 2829, 2315, 61438, + -1000, -1000, -1000, -1000, 2745, -1000, 2745, 1890, 3765, 2449, + 23706, -1000, -1000, 3765, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1724, -1000, 390, + 790, 2220, 298, 61438, 779, 548, 536, 494, -1000, -66, + 1093, 62976, 2140, 2731, -1000, 2137, -1000, -1000, 2193, -1000, + -277, -1000, -279, 2445, 1880, 853, -1000, 1506, 26031, 26031, + 2131, -1000, 1921, 62976, 62976, -1000, -230, -1000, 47596, -1000, + -1000, 15947, 62976, 62976, 421, 62976, -1000, 35291, 46827, 290, + -1000, 75, 2097, -1000, 51, 65, 20605, 947, -1000, -1000, + -1000, 2192, 30675, 1948, 947, 145, -1000, -1000, -1000, 2238, + -1000, 2238, 2238, 2238, 2238, 2238, 853, 853, 853, 2238, + -1000, -1000, -1000, -1000, 2277, 2238, 2270, -1000, 2238, 2238, + 2238, 2238, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 2268, + 2268, 2268, 2267, 2267, 2239, 2239, 478, -1000, 26031, 407, + 46057, 2686, 1408, 1669, -185, -1000, 61438, 1634, 1591, 1585, + -1000, -502, 2129, -1000, -1000, 2783, -1000, -1000, 984, 1229, + 1228, 1256, 61438, 283, 414, -1000, 469, -1000, 46057, 61438, + 1208, 918, 61438, -1000, 61438, -1000, -1000, -1000, -1000, -1000, + 61438, -1000, -1000, 2122, -1000, 2096, 1286, 1227, 1234, 1209, + 2122, -1000, -1000, -184, 2122, -1000, 2122, -1000, 2122, -1000, + 2122, -1000, 2122, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 1081, 337, -325, 61438, 283, 504, -1000, 502, + 39136, -1000, -1000, -1000, 39136, 39136, -1000, -1000, -1000, -1000, + 1877, 1852, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -508, 61657, - -1000, 305, 350, 386, 375, 61657, 427, 2541, 2523, 2522, - 2520, 2518, 2516, 2515, 301, 337, 61657, 61657, 483, 2348, - 61657, 2620, 61657, 61657, -1000, -1000, -1000, -1000, -1000, 1819, - 1817, -1000, 1210, 61657, -1000, -1000, 1157, 1157, -1000, -1000, - 61657, 1157, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 1157, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 61657, -1000, -1000, -1000, - -1000, 1806, -1000, 61657, -31, 238, -1000, -1000, 60119, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -74, -1000, - 341, 21, 448, -1000, -1000, -1000, -1000, -1000, 2657, -1000, - 1210, 1051, 1014, 962, 2184, -1000, -1000, 1340, -1000, -1000, - -1000, -1000, -1000, 2184, 2184, 2184, -1000, -1000, -1000, -1000, - -1000, 1254, 27037, 27037, 27037, 1760, 858, 1338, 1483, 1471, - 1312, 1312, 964, 27037, 964, 27037, 941, 941, 941, 941, - 941, -1000, -1000, -1000, -1000, -1000, -1000, 1792, -1000, 1790, - -1000, 2184, 60888, 2023, 19286, 1602, 2025, 1484, 957, -1000, + -1000, -508, 62976, -1000, 297, 409, 399, 394, 62976, 367, + 2593, 2592, 2583, 2580, 2571, 2567, 2564, 334, 398, 62976, + 62976, 497, 2387, 62976, 2691, 62976, 62976, -1000, -1000, -1000, + -1000, -1000, 1836, 1833, -1000, 1571, 62976, -1000, -1000, 1181, + 1181, -1000, -1000, 62976, 1181, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 1181, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 62976, + -1000, -1000, -1000, -1000, 1804, -1000, 62976, -14, 225, -1000, + -1000, 61438, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -41, -1000, 348, 64, 408, -1000, -1000, -1000, -1000, + -1000, 2739, -1000, 1571, 1035, 1033, 970, 2193, -1000, -1000, + 1244, -1000, -1000, -1000, -1000, -1000, 2193, 2193, 2193, -1000, + -1000, -1000, -1000, -1000, 1299, 28356, 28356, 28356, 1755, 860, + 1961, 1996, 1870, 1283, 1283, 1232, 28356, 1232, 28356, 952, + 952, 952, 952, 952, -1000, -1000, -1000, -1000, -1000, -1000, + 1796, -1000, 1787, -1000, 2193, 62207, 1901, 19055, 1751, 1800, + 1504, 981, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 3618, - 1484, 2014, 1484, 1594, 3608, 1064, -1000, 24712, 1484, 3591, - -1000, -1000, 1484, 1484, 24712, -1000, -1000, 24712, 24712, 24712, - 24712, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, - 1290, 24712, 1290, 2092, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 3597, 1504, 1953, 1504, 1503, 3581, 1197, -1000, + 26031, 1504, 3576, -1000, -1000, 1504, 1504, 26031, -1000, -1000, + 26031, 26031, 26031, 26031, 1669, 1669, 1669, 1669, 1669, 1669, + 1669, 1669, 1669, 1669, 26031, 1669, 2118, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 2090, 2777, 1598, 1290, 1290, 1290, 1290, 3577, - 1290, 1290, 24712, 1667, -1000, -1000, -1000, 1758, 3572, 1653, - 3511, 1290, 1290, -1000, 1290, 3507, 3503, 1484, 2851, 2784, - 1290, 1290, 1290, 1290, 1290, 2778, 2774, 1290, 1290, 2767, - 1290, 3490, 1290, 2763, 2742, 2738, 2713, 2677, 2652, 2648, - 2635, 2623, 2606, 2574, 2559, 2545, 2538, 2534, 2529, 2513, - 2441, 1290, 1290, 1290, 3486, 1290, 3478, 1290, 3470, 1290, - 1290, 3453, 2432, 2420, 1484, 2086, -1000, 3449, 1290, 3440, - 3434, 3422, 2413, 3415, 3388, 3384, 1290, 1290, 1290, 2392, - 3379, 3373, 3369, 3354, 3348, 3341, 3326, 3321, 3299, 1290, - 1718, 1718, 1718, 1718, 1718, 3293, -278, 1290, 1484, -1000, - -1000, -1000, -1000, 3287, 2388, 3260, 3255, 3199, 3113, 1484, - 2184, 857, -1000, -1000, 1718, 1484, 1484, 1718, 1718, 3108, - 3100, 3092, 3088, 3036, 3027, 1290, 1290, -1000, 1290, 3019, - 3011, 2379, 2342, 1484, -1000, 1718, 61657, -1000, -432, -1000, - 11, 1025, 2184, -1000, 43200, 1484, -1000, 5250, -1000, 1456, - -1000, -1000, -1000, -1000, -1000, 39355, 1864, -1000, -1000, -1000, - 468, 518, 293, 468, 313, 305, 2306, 60119, 60119, 60119, - 61657, 1072, -1000, 517, -1000, 2184, -475, 23162, -1000, -1000, - -1000, 912, 129, 38586, 923, 923, 165, -1000, 1210, 1210, - 24712, -1000, -1000, -1000, -1000, -1000, -1000, 855, 2748, 380, - 2184, -1000, 2093, 3291, -1000, -1000, -1000, 2631, 30126, -1000, - -1000, 2184, 2184, 61657, 2066, 2061, -1000, 847, -1000, 1465, - 2083, 10, 14, -1000, -1000, -1000, -1000, 1210, -1000, 1498, - 370, 1453, -1000, 467, -1000, -1000, -1000, -1000, 2504, 141, - -1000, -1000, -1000, 593, 912, -1000, -1000, 912, -1000, -1000, - -1000, -1000, 1781, -1000, 1781, -1000, -1000, -1000, -1000, -1000, - 1373, -1000, -1000, -1000, -1000, 1361, -1000, -1000, 1360, -1000, - -1000, 2021, 2320, 450, -1000, -1000, 1008, 1771, -1000, -1000, - 2510, 1008, 1008, 60119, -1000, -1000, 2006, 2614, -1000, -1, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -544, 169, 388, - -1000, -1000, -1000, 4665, 60119, 2009, -1000, 281, -1000, 1922, - -1000, 60119, -1000, 2005, 2267, 60119, 60119, -1000, -1000, -1000, - 60119, 2184, -1000, -1000, -1000, -1000, 519, 2585, 328, -1000, - -1000, -299, -1000, -1000, 291, 281, 60888, 60119, 933, -1000, - -1000, -1000, -1000, -1000, -504, 1974, 516, 61657, 61657, 61657, - 61657, 61657, 61657, 819, -1000, -1000, 34, -1000, -1000, 259, - -1000, -1000, 1765, -1000, -1000, -1000, -1000, 259, -1000, -1000, - -1000, -1000, -1000, 332, 500, -1000, 61657, 61657, 1009, -1000, - -1000, -1000, -1000, -1000, -1000, 1126, -1000, -1000, 1126, -1000, + -1000, -1000, -1000, -1000, -1000, 2104, 2828, 1257, 1669, 1669, + 1669, 1669, 3572, 1669, 1669, 26031, 2523, -1000, -1000, -1000, + 1661, 3559, 1657, 3547, 1669, 1669, -1000, 1669, 3532, 3520, + 1504, 3034, 2827, 1669, 1669, 1669, 1669, 1669, 2792, 2782, + 1669, 1669, 2743, 1669, 3510, 1669, 2708, 2703, 2696, 2675, + 2658, 2630, 2622, 2611, 2597, 2578, 2559, 2550, 2543, 2531, + 2513, 2498, 2482, 2470, 1669, 1669, 1669, 3495, 1669, 3483, + 1669, 3462, 1669, 1669, 3455, 2419, 2408, 1504, 2101, -1000, + 3442, 1669, 3434, 3421, 3414, 2381, 3404, 3394, 3387, 1669, + 1669, 1669, 2377, 3365, 3360, 3356, 3349, 3329, 3318, 3310, + 3302, 3298, 1669, 1622, 1622, 1622, 1622, 1622, 3291, -237, + 1669, 1504, -1000, -1000, -1000, -1000, 3271, 2373, 3252, 3236, + 3198, 3194, 1504, 2193, 887, -1000, -1000, 1622, 1504, 1504, + 1622, 1622, 3112, 3103, 3095, 3090, 3075, 3070, 1669, 1669, + -1000, 1669, 3063, 3054, 2368, 2364, 1504, -1000, 1622, 62976, + -1000, -407, -1000, -1, 983, 2193, -1000, 44519, 1504, -1000, + 7258, -1000, 1419, -1000, -1000, -1000, -1000, -1000, 40674, 2070, + -1000, -1000, -1000, -1000, 494, 530, 287, 494, 298, 297, + 2309, 61438, 61438, 61438, 62976, 1177, -1000, 496, -1000, 2193, + -465, 22931, -1000, -1000, -1000, 853, 116, 39905, 943, 943, + 160, -1000, 1571, 1571, 26031, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 886, 2810, 2810, 486, 2193, -1000, 2120, 3750, + -1000, -1000, -1000, 2730, 31445, -1000, -1000, 2193, 2193, 62976, + 1998, 1985, -1000, 885, -1000, 1488, 2097, 75, 59, -1000, + -1000, -1000, -1000, 1571, -1000, 1519, 422, 1508, -1000, 467, + -1000, -1000, -1000, -1000, 2555, 128, -1000, -1000, -1000, 361, + 853, -1000, -1000, 853, -1000, -1000, -1000, -1000, 1773, -1000, + 1773, -1000, -1000, -1000, -1000, -1000, 1404, -1000, -1000, -1000, + -1000, 1401, -1000, -1000, 1399, -1000, -1000, 2875, 2362, 407, + -1000, -1000, 1055, 1770, -1000, -1000, 2557, 1055, 1055, 61438, + -1000, -1000, 1946, 2686, -1000, 18, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -536, 170, 584, -1000, -1000, -1000, 4728, + 61438, 1897, -1000, 262, -1000, 1902, -1000, 61438, -1000, 1889, + 2265, 61438, 61438, -1000, -1000, -1000, 61438, 2193, -1000, -1000, + -1000, -1000, 789, 2661, 330, -1000, -1000, -266, -1000, -1000, + 283, 262, 62207, 61438, 947, -1000, -1000, -1000, -1000, -1000, + -496, 1887, 528, 62976, 62976, 62976, 62976, 62976, 62976, 873, + -1000, -1000, 79, -1000, -1000, 257, -1000, -1000, 1764, -1000, + -1000, -1000, -1000, 257, -1000, -1000, -1000, -1000, -1000, 349, + 490, -1000, 62976, 62976, 963, -1000, -1000, -1000, -1000, -1000, + -1000, 1134, -1000, -1000, 1134, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 2652, 62976, 61, + -462, -1000, -459, 26031, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 1605, 855, 1961, 28356, 28356, 1924, 1924, 28356, -1000, + -1000, -1000, 1365, 1365, 39136, -1000, 28356, 26031, -1000, -1000, + 26031, 26031, 26031, 1122, -1000, 26031, 2068, -1000, 26031, -1000, + -237, 1622, 1669, 1669, 1669, 1669, -237, -237, -237, -237, + -237, -237, -237, -237, -237, -237, 2132, -1000, 26031, 26031, + 26031, 1504, 354, -1000, -1000, -1000, -237, 26031, -1000, -1000, + 2824, -1000, 26031, -1000, 39136, 26031, 26031, 26031, -1000, -1000, + -1000, 26031, 26031, -1000, -1000, 26031, -1000, 26031, -1000, -1000, + -1000, -1000, -1000, -1000, 26031, -1000, 26031, -1000, -1000, -1000, + 26031, -1000, 26031, -1000, -1000, 26031, -1000, 26031, -1000, 26031, + -1000, 26031, -1000, 26031, -1000, 26031, -1000, 26031, -1000, 26031, + -1000, 26031, -1000, 26031, -1000, 26031, -1000, 26031, -1000, 26031, + -1000, 26031, -1000, 26031, -1000, 26031, -1000, 26031, -1000, 26031, + -1000, -1000, -1000, 26031, -1000, 26031, -1000, 26031, -1000, -1000, + 26031, -1000, 26031, -1000, 26031, -1000, 26031, 26031, -1000, 26031, + 26031, 26031, -1000, 26031, 26031, 26031, 26031, -1000, -1000, -1000, + -1000, 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, 26031, + 26031, -1000, -1000, -1000, -1000, -1000, -1000, 26031, -1000, 46057, + 98, -237, 1481, 98, 1481, 27581, 899, 854, 26806, -1000, + 26031, 18278, -1000, -1000, -1000, -1000, -1000, 26031, 26031, 26031, + 26031, 26031, 26031, -1000, -1000, -1000, 26031, 26031, -1000, 26031, + -1000, 26031, -1000, -1000, -1000, -1000, -1000, 983, -1000, 861, + 852, 918, 61438, -1000, -1000, -1000, -1000, 2095, -1000, 2744, + -1000, 2502, 2496, 2823, 2810, 26031, -1000, 35291, 62976, 62976, + 294, 62976, 297, 527, 2378, -1000, 2309, 2309, 2309, -1000, + 2682, -1000, 2262, 1466, -1000, -1000, -1000, -1000, -1000, -390, + -1000, 2541, 2500, 943, 943, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 15170, 2745, 26031, 2745, 2374, 62207, 2193, -1000, + 32984, 61438, 62207, 35291, 35291, 35291, 35291, 35291, -1000, 2415, + 2409, -1000, 2428, 2411, 2471, 62976, -1000, 1890, 1871, -1000, + 26031, 37598, 1987, 35291, -1000, -1000, 35291, 62976, 14393, -1000, + -1000, 60, 50, -1000, -1000, -1000, -1000, 2192, -1000, -1000, + 1164, 2709, 2553, -1000, -1000, -1000, -1000, -1000, -1000, 1869, + -1000, 1862, 2078, 1829, 1823, 337, -1000, 2216, 2637, 1055, + 1055, -1000, 1398, -1000, 1483, 1762, 1760, -1000, -1000, -1000, + 477, -1000, -1000, -553, 1395, 2256, 2204, 26031, 2241, 2779, + 2061, 61438, -1000, -1000, 62207, -1000, 278, -1000, 407, 61438, + -1000, -1000, -1000, 414, 62976, -1000, 7780, -1000, -1000, -1000, + 262, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 62976, 2212, + -1000, -1000, -1000, -1000, -1000, 252, 242, 1754, 260, 1753, + -1000, 260, -1000, 62976, 950, 2362, 62976, -1000, -1000, -1000, + 1181, 1181, -1000, -1000, 2635, -1000, 1483, 1669, 28356, 28356, + -1000, 948, -1000, -1000, 386, -210, 2238, 2238, -1000, 2238, + 2239, -1000, 2238, 199, 2238, 197, 2238, -1000, -1000, 1504, + 1504, -1000, 1622, 2332, 2300, 3042, -1000, 1571, 26031, 3024, + -1000, -1000, -237, -237, -237, -237, -237, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -75, 2986, 2880, + 1669, -1000, 2234, 2232, -1000, 1669, 26031, 1669, 1504, 2289, + 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, + 1669, 1669, 2283, 2278, 2228, 2215, 2211, 2203, 2199, 2194, + 2182, 2160, 2108, 2098, 2076, 2064, 2056, 1983, 1669, 1669, + 1914, 1669, 1910, 1821, -1000, 1571, 1622, 2838, 1622, 1669, + 1669, 2721, 249, 1669, 1819, 1819, 1819, 1819, 1819, 1622, + 1622, 1622, 1622, 1669, 61438, -1000, -237, -1000, -1000, -291, + -296, -1000, 1504, -237, 2071, 28356, 1669, 28356, 28356, 28356, + 1669, 1504, -1000, 1793, 1768, 2714, 1719, 1669, 2589, 1669, + 1669, 1669, 1652, -1000, 2737, 2193, 2737, 2193, 2737, 1783, + 1419, 62976, -1000, -1000, -1000, -1000, 2810, 2796, -1000, 2067, + 2193, -1000, -1000, -1000, -1000, -1000, 516, 62976, 62976, 2369, + 2366, 2358, -1000, 1898, -1000, -1000, 116, 615, -1000, 2515, + 2500, -1000, 2775, 2529, 2774, -1000, -1000, -1000, -1000, -1000, + 1571, -1000, -1000, 2667, 1979, -1000, 1075, 2093, -1000, -1000, + 22931, 1791, 2472, 883, 1783, 2114, 3750, 2314, 2356, 3771, + -1000, -1000, -1000, -1000, 2401, -1000, 2400, -1000, -1000, 2219, + -1000, 2568, 421, 35291, 2112, 2112, -1000, 877, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 1250, 7780, 2865, -1000, 1686, + -1000, 1515, 256, 1393, -1000, -1000, 1055, 1055, -1000, 1194, + 1193, -1000, 62976, 2227, -1000, 853, 1684, 853, 1388, -1000, + -1000, 1381, -1000, -1000, -1000, -1000, 2153, 2393, -1000, -1000, + -1000, -1000, 299, 2226, 2773, -1000, 26031, 2223, 1059, 2753, + 61438, 61438, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 829, 1055, -491, 382, 371, 1055, 1055, + 1055, -554, -1000, -1000, 1780, 1759, -1000, -198, -1000, 26031, + -1000, -1000, -1000, -1000, -1000, 1344, 1344, 1666, 1653, 1640, + -1000, 2219, -187, 61438, 61438, 61438, 61438, -1000, -1000, -1000, + 1353, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 948, 1504, 413, -191, 1504, -1000, -1000, + 853, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 26031, -1000, 26031, -1000, 26031, 1571, 26031, -1000, -1000, + -1000, -1000, -1000, 2745, 1638, 26031, 26031, -1000, 1378, 1377, + -237, 1669, -1000, -1000, -1000, 26031, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 26031, + -1000, 26031, -1000, 26031, -1000, 26031, -1000, 26031, -1000, 26031, + -1000, 26031, -1000, 26031, -1000, 26031, -1000, 26031, -1000, 26031, + -1000, 26031, -1000, 26031, -1000, 26031, -1000, 26031, -1000, 26031, + -1000, -1000, 26031, -1000, -1000, -1000, 26031, -1000, 26031, -1000, + 26031, -1000, -1000, -1000, 26031, 285, 1365, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1504, 419, + -1000, -1000, -1000, 2815, -1000, 1504, 26031, 1924, -1000, 1924, + 1924, 1924, -1000, -1000, -1000, 26031, -1000, 26031, 26031, -1000, + 26031, -1000, 26031, -1000, -1000, -1000, -1000, 26031, 2193, 2570, + 45288, 2193, 45288, 2193, 37598, -1000, -1000, 2796, 2794, 2768, + 268, 62976, -1000, -1000, 62976, 62976, 62976, -1000, 2514, 2519, + 2519, 2515, -1000, 2766, 2765, -1000, 1633, 2761, 1627, 1184, + -1000, 62207, 26031, -1000, 2193, 44519, -1000, 491, 61438, 2193, + 61438, -1000, 2790, -1000, -1000, 26031, 2214, -1000, 26031, -1000, + -1000, -1000, -1000, 8698, 2810, 2112, -1000, -1000, 958, -1000, + 26031, -1000, 12602, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 1614, 1586, -1000, -1000, 2208, 26031, -1000, -1000, + -1000, 1872, 1794, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 414, -547, 2748, 61438, 1373, -1000, 1736, + 2061, 357, 2193, 1559, 1055, 1055, 1055, 1372, 1371, 44519, + 1732, -1000, 61438, 459, -1000, 414, -1000, -204, -205, 1669, + -1000, -1000, 2707, -1000, 18278, -1000, -1000, 2206, 2237, -1000, + -1000, -1000, -1000, 2444, -181, -194, -1000, -1000, 1669, 1669, + 1669, 2339, 1504, -1000, 1669, 1669, 1769, 1752, -1000, -1000, + 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, + 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, 1669, + 1622, 1625, -1000, 285, 1504, 2347, -1000, -1000, 8698, -1000, + -1000, 2790, 2759, 98, -1000, -1000, 280, 98, 1571, 1049, + 1504, 1504, 1049, 1590, 1669, 1467, 1447, 1669, 1669, 38367, + -1000, 2756, 2751, 1721, -1000, -1000, 45288, 1721, 45288, 983, + 2794, -245, 26031, 26031, 1504, 2062, -1000, 61438, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 2509, 1303, -1000, -1000, -1000, + -1000, 1550, 1536, -1000, 1526, -1000, 2864, -1000, 1571, -1000, + 2193, 2193, -1000, 844, 2093, -1000, 2745, 1571, 61438, 1571, + 113, 2790, -1000, 1669, -1000, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, + 2193, 2193, 2193, 2193, 2193, 2193, -1000, -1000, 61438, 2402, + -1000, -1000, 1723, 169, -1000, 1670, 2061, -1000, -1000, 714, + -1000, 26031, -1000, 44519, 1518, 1512, -1000, -1000, -1000, -1000, + -554, -1000, -1000, -1000, -1000, -1000, -1000, 488, 1995, -1000, + 1054, 61438, 62976, -1000, 2425, -1000, -1000, -1000, -1000, 26031, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 2567, 61657, 19, -472, -1000, -469, 24712, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 1494, 844, 1338, 27037, 27037, - 2661, 2661, 27037, -1000, -1000, -1000, 1068, 1068, 37817, -1000, - 27037, 24712, -1000, -1000, 24712, 24712, 24712, 1049, -1000, 24712, - 2253, -1000, 24712, -1000, -278, 1718, 1290, 1290, 1290, 1290, - -278, -278, -278, -278, -278, -278, -278, -278, -278, -278, - 2050, -1000, 24712, 24712, 24712, 1484, 376, -1000, -1000, -1000, - -278, 24712, -1000, -1000, 2766, -1000, 24712, -1000, 37817, 24712, - 24712, 24712, -1000, -1000, -1000, 24712, 24712, -1000, -1000, 24712, - -1000, 24712, -1000, -1000, -1000, -1000, -1000, -1000, 24712, -1000, - 24712, -1000, -1000, -1000, 24712, -1000, 24712, -1000, -1000, 24712, - -1000, 24712, -1000, 24712, -1000, 24712, -1000, 24712, -1000, 24712, - -1000, 24712, -1000, 24712, -1000, 24712, -1000, 24712, -1000, 24712, - -1000, 24712, -1000, 24712, -1000, 24712, -1000, 24712, -1000, 24712, - -1000, 24712, -1000, 24712, -1000, -1000, -1000, 24712, -1000, 24712, - -1000, 24712, -1000, -1000, 24712, -1000, 24712, -1000, 24712, -1000, - 24712, 24712, -1000, 24712, 24712, 24712, -1000, 24712, 24712, 24712, - 24712, -1000, -1000, -1000, -1000, 24712, 24712, 24712, 24712, 24712, - 24712, 24712, 24712, 24712, 24712, -1000, -1000, -1000, -1000, -1000, - -1000, 24712, -1000, 44738, 54, -278, 1489, 54, 1489, 26262, - 879, 845, 25487, -1000, 24712, 18509, -1000, -1000, -1000, -1000, - -1000, 24712, 24712, 24712, 24712, 24712, 24712, -1000, -1000, -1000, - 24712, 24712, -1000, 24712, -1000, 24712, -1000, -1000, -1000, -1000, - -1000, 1025, -1000, 877, 854, 897, 60119, -1000, -1000, -1000, - -1000, 2077, -1000, 2710, -1000, 2444, 2442, 2759, 2748, 23937, - -1000, 33972, 61657, 61657, 303, 61657, 305, 514, 2346, -1000, - 2306, 2306, 2306, -1000, 2619, -1000, 2266, 1459, -1000, -1000, - -1000, -1000, -1000, -417, -1000, 2478, 2440, 923, 923, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 15401, 2627, 24712, 2345, - 60888, 2184, -1000, 31665, 60119, 60888, 33972, 33972, 33972, 33972, - 33972, -1000, 2376, 2372, -1000, 2369, 2360, 2391, 61657, -1000, - 1715, 1972, -1000, 24712, 36279, 2059, 33972, -1000, -1000, 33972, - 61657, 14624, -1000, -1000, 18, -5, -1000, -1000, -1000, -1000, - 1497, -1000, -1000, 1081, 2629, 2502, -1000, -1000, -1000, -1000, - -1000, -1000, 1969, -1000, 1955, 2074, 1937, 1934, 283, -1000, - 2247, 2564, 1008, 1008, -1000, 1352, -1000, 1464, 1762, 1759, - -1000, -1000, -1000, 432, -1000, -1000, -549, 1343, 2248, 2199, - 24712, 2237, 2720, 2055, 60119, -1000, -1000, 60888, -1000, 302, - -1000, 450, 60119, -1000, -1000, -1000, 364, 61657, -1000, 9649, - -1000, -1000, -1000, 281, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 61657, 2198, -1000, -1000, -1000, -1000, -1000, 254, 243, - 1754, 260, 1747, -1000, 260, -1000, 61657, 985, 2320, 61657, - -1000, -1000, -1000, 1157, 1157, -1000, -1000, 2562, -1000, 1464, - 1290, 27037, 27037, -1000, 934, -1000, -1000, 503, -253, 2229, - 2229, -1000, 2229, 2231, -1000, 2229, 225, 2229, 199, 2229, - -1000, -1000, 1484, 1484, -1000, 1718, 2317, 1706, 2929, -1000, - 1210, 24712, 2864, -1000, -1000, -278, -278, -278, -278, -278, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -76, 2860, 2615, 1290, -1000, 2228, 2227, -1000, 1290, 24712, - 1290, 1484, 2308, 1290, 1290, 1290, 1290, 1290, 1290, 1290, - 1290, 1290, 1290, 1290, 1290, 2304, 2300, 2273, 2263, 2233, - 2211, 2202, 2194, 2189, 2157, 2149, 2141, 2127, 2096, 2087, - 2052, 1290, 1290, 2043, 1290, 1959, 1925, -1000, 1210, 1718, - 2610, 1718, 1290, 1290, 2601, 272, 1290, 1932, 1932, 1932, - 1932, 1932, 1718, 1718, 1718, 1718, 1290, 60119, -1000, -278, - -1000, -1000, -321, -336, -1000, 1484, -278, 2067, 27037, 1290, - 27037, 27037, 27037, 1290, 1484, -1000, 1921, 1908, 2428, 1904, - 1290, 2219, 1290, 1290, 1290, 1888, -1000, 2655, 2184, 2655, - 2184, 2655, 1918, 1456, 61657, -1000, -1000, -1000, -1000, 2748, - 2744, -1000, 2065, 2184, -1000, -1000, -1000, -1000, -1000, 487, - 61657, 61657, 2340, 2339, 2338, -1000, 1824, -1000, -1000, 129, - 620, -1000, 2461, 2440, -1000, 2719, 2471, 2718, -1000, -1000, - -1000, -1000, -1000, 1210, -1000, 2591, 2058, -1000, 1017, 2136, - -1000, -1000, 23162, 1930, 2427, 841, 1918, 2113, 3291, 2309, - 2337, 3731, -1000, -1000, -1000, -1000, 2370, -1000, 2366, -1000, - -1000, 2216, -1000, 2114, 369, 33972, 2034, 2034, -1000, 833, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1216, 9649, 2797, - -1000, 1728, -1000, 1488, 261, 1332, -1000, -1000, 1008, 1008, - -1000, 1094, 1091, -1000, 61657, 2226, -1000, 912, 1726, 912, - 1329, -1000, -1000, 1324, -1000, -1000, -1000, -1000, 2242, 2424, - -1000, -1000, -1000, -1000, 309, 2224, 2714, -1000, 24712, 2222, - 1012, 2016, 60119, 60119, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 486, 1008, -492, 335, 334, - 1008, 1008, 1008, -550, -1000, -1000, 1916, 1910, -1000, -234, - -1000, 24712, -1000, -1000, -1000, -1000, -1000, 1315, 1315, 1723, - 1713, 1703, -1000, 2216, -205, 60119, 60119, 60119, 60119, -1000, - -1000, -1000, 1269, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 934, 1484, 378, -209, 1484, - -1000, -1000, 912, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 24712, -1000, 24712, -1000, 24712, 1210, 24712, - -1000, -1000, -1000, -1000, -1000, 2627, 1690, 24712, 24712, -1000, - 1311, 1310, -278, 1290, -1000, -1000, -1000, 24712, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 24712, -1000, 24712, -1000, 24712, -1000, 24712, -1000, 24712, - -1000, 24712, -1000, 24712, -1000, 24712, -1000, 24712, -1000, 24712, - -1000, 24712, -1000, 24712, -1000, 24712, -1000, 24712, -1000, 24712, - -1000, 24712, -1000, -1000, 24712, -1000, -1000, -1000, 24712, -1000, - 24712, -1000, 24712, -1000, -1000, -1000, 24712, 257, 1068, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 1484, 368, -1000, -1000, -1000, 2751, -1000, 1484, 24712, 2661, - -1000, 2661, 2661, 2661, -1000, -1000, -1000, 24712, -1000, 24712, - 24712, -1000, 24712, -1000, 24712, -1000, -1000, -1000, -1000, 24712, - 2184, 2479, 43969, 2184, 43969, 2184, 36279, -1000, -1000, 2744, - 2734, 2699, 249, 61657, -1000, -1000, 61657, 61657, 61657, -1000, - 2456, 2465, 2465, 2461, -1000, 2698, 2687, -1000, 1681, 2686, - 1677, 1086, -1000, 60888, 24712, -1000, 2184, 43200, -1000, 476, - 60119, 2184, 60119, -1000, 2711, -1000, -1000, 24712, 2206, -1000, - 24712, -1000, -1000, -1000, -1000, 6546, 2748, 2034, -1000, -1000, - 948, -1000, 24712, -1000, 12151, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 1658, 1650, -1000, -1000, 2205, 24712, - -1000, -1000, -1000, 1776, 1639, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 364, -548, 1894, 60119, 1286, - -1000, 1866, 2055, 356, 2184, 1644, 1008, 1008, 1008, 1280, - 1278, 43200, 1856, -1000, 60119, 421, -1000, 364, -1000, -247, - -248, 1290, -1000, -1000, 2625, -1000, 18509, -1000, -1000, 2197, - 2301, -1000, -1000, -1000, -1000, 2403, -197, -218, -1000, -1000, - 1290, 1290, 1290, 1731, 1484, -1000, 1290, 1290, 1636, 1628, - -1000, -1000, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, - 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290, - 1290, 1290, 1718, 1841, -1000, 257, 1484, 2336, -1000, -1000, - 6546, -1000, -1000, 2711, 2681, 54, -1000, -1000, 287, 54, - 1210, 1041, 1484, 1484, 1041, 1837, 1290, 1823, 1722, 1290, - 1290, 37048, -1000, 2676, 2672, 1835, -1000, -1000, 43969, 1835, - 43969, 1025, 2734, -289, 24712, 24712, 1484, 2063, -1000, 60119, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 2448, 1296, -1000, - -1000, -1000, -1000, 1608, 1589, -1000, 1537, -1000, 2790, -1000, - 1210, -1000, 2184, 2184, -1000, 768, 2136, -1000, 2627, 1210, - 60119, 1210, 73, 2711, -1000, 1290, -1000, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, - 2184, 2184, 2184, 2184, 2184, 2184, 2184, 2184, -1000, -1000, - 60119, 1712, -1000, -1000, 1839, 160, -1000, 1490, 2055, -1000, - -1000, 719, -1000, 24712, -1000, 43200, 1522, 1511, -1000, -1000, - -1000, -1000, -550, -1000, -1000, -1000, -1000, -1000, -1000, 474, - 2054, -1000, 1002, 60119, 61657, -1000, 2394, -1000, -1000, -1000, - -1000, 24712, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 24712, - -1000, 1484, 2335, -1000, -348, -1000, -509, 24712, -278, -1000, - -1000, -278, -1000, -1000, -1000, -1000, -1000, 24712, -1000, -1000, - 24712, -1000, 24712, -1000, -1000, 1835, -1000, -1000, -1000, 42431, - -1000, 1835, -1000, 1835, -1000, -289, -1000, 2048, -1000, 60119, - 1210, 354, 8032, 249, 5383, -1000, 1283, -1000, -1000, -1000, - -1000, -1000, 60888, 60119, 2136, 60119, -1000, -1000, 1803, 1484, - 2184, 2627, -1000, 1775, -1000, -1000, 2192, 2199, -1000, -1000, - -1000, 22387, -1000, -1000, -1000, -1000, -1000, 279, -200, 18509, - 13847, 1752, -1000, -203, 1290, 1718, -1000, -459, -1000, -1000, - -1000, -1000, 297, -1000, -1000, 2014, -1000, -1000, 1649, 1638, - 1634, -1000, -1000, -1000, -1000, -1000, -1000, -289, -1000, -1000, - 2624, -1000, -250, -1000, -567, -1000, -1000, 8032, 24712, 33203, - 41662, -1000, -1000, -1000, -1000, 1499, 1688, -1000, -1000, -1000, - 36279, 59350, -1000, -179, 322, 24712, 2186, 1484, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 571, -1000, - -1000, -1000, 2198, -216, -1000, -1000, -1000, 5852, -477, -319, - -320, 27037, -1000, 24712, -1000, 24712, -1000, 24712, -1000, 60119, - 2184, -1000, -1000, 1048, 8032, -1000, -567, 1400, 4501, 540, - 508, -1000, -1000, -1000, 2569, -1000, -1000, 2415, -1000, -1000, - -1000, 1625, -1000, 2942, -360, 2332, -1000, -95, -1000, -1000, - -1000, 1142, 1508, -1000, 1274, -1000, -1000, -1000, -1000, 1627, - 60119, -1000, 17732, -205, -225, 1085, -1000, -1000, -1000, -1000, - -1000, 2661, 1449, 1444, 1290, -1000, 60119, -1000, -1000, 8032, - 2517, 2641, 2639, -1000, 118, 118, 1493, -1000, -1000, 59350, - -354, 933, 6546, -1000, 2326, 2318, 2770, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -556, 1621, -1000, -1000, -1000, 5852, - -325, -1000, 24712, -1000, 24712, -1000, 1484, 6867, -1000, 9649, - 30895, 960, -1000, 993, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 2607, 73, -1000, 2780, -1000, 2764, 998, 998, -1000, 1273, - -556, -1000, -1000, -1000, 1290, 1290, -1000, 1059, 1053, -1000, - 24712, 24712, -1000, 6389, -1000, -1000, -1000, -1000, 542, -1000, - -1000, -1000, -1000, 8895, -362, -1000, -1000, -1000, -1000, -1000, - 428, 1314, -1000, -1000, -1000, -1000, -1000, 1010, 8032, -1000, - 1026, 1290, -1000, 30895, -1000, -1000, 6546, -1000, -1000, -1000, - 458, 8032, 8032, -1000, -1000, 251, -1000, 8032, 251, -1000, - -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 26031, -1000, 1504, + 2345, -1000, -340, -1000, -484, 26031, -237, -1000, -1000, -237, + -1000, -1000, -1000, -1000, -1000, 26031, -1000, -1000, 26031, -1000, + 26031, -1000, -1000, 1721, -1000, -1000, -1000, 43750, -1000, 1721, + -1000, 1721, -1000, -245, -1000, 1972, -1000, 61438, 1571, 352, + 6007, 268, 7049, -1000, 1296, -1000, -1000, -1000, -1000, -1000, + 62207, 61438, 2093, 61438, -1000, -1000, 1716, 1504, 2193, 2745, + -1000, 1679, -1000, -1000, 2198, 2204, -1000, -1000, -1000, 22156, + -1000, -1000, -1000, -1000, -1000, 273, -185, 18278, 13616, 1658, + -1000, -186, 1669, 1622, -1000, -449, -1000, -1000, -1000, -1000, + 254, -1000, -1000, 1953, -1000, -1000, 1415, 1400, 1346, -1000, + -1000, -1000, -1000, -1000, -1000, -245, -1000, -1000, 2704, -1000, + -207, -1000, -560, -1000, -1000, 6007, 26031, 34522, 42981, -1000, + -1000, -1000, -1000, 1592, 1564, -1000, -1000, -1000, 37598, 60669, + -1000, -176, 448, 26031, 2197, 1504, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 842, -1000, -1000, -1000, + 2212, -192, -1000, -1000, -1000, 4452, -468, -288, -290, 28356, + -1000, 26031, -1000, 26031, -1000, 26031, -1000, 61438, 2193, -1000, + -1000, 1066, 6007, -1000, -560, 1647, 2943, 820, 802, -1000, + -1000, -1000, 2654, -1000, -1000, 2430, -1000, -1000, -1000, 1555, + -1000, 4527, -312, 2321, -1000, -67, -1000, -1000, -1000, 1239, + 1500, -1000, 1357, -1000, -1000, -1000, -1000, 2043, 61438, -1000, + 17501, -187, -195, 1151, -1000, -1000, -1000, -1000, -1000, 1924, + 1301, 1173, 1669, -1000, 61438, -1000, -1000, 6007, 2657, 2735, + 2710, -1000, 174, 174, 1495, -1000, -1000, 60669, -303, 947, + 8698, -1000, 2319, 2318, 2818, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -556, 1531, -1000, -1000, -1000, 4452, -293, -1000, + 26031, -1000, 26031, -1000, 1504, 5292, -1000, 7780, 32214, 966, + -1000, 1037, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 2680, 113, + -1000, 2850, -1000, 2819, 969, 969, -1000, 1354, -556, -1000, + -1000, -1000, 1669, 1669, -1000, 1135, 1131, -1000, 26031, 26031, + -1000, 1141, -1000, -1000, -1000, -1000, 824, -1000, -1000, -1000, + -1000, 8259, -314, -1000, -1000, -1000, -1000, -1000, 466, 1345, + -1000, -1000, -1000, -1000, -1000, 1050, 6007, -1000, 1032, 1669, + -1000, 32214, -1000, -1000, 8698, -1000, -1000, -1000, 489, 6007, + 6007, -1000, -1000, 296, -1000, 6007, 296, -1000, -1000, } var yyPgo = [...]int{ - 0, 3462, 3461, 41, 8, 60, 59, 3460, 2851, 3458, - 3456, 2828, 3455, 202, 3452, 3450, 3446, 3444, 3440, 3437, - 204, 203, 199, 3432, 3430, 3429, 3428, 3425, 3423, 3422, - 3417, 3411, 45, 107, 62, 117, 217, 226, 3404, 3402, - 42, 186, 216, 3399, 3398, 3397, 3396, 3395, 130, 213, - 99, 101, 214, 3390, 3386, 90, 3384, 3383, 3381, 3379, - 3378, 19, 18, 36, 33, 3374, 3370, 3363, 26, 3361, - 209, 205, 201, 1113, 3358, 208, 126, 52, 3357, 3356, - 3349, 3347, 12, 10, 3345, 11, 3343, 6, 3342, 3337, - 3331, 3330, 3320, 3318, 3303, 3293, 3292, 3290, 3287, 3285, - 3283, 3282, 3281, 3280, 3279, 297, 3277, 3276, 47, 3275, - 94, 3274, 3273, 3272, 3264, 3261, 20, 3259, 3258, 28, - 48, 75, 3257, 3256, 49, 3251, 3250, 3248, 3245, 3241, - 32, 3239, 39, 3238, 80, 3237, 3236, 136, 3228, 3226, - 3224, 57, 3223, 3218, 3217, 27, 193, 3216, 3213, 161, - 3212, 3211, 3209, 190, 221, 3207, 2426, 3206, 121, 3204, - 3201, 3198, 188, 187, 223, 3196, 115, 3194, 3193, 3192, - 3186, 145, 3185, 3184, 4599, 3178, 3177, 16, 21, 140, - 3176, 3175, 166, 14, 77, 3172, 9, 4, 3167, 3164, - 17, 88, 3143, 113, 3140, 3138, 116, 78, 3137, 108, - 111, 3136, 3134, 25, 15, 3132, 1, 3, 2, 81, - 3130, 3129, 124, 3127, 3125, 3124, 106, 3123, 3120, 4579, - 3119, 102, 146, 112, 92, 3117, 183, 72, 3116, 3115, - 3112, 3110, 3103, 3093, 63, 3092, 3090, 3089, 158, 191, - 118, 3087, 3086, 149, 366, 144, 64, 148, 3082, 173, - 3079, 147, 96, 3076, 194, 3071, 3068, 154, 156, 3067, - 3059, 71, 181, 206, 3044, 110, 141, 128, 143, 104, - 160, 3043, 3040, 3039, 73, 85, 3037, 3036, 3035, 3032, - 195, 3031, 3030, 83, 3028, 70, 3027, 192, 3025, 330, - 76, 3023, 189, 178, 3022, 86, 185, 3017, 3009, 3008, - 82, 133, 84, 69, 3001, 175, 182, 137, 179, 2999, - 2998, 66, 2997, 2986, 2985, 215, 336, 2983, 2981, 291, - 196, 163, 150, 100, 2980, 222, 2979, 2978, 2977, 29, - 5792, 8106, 211, 44, 184, 2974, 2972, 9925, 30, 46, - 43, 2971, 219, 2969, 142, 2968, 2966, 2965, 218, 224, - 120, 180, 74, 2964, 2963, 2961, 2960, 37, 2958, 2954, - 2953, 2951, 2950, 2949, 58, 56, 55, 89, 237, 79, - 24, 109, 177, 172, 87, 2948, 2944, 2943, 134, 103, - 2935, 174, 171, 138, 132, 2931, 198, 164, 127, 2927, - 65, 54, 2924, 2923, 2914, 2912, 105, 2909, 2908, 2907, - 2906, 169, 165, 131, 97, 2904, 98, 122, 170, 168, - 61, 2902, 50, 2901, 2900, 53, 212, 68, 2899, 2888, - 2887, 40, 2886, 31, 119, 125, 2885, 7762, 2883, 34, - 283, 167, 2882, 2881, 13, 23, 22, 2878, 2877, 2875, - 2872, 152, 2871, 2866, 2864, 2860, 38, 51, 35, 7, - 123, 159, 95, 2857, 2854, 162, 2852, 2827, 0, 1830, - 139, 2815, 227, + 0, 3563, 3561, 41, 9, 58, 57, 3560, 2889, 3553, + 3552, 2884, 3551, 197, 3547, 3545, 3544, 3540, 3536, 3535, + 204, 199, 198, 3533, 3532, 3531, 3530, 3528, 3526, 3525, + 3524, 3518, 47, 107, 74, 125, 223, 265, 3513, 3506, + 45, 179, 214, 3505, 3502, 3500, 3498, 3497, 127, 211, + 97, 99, 212, 3495, 3494, 88, 3490, 3486, 3485, 3479, + 3478, 12, 19, 36, 33, 3477, 3474, 3471, 25, 3468, + 210, 208, 206, 1138, 3467, 209, 124, 51, 3466, 3463, + 3458, 3448, 13, 10, 3447, 11, 3438, 6, 3436, 3435, + 3433, 3431, 3427, 3420, 3416, 3415, 3412, 3410, 3409, 3408, + 3402, 3395, 3383, 3382, 3380, 225, 3379, 3378, 46, 3377, + 90, 3375, 3374, 3371, 3370, 3369, 22, 3368, 3365, 27, + 147, 70, 3362, 3360, 49, 3359, 3358, 3357, 3356, 3355, + 28, 3351, 39, 3343, 101, 3338, 3332, 132, 3321, 3319, + 3304, 42, 3295, 3294, 3292, 30, 190, 3288, 3287, 159, + 3286, 3285, 3283, 189, 216, 3279, 2465, 3272, 113, 3271, + 3270, 3269, 187, 183, 220, 3265, 109, 3263, 3262, 3261, + 3259, 143, 3254, 3252, 4183, 3251, 3246, 17, 20, 140, + 3243, 3240, 166, 14, 75, 3239, 7, 8, 3238, 3228, + 18, 87, 3223, 111, 3219, 3214, 110, 80, 3213, 105, + 112, 3211, 3210, 26, 16, 3203, 1, 3, 2, 77, + 3200, 3199, 121, 3195, 3193, 3192, 104, 3191, 3187, 5254, + 3184, 102, 157, 115, 84, 3182, 184, 86, 3181, 3180, + 3177, 3175, 3172, 3171, 63, 3169, 3167, 3166, 156, 273, + 120, 3163, 3162, 149, 355, 144, 64, 145, 3161, 172, + 3160, 146, 92, 3159, 191, 3157, 3156, 152, 151, 3155, + 3150, 67, 182, 207, 3148, 106, 136, 128, 141, 103, + 155, 3145, 3143, 3142, 68, 82, 3132, 3131, 3126, 3124, + 193, 3123, 3122, 81, 3121, 66, 3118, 186, 3117, 331, + 71, 3106, 192, 175, 3103, 83, 180, 3100, 3096, 3095, + 76, 123, 78, 59, 3093, 178, 185, 133, 201, 3092, + 3090, 65, 3089, 3086, 3085, 213, 350, 3084, 3080, 297, + 195, 161, 148, 98, 3079, 215, 3078, 3076, 3067, 29, + 6093, 8449, 203, 40, 177, 3066, 3064, 9686, 31, 50, + 43, 3063, 219, 3061, 142, 3060, 3057, 3047, 217, 224, + 118, 181, 69, 3046, 3045, 3044, 3042, 37, 3041, 3040, + 3037, 3033, 3026, 3025, 56, 55, 54, 137, 243, 73, + 23, 108, 176, 170, 85, 3024, 3020, 3019, 131, 96, + 3018, 174, 173, 139, 119, 3015, 196, 162, 126, 3013, + 62, 53, 3012, 3003, 3002, 3000, 100, 2999, 2988, 2987, + 2986, 169, 163, 130, 94, 2985, 95, 116, 164, 168, + 60, 2984, 61, 2983, 2980, 48, 205, 72, 2973, 2972, + 2969, 44, 2963, 32, 117, 134, 2962, 7569, 2961, 34, + 238, 171, 2945, 2941, 15, 21, 24, 2940, 2939, 2938, + 2935, 154, 2929, 2925, 2920, 2918, 38, 52, 35, 4, + 122, 158, 89, 2917, 2913, 160, 2911, 2909, 0, 1835, + 135, 2906, 221, } -//line sql.y:9284 +//line sql.y:9288 type yySymType struct { union any empty struct{} @@ -9341,116 +9473,117 @@ var yyR1 = [...]int{ 39, 39, 42, 42, 41, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 32, 32, 32, 32, 33, 33, 33, 33, 33, - 38, 38, 18, 19, 37, 37, 37, 20, 20, 135, - 135, 21, 22, 22, 22, 22, 460, 460, 214, 214, - 212, 212, 213, 213, 300, 300, 23, 304, 304, 306, - 306, 306, 306, 294, 294, 294, 24, 24, 305, 305, - 307, 307, 307, 310, 310, 310, 310, 351, 351, 351, - 25, 25, 25, 25, 25, 25, 155, 429, 429, 428, - 423, 423, 422, 422, 421, 426, 426, 425, 425, 424, - 45, 44, 46, 46, 46, 47, 56, 56, 56, 56, - 57, 58, 430, 430, 392, 74, 74, 73, 73, 73, - 73, 73, 73, 75, 75, 71, 71, 70, 70, 72, - 72, 394, 394, 380, 380, 393, 393, 393, 393, 393, - 393, 393, 379, 379, 167, 167, 271, 271, 271, 271, + 38, 38, 18, 18, 19, 19, 37, 37, 37, 20, + 20, 135, 135, 21, 22, 22, 22, 22, 460, 460, + 214, 214, 212, 212, 213, 213, 300, 300, 23, 304, + 304, 306, 306, 306, 306, 294, 294, 294, 24, 24, + 305, 305, 307, 307, 307, 310, 310, 310, 310, 351, + 351, 351, 25, 25, 25, 25, 25, 25, 155, 429, + 429, 428, 423, 423, 422, 422, 421, 426, 426, 425, + 425, 424, 45, 44, 46, 46, 46, 47, 56, 56, + 56, 56, 57, 58, 430, 430, 392, 74, 74, 73, + 73, 73, 73, 73, 73, 75, 75, 71, 71, 70, + 70, 72, 72, 394, 394, 380, 380, 393, 393, 393, + 393, 393, 393, 393, 379, 379, 167, 167, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, - 271, 271, 271, 445, 445, 445, 445, 444, 444, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 178, 178, - 190, 190, 190, 190, 190, 190, 176, 176, 177, 175, - 175, 175, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 449, 449, + 271, 271, 271, 271, 271, 445, 445, 445, 445, 444, + 444, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 178, 178, 190, 190, 190, 190, 190, 190, 176, 176, + 177, 175, 175, 175, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 189, 189, 184, 184, 184, 186, 186, 185, 185, 185, - 187, 187, 446, 446, 446, 446, 357, 357, 357, 357, - 360, 360, 358, 358, 358, 358, 358, 358, 358, 358, - 358, 359, 359, 359, 359, 359, 359, 359, 361, 361, - 361, 361, 361, 362, 362, 362, 362, 362, 362, 362, + 449, 449, 189, 189, 184, 184, 184, 186, 186, 185, + 185, 185, 187, 187, 446, 446, 446, 446, 357, 357, + 357, 357, 360, 360, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 359, 359, 359, 359, 359, 359, 359, + 361, 361, 361, 361, 361, 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, - 363, 363, 363, 363, 363, 363, 363, 363, 378, 378, - 367, 367, 372, 372, 373, 373, 374, 374, 374, 375, - 375, 375, 376, 376, 369, 369, 369, 369, 369, 369, - 369, 369, 369, 371, 371, 370, 370, 370, 381, 406, - 406, 405, 405, 403, 403, 403, 403, 403, 403, 403, - 403, 390, 390, 400, 400, 400, 400, 400, 389, 389, - 385, 385, 385, 386, 386, 387, 387, 384, 384, 388, - 388, 402, 402, 401, 401, 382, 382, 383, 383, 408, - 447, 447, 447, 447, 447, 448, 448, 409, 437, 439, - 439, 439, 438, 438, 435, 436, 434, 434, 434, 434, - 434, 110, 110, 110, 323, 323, 324, 324, 398, 398, - 397, 397, 397, 399, 399, 396, 396, 396, 396, 396, + 362, 362, 363, 363, 363, 363, 363, 363, 363, 363, + 378, 378, 367, 367, 372, 372, 373, 373, 374, 374, + 374, 375, 375, 375, 376, 376, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 371, 371, 370, 370, 370, + 381, 406, 406, 405, 405, 403, 403, 403, 403, 403, + 403, 403, 403, 390, 390, 400, 400, 400, 400, 400, + 389, 389, 385, 385, 385, 386, 386, 387, 387, 384, + 384, 388, 388, 402, 402, 401, 401, 382, 382, 383, + 383, 408, 447, 447, 447, 447, 447, 448, 448, 409, + 437, 439, 439, 439, 438, 438, 435, 436, 434, 434, + 434, 434, 434, 110, 110, 110, 323, 323, 324, 324, + 398, 398, 397, 397, 397, 399, 399, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, - 396, 396, 396, 396, 396, 396, 318, 318, 318, 433, - 433, 433, 433, 433, 433, 432, 432, 432, 395, 395, - 395, 395, 431, 431, 76, 76, 252, 252, 450, 450, - 452, 452, 452, 53, 53, 53, 53, 53, 53, 52, - 52, 52, 48, 48, 48, 48, 48, 48, 48, 48, + 396, 396, 396, 396, 396, 396, 396, 396, 318, 318, + 318, 433, 433, 433, 433, 433, 433, 432, 432, 432, + 395, 395, 395, 395, 431, 431, 76, 76, 252, 252, + 450, 450, 452, 452, 452, 53, 53, 53, 53, 53, + 53, 52, 52, 52, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 54, 54, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 26, 26, 26, 26, 26, + 48, 48, 48, 48, 48, 54, 54, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 137, - 137, 138, 138, 138, 138, 140, 140, 140, 411, 411, - 77, 77, 3, 3, 202, 204, 205, 205, 203, 203, - 203, 203, 203, 203, 79, 79, 78, 78, 207, 206, - 208, 208, 208, 1, 1, 2, 2, 4, 4, 416, - 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 137, 137, 138, 138, 138, 138, 140, 140, 140, + 411, 411, 77, 77, 3, 3, 202, 204, 205, 205, + 203, 203, 203, 203, 203, 203, 79, 79, 78, 78, + 207, 206, 208, 208, 208, 1, 1, 2, 2, 4, + 4, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, - 416, 377, 377, 377, 410, 410, 412, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 143, 142, 142, - 141, 144, 144, 144, 144, 144, 144, 144, 144, 414, - 414, 414, 80, 80, 415, 364, 365, 366, 5, 6, - 391, 413, 151, 151, 27, 43, 43, 28, 28, 28, - 28, 28, 29, 29, 90, 93, 93, 91, 91, 91, + 416, 416, 416, 377, 377, 377, 410, 410, 412, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 143, + 142, 142, 141, 144, 144, 144, 144, 144, 144, 144, + 144, 414, 414, 414, 80, 80, 415, 364, 365, 366, + 5, 6, 391, 413, 151, 151, 27, 43, 43, 28, + 28, 28, 28, 28, 29, 29, 90, 93, 93, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 328, 328, 317, 317, 326, 326, 316, - 316, 342, 342, 342, 319, 319, 319, 320, 320, 443, - 443, 443, 313, 313, 92, 92, 92, 343, 343, 343, - 343, 95, 95, 453, 453, 454, 454, 455, 455, 455, - 96, 97, 97, 346, 346, 347, 347, 98, 99, 111, - 111, 111, 111, 111, 112, 112, 112, 112, 112, 112, - 136, 136, 136, 13, 13, 13, 13, 107, 107, 107, - 12, 12, 14, 94, 94, 101, 440, 440, 441, 442, - 442, 442, 442, 102, 104, 30, 30, 30, 30, 30, - 30, 161, 161, 149, 149, 149, 149, 149, 149, 149, - 149, 149, 149, 149, 149, 156, 156, 156, 150, 150, - 461, 105, 106, 106, 154, 154, 154, 147, 147, 147, - 153, 153, 153, 15, 15, 16, 298, 298, 17, 17, - 160, 160, 159, 159, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 157, 157, 158, 158, 158, - 158, 335, 335, 335, 334, 334, 196, 196, 198, 197, - 197, 199, 199, 200, 200, 200, 200, 250, 250, 222, - 222, 290, 290, 291, 291, 289, 289, 297, 297, 292, - 292, 292, 292, 301, 301, 201, 201, 201, 201, 209, - 209, 210, 210, 211, 211, 345, 345, 340, 340, 340, - 339, 339, 215, 215, 215, 217, 216, 216, 216, 216, - 218, 218, 220, 220, 219, 219, 221, 226, 226, 225, - 225, 223, 223, 223, 223, 223, 223, 224, 224, 224, - 224, 227, 227, 174, 174, 174, 174, 174, 174, 174, - 174, 451, 451, 188, 188, 188, 188, 188, 188, 188, - 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, - 191, 280, 280, 179, 179, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 182, 182, + 91, 91, 91, 91, 91, 328, 328, 317, 317, 326, + 326, 316, 316, 342, 342, 342, 319, 319, 319, 320, + 320, 443, 443, 443, 313, 313, 92, 92, 92, 343, + 343, 343, 343, 95, 95, 453, 453, 454, 454, 455, + 455, 455, 96, 97, 97, 346, 346, 347, 347, 98, + 99, 111, 111, 111, 111, 111, 112, 112, 112, 112, + 112, 112, 136, 136, 136, 13, 13, 13, 13, 107, + 107, 107, 12, 12, 14, 94, 94, 101, 440, 440, + 441, 442, 442, 442, 442, 102, 104, 30, 30, 30, + 30, 30, 30, 161, 161, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 156, 156, 156, + 150, 150, 461, 105, 106, 106, 154, 154, 154, 147, + 147, 147, 153, 153, 153, 15, 15, 16, 298, 298, + 17, 17, 160, 160, 159, 159, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 157, 157, 157, + 158, 158, 158, 335, 335, 335, 334, 334, 196, 196, + 198, 197, 197, 199, 199, 200, 200, 200, 200, 250, + 250, 222, 222, 290, 290, 291, 291, 289, 289, 297, + 297, 292, 292, 292, 292, 301, 301, 201, 201, 201, + 201, 209, 209, 210, 210, 211, 211, 345, 345, 340, + 340, 340, 339, 339, 215, 215, 215, 217, 216, 216, + 216, 216, 218, 218, 220, 220, 219, 219, 221, 226, + 226, 225, 225, 223, 223, 223, 223, 223, 223, 224, + 224, 224, 224, 227, 227, 174, 174, 174, 174, 174, + 174, 174, 174, 451, 451, 188, 188, 188, 188, 188, + 188, 188, 191, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 280, 280, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, - 182, 182, 182, 255, 255, 254, 254, 113, 113, 113, - 114, 114, 115, 115, 115, 115, 115, 116, 116, 116, - 116, 116, 116, 116, 118, 118, 117, 117, 241, 241, - 332, 332, 119, 120, 120, 121, 121, 124, 124, 123, - 122, 122, 128, 128, 125, 125, 127, 127, 126, 129, - 129, 130, 131, 131, 314, 314, 228, 228, 237, 237, - 237, 237, 229, 229, 230, 230, 230, 230, 230, 230, - 238, 238, 238, 249, 239, 239, 235, 235, 233, 233, - 233, 233, 233, 233, 233, 233, 233, 233, 233, 234, + 182, 182, 182, 182, 182, 255, 255, 254, 254, 113, + 113, 113, 114, 114, 115, 115, 115, 115, 115, 116, + 116, 116, 116, 116, 116, 116, 118, 118, 117, 117, + 241, 241, 332, 332, 119, 120, 120, 121, 121, 124, + 124, 123, 122, 122, 128, 128, 125, 125, 127, 127, + 126, 129, 129, 130, 131, 131, 314, 314, 228, 228, + 237, 237, 237, 237, 229, 229, 230, 230, 230, 230, + 230, 230, 238, 238, 238, 249, 239, 239, 235, 235, + 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, @@ -9469,39 +9602,38 @@ var yyR1 = [...]int{ 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, - 234, 234, 193, 193, 193, 193, 260, 260, 180, 180, + 234, 234, 234, 234, 193, 193, 193, 193, 260, 260, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, - 180, 180, 180, 181, 181, 194, 194, 194, 194, 195, - 195, 195, 195, 195, 195, 195, 353, 353, 145, 145, + 180, 180, 180, 180, 180, 181, 181, 194, 194, 194, + 194, 195, 195, 195, 195, 195, 195, 195, 353, 353, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 462, 462, 368, 368, - 368, 236, 236, 236, 236, 236, 152, 152, 152, 152, - 152, 350, 350, 350, 354, 354, 354, 352, 352, 352, + 146, 146, 146, 146, 146, 146, 146, 146, 462, 462, + 368, 368, 368, 236, 236, 236, 236, 236, 152, 152, + 152, 152, 152, 350, 350, 350, 354, 354, 354, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, - 352, 352, 355, 355, 258, 258, 148, 148, 256, 256, - 257, 259, 259, 251, 251, 251, 251, 253, 253, 232, - 232, 232, 261, 261, 356, 356, 262, 262, 132, 133, - 133, 134, 134, 263, 263, 265, 264, 264, 266, 267, - 267, 267, 268, 268, 269, 269, 269, 55, 55, 55, - 55, 55, 50, 50, 50, 50, 51, 51, 51, 51, - 163, 163, 164, 164, 164, 166, 166, 165, 165, 108, - 108, 109, 109, 109, 420, 420, 419, 419, 417, 418, - 418, 418, 418, 171, 171, 172, 173, 173, 173, 168, - 168, 169, 169, 287, 287, 287, 287, 287, 287, 287, - 270, 270, 270, 270, 299, 299, 296, 296, 278, 278, - 278, 274, 274, 276, 276, 276, 277, 277, 277, 275, - 284, 284, 286, 286, 285, 285, 281, 281, 282, 282, - 283, 283, 283, 279, 279, 231, 231, 231, 231, 231, - 288, 288, 288, 288, 344, 344, 344, 302, 302, 242, - 242, 243, 243, 247, 247, 246, 246, 244, 245, 248, - 248, 192, 303, 303, 311, 308, 308, 309, 309, 336, - 336, 336, 312, 312, 325, 325, 321, 321, 322, 322, - 315, 315, 327, 327, 327, 103, 240, 240, 407, 407, - 404, 331, 331, 333, 333, 337, 337, 341, 341, 338, - 338, 10, 456, 456, 456, 329, 329, 329, 329, 329, + 352, 352, 352, 352, 355, 355, 258, 258, 148, 148, + 256, 256, 257, 259, 259, 251, 251, 251, 251, 253, + 253, 232, 232, 232, 261, 261, 356, 356, 262, 262, + 132, 133, 133, 134, 134, 263, 263, 265, 264, 264, + 266, 267, 267, 267, 268, 268, 269, 269, 269, 55, + 55, 55, 55, 55, 50, 50, 50, 50, 51, 51, + 51, 51, 163, 163, 164, 164, 164, 166, 166, 165, + 165, 108, 108, 109, 109, 109, 420, 420, 419, 419, + 417, 418, 418, 418, 418, 171, 171, 172, 173, 173, + 173, 168, 168, 169, 169, 287, 287, 287, 287, 287, + 287, 287, 270, 270, 270, 270, 299, 299, 296, 296, + 278, 278, 278, 274, 274, 276, 276, 276, 277, 277, + 277, 275, 284, 284, 286, 286, 285, 285, 281, 281, + 282, 282, 283, 283, 283, 279, 279, 231, 231, 231, + 231, 231, 288, 288, 288, 288, 344, 344, 344, 302, + 302, 242, 242, 243, 243, 247, 247, 246, 246, 244, + 245, 248, 248, 192, 303, 303, 311, 308, 308, 309, + 309, 336, 336, 336, 312, 312, 325, 325, 321, 321, + 322, 322, 315, 315, 327, 327, 327, 103, 240, 240, + 407, 407, 404, 331, 331, 333, 333, 337, 337, 341, + 341, 338, 338, 10, 456, 456, 456, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, @@ -9518,6 +9650,7 @@ var yyR1 = [...]int{ 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, @@ -9567,8 +9700,7 @@ var yyR1 = [...]int{ 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, - 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, - 330, 458, 459, 348, 349, 349, 349, + 330, 330, 330, 458, 459, 348, 349, 349, 349, } var yyR2 = [...]int{ @@ -9586,167 +9718,167 @@ var yyR2 = [...]int{ 0, 1, 3, 1, 4, 3, 3, 4, 3, 2, 3, 4, 3, 4, 2, 7, 1, 3, 3, 3, 3, 1, 2, 1, 1, 3, 2, 3, 3, 2, - 3, 3, 5, 7, 10, 9, 1, 7, 8, 1, - 1, 10, 11, 9, 8, 8, 1, 1, 1, 3, - 1, 3, 1, 3, 0, 4, 3, 1, 3, 3, - 3, 3, 3, 1, 1, 2, 5, 4, 1, 3, - 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, - 2, 2, 1, 6, 5, 2, 2, 0, 2, 1, - 0, 2, 1, 3, 3, 0, 1, 1, 3, 3, - 10, 6, 6, 8, 7, 4, 7, 8, 8, 8, - 5, 3, 1, 1, 5, 0, 1, 1, 1, 1, - 2, 2, 2, 0, 1, 4, 4, 4, 4, 4, - 4, 2, 4, 1, 3, 1, 1, 3, 4, 3, - 3, 3, 5, 10, 0, 2, 0, 2, 3, 5, - 3, 4, 2, 3, 2, 3, 3, 3, 3, 2, - 2, 4, 4, 1, 1, 1, 1, 1, 1, 0, - 2, 2, 3, 3, 2, 3, 2, 2, 1, 1, - 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, - 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, + 3, 3, 5, 5, 7, 7, 10, 9, 1, 7, + 8, 1, 1, 10, 11, 9, 8, 8, 1, 1, + 1, 3, 1, 3, 1, 3, 0, 4, 3, 1, + 3, 3, 3, 3, 3, 1, 1, 2, 5, 4, + 1, 3, 3, 2, 2, 2, 2, 2, 1, 1, + 1, 1, 2, 2, 1, 6, 5, 2, 2, 0, + 2, 1, 0, 2, 1, 3, 3, 0, 1, 1, + 3, 3, 10, 6, 6, 8, 7, 4, 7, 8, + 8, 8, 5, 3, 1, 1, 5, 0, 1, 1, + 1, 1, 2, 2, 2, 0, 1, 4, 4, 4, + 4, 4, 4, 2, 4, 1, 3, 1, 1, 3, + 4, 3, 3, 3, 5, 10, 0, 2, 0, 2, + 3, 5, 3, 4, 2, 3, 2, 3, 3, 3, + 3, 2, 2, 4, 4, 1, 1, 1, 1, 1, + 1, 0, 2, 2, 3, 3, 2, 3, 2, 2, + 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, + 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, - 1, 1, 2, 1, 2, 1, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, + 1, 2, 1, 1, 2, 1, 2, 1, 3, 1, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, + 1, 2, 2, 2, 2, 3, 3, 3, 2, 2, + 3, 2, 2, 2, 2, 1, 1, 1, 1, 5, + 2, 5, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 0, 3, 0, 5, 1, 3, 0, 3, + 5, 0, 1, 1, 0, 1, 0, 3, 3, 2, + 2, 2, 1, 2, 2, 0, 1, 0, 2, 2, + 5, 0, 1, 1, 2, 1, 3, 2, 1, 1, + 3, 3, 3, 0, 1, 4, 3, 3, 4, 2, + 0, 2, 1, 1, 1, 1, 1, 0, 1, 1, + 1, 0, 1, 1, 3, 3, 4, 3, 1, 3, + 1, 7, 6, 7, 7, 8, 8, 0, 1, 5, + 2, 1, 1, 1, 0, 1, 3, 3, 1, 1, + 2, 2, 2, 0, 1, 1, 1, 2, 0, 1, + 0, 1, 1, 3, 2, 1, 2, 3, 3, 3, + 4, 4, 3, 3, 3, 3, 4, 4, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 4, 5, 0, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, - 2, 2, 2, 3, 3, 3, 2, 2, 3, 2, - 2, 2, 2, 1, 1, 1, 1, 5, 2, 5, + 3, 1, 1, 1, 0, 1, 0, 1, 0, 2, + 0, 2, 0, 2, 2, 0, 1, 5, 1, 3, + 7, 1, 3, 3, 1, 2, 2, 2, 5, 5, + 5, 6, 8, 5, 5, 4, 4, 4, 6, 5, + 5, 5, 2, 2, 2, 2, 3, 3, 3, 4, + 3, 3, 1, 3, 5, 1, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 2, 2, 3, 4, 4, + 2, 11, 3, 6, 8, 6, 6, 6, 13, 8, + 6, 6, 10, 7, 5, 5, 5, 5, 7, 5, + 5, 5, 5, 5, 7, 7, 5, 5, 5, 5, + 6, 0, 6, 5, 6, 4, 5, 0, 8, 9, + 0, 3, 0, 1, 0, 3, 8, 4, 1, 3, + 3, 6, 7, 7, 8, 4, 0, 1, 0, 1, + 3, 3, 1, 1, 2, 1, 1, 0, 2, 0, + 2, 5, 3, 7, 4, 4, 4, 4, 3, 3, + 3, 7, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 2, 0, 2, 2, 1, 3, 2, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, + 1, 3, 3, 0, 2, 2, 2, 2, 2, 2, + 2, 4, 4, 3, 0, 1, 4, 3, 4, 4, + 3, 3, 3, 2, 1, 3, 3, 3, 5, 7, + 7, 6, 5, 5, 3, 2, 4, 5, 5, 3, + 3, 7, 3, 3, 3, 3, 4, 7, 5, 2, + 4, 4, 4, 4, 4, 5, 5, 4, 4, 4, + 4, 4, 4, 4, 4, 2, 2, 4, 4, 4, + 4, 4, 2, 3, 3, 3, 3, 3, 5, 2, + 3, 3, 2, 3, 4, 4, 4, 3, 4, 4, + 5, 3, 5, 3, 5, 0, 1, 0, 1, 0, + 1, 1, 1, 0, 2, 2, 0, 2, 2, 0, + 2, 0, 1, 1, 1, 1, 2, 1, 3, 1, + 1, 1, 1, 1, 3, 0, 1, 1, 3, 3, + 2, 2, 1, 1, 5, 0, 1, 0, 1, 2, + 3, 0, 3, 3, 3, 1, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 4, 4, 4, 2, 2, 3, 1, 3, + 2, 1, 2, 1, 2, 2, 4, 3, 3, 6, + 4, 7, 6, 1, 3, 2, 2, 2, 2, 1, + 1, 1, 3, 2, 1, 1, 1, 0, 1, 1, + 0, 3, 0, 2, 0, 2, 1, 2, 2, 0, + 1, 1, 0, 1, 1, 5, 5, 4, 0, 2, + 4, 4, 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, - 0, 3, 0, 5, 1, 3, 0, 3, 5, 0, - 1, 1, 0, 1, 0, 3, 3, 2, 2, 2, - 1, 2, 2, 0, 1, 0, 2, 2, 5, 0, - 1, 1, 2, 1, 3, 2, 1, 1, 3, 3, - 3, 0, 1, 4, 3, 3, 4, 2, 0, 2, - 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, - 1, 1, 3, 3, 4, 3, 1, 3, 1, 7, - 6, 7, 7, 8, 8, 0, 1, 5, 2, 1, - 1, 1, 0, 1, 3, 3, 1, 1, 2, 2, - 2, 0, 1, 1, 1, 2, 0, 1, 0, 1, - 1, 3, 2, 1, 2, 3, 3, 3, 4, 4, - 3, 3, 3, 3, 4, 4, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 4, 5, 0, 2, 2, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, - 1, 1, 0, 1, 0, 1, 0, 2, 0, 2, - 0, 2, 2, 0, 1, 5, 1, 3, 7, 1, - 3, 3, 1, 2, 2, 2, 5, 5, 5, 6, - 8, 5, 5, 4, 4, 4, 6, 5, 5, 5, - 2, 2, 2, 2, 3, 3, 3, 4, 3, 3, - 1, 3, 5, 1, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 2, 2, 3, 4, 4, 2, 11, - 3, 6, 8, 6, 6, 6, 13, 8, 6, 6, - 10, 7, 5, 5, 5, 5, 7, 5, 5, 5, - 5, 5, 7, 7, 5, 5, 5, 5, 6, 0, - 6, 5, 6, 4, 5, 0, 8, 9, 0, 3, - 0, 1, 0, 3, 8, 4, 1, 3, 3, 6, - 7, 7, 8, 4, 0, 1, 0, 1, 3, 3, - 1, 1, 2, 1, 1, 0, 2, 0, 2, 5, - 3, 7, 4, 4, 4, 4, 3, 3, 3, 7, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 0, 2, 2, 1, 3, 2, 0, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 3, 1, 3, - 3, 0, 2, 2, 2, 2, 2, 2, 2, 4, - 4, 3, 0, 1, 4, 3, 4, 4, 3, 3, - 3, 2, 1, 3, 3, 3, 5, 7, 7, 6, - 5, 5, 3, 2, 4, 5, 5, 3, 3, 7, - 3, 3, 3, 3, 4, 7, 5, 2, 4, 4, - 4, 4, 4, 5, 5, 4, 4, 4, 4, 4, - 4, 4, 4, 2, 2, 4, 4, 4, 4, 4, - 2, 3, 3, 3, 3, 3, 5, 2, 3, 3, - 2, 3, 4, 4, 4, 3, 4, 4, 5, 3, - 5, 3, 5, 0, 1, 0, 1, 0, 1, 1, - 1, 0, 2, 2, 0, 2, 2, 0, 2, 0, - 1, 1, 1, 1, 2, 1, 3, 1, 1, 1, - 1, 1, 3, 0, 1, 1, 3, 3, 2, 2, - 1, 1, 5, 0, 1, 0, 1, 2, 3, 0, - 3, 3, 3, 1, 0, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, - 4, 4, 4, 2, 2, 3, 1, 3, 2, 1, - 2, 1, 2, 2, 4, 3, 3, 6, 4, 7, - 6, 1, 3, 2, 2, 2, 2, 1, 1, 1, - 3, 2, 1, 1, 1, 0, 1, 1, 0, 3, - 0, 2, 0, 2, 1, 2, 2, 0, 1, 1, - 0, 1, 1, 5, 5, 4, 0, 2, 4, 4, - 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 3, 1, 2, 3, - 5, 0, 1, 2, 1, 1, 0, 1, 2, 1, - 3, 1, 1, 1, 4, 3, 1, 1, 2, 3, - 7, 0, 3, 0, 1, 1, 3, 1, 3, 1, - 1, 3, 3, 1, 3, 4, 4, 4, 3, 2, - 4, 0, 1, 0, 2, 0, 1, 0, 1, 2, - 1, 1, 1, 2, 2, 1, 2, 3, 2, 3, - 2, 2, 2, 1, 1, 3, 3, 0, 1, 1, - 2, 6, 5, 6, 6, 5, 5, 0, 2, 3, - 3, 0, 2, 3, 3, 3, 2, 3, 1, 3, - 6, 1, 1, 3, 4, 3, 4, 4, 4, 1, - 3, 4, 5, 6, 3, 4, 5, 6, 3, 4, - 1, 1, 1, 3, 3, 3, 3, 3, 3, 5, - 5, 3, 3, 3, 3, 3, 3, 1, 1, 1, - 1, 1, 3, 1, 1, 1, 2, 2, 2, 2, - 1, 1, 2, 7, 7, 6, 6, 2, 2, 5, - 6, 3, 3, 1, 3, 1, 3, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, - 2, 4, 2, 4, 0, 1, 2, 5, 0, 3, - 0, 1, 4, 4, 2, 1, 0, 0, 1, 1, - 2, 2, 1, 1, 2, 2, 0, 1, 1, 1, - 1, 5, 1, 3, 0, 3, 1, 1, 1, 2, - 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 3, 4, 6, 4, 4, - 8, 8, 6, 8, 6, 5, 4, 10, 2, 2, - 1, 2, 2, 2, 2, 2, 5, 6, 6, 6, - 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 8, 4, 8, 8, 6, 5, 4, 4, - 4, 5, 7, 4, 4, 7, 4, 4, 6, 6, - 6, 8, 6, 6, 4, 4, 3, 4, 6, 6, - 4, 4, 6, 4, 6, 4, 4, 4, 4, 4, - 4, 6, 4, 6, 4, 4, 4, 6, 4, 6, - 4, 4, 6, 4, 6, 4, 6, 8, 4, 6, - 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, + 2, 3, 5, 0, 1, 2, 1, 1, 0, 1, + 2, 1, 3, 1, 1, 1, 4, 3, 1, 1, + 2, 3, 7, 0, 3, 0, 1, 1, 3, 1, + 3, 1, 1, 3, 3, 1, 3, 4, 4, 4, + 3, 2, 4, 0, 1, 0, 2, 0, 1, 0, + 1, 2, 1, 1, 1, 2, 2, 1, 2, 3, + 2, 3, 2, 2, 2, 1, 1, 3, 3, 0, + 1, 1, 2, 6, 5, 6, 6, 5, 5, 0, + 2, 3, 3, 0, 2, 3, 3, 3, 2, 3, + 1, 3, 6, 1, 1, 3, 4, 3, 4, 4, + 4, 1, 3, 4, 5, 6, 3, 4, 5, 6, + 3, 4, 1, 1, 1, 3, 3, 3, 3, 3, + 3, 5, 5, 3, 3, 3, 3, 3, 3, 1, + 1, 1, 1, 1, 3, 1, 1, 1, 2, 2, + 2, 2, 1, 1, 2, 7, 7, 6, 6, 2, + 2, 5, 6, 3, 3, 1, 3, 1, 3, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 4, 2, 4, 0, 1, 2, 5, + 0, 3, 0, 1, 4, 4, 2, 1, 0, 0, + 1, 1, 2, 2, 1, 1, 2, 2, 0, 1, + 1, 1, 1, 5, 1, 3, 0, 3, 1, 1, + 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 3, 4, 6, + 4, 4, 8, 8, 6, 8, 6, 5, 4, 10, + 2, 2, 1, 2, 2, 2, 2, 2, 5, 6, + 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 8, 4, 8, 8, 6, 5, + 4, 4, 4, 5, 7, 4, 4, 7, 4, 4, + 6, 6, 6, 8, 6, 6, 4, 4, 3, 4, + 6, 6, 4, 4, 6, 4, 6, 4, 4, 4, + 4, 4, 4, 6, 4, 6, 4, 4, 4, 6, + 4, 6, 4, 4, 6, 4, 6, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, 6, 8, - 4, 6, 8, 4, 4, 4, 6, 4, 6, 4, - 8, 6, 4, 4, 6, 4, 6, 8, 4, 6, - 8, 4, 4, 6, 8, 6, 4, 6, 6, 8, - 10, 7, 8, 8, 9, 4, 4, 4, 4, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, - 4, 4, 4, 4, 4, 6, 4, 6, 5, 9, - 6, 9, 8, 6, 8, 8, 8, 6, 1, 1, - 1, 1, 1, 1, 1, 1, 0, 2, 6, 8, - 10, 12, 14, 6, 8, 8, 10, 12, 14, 6, - 8, 10, 12, 6, 8, 4, 4, 3, 4, 6, - 6, 4, 6, 4, 6, 8, 0, 2, 1, 1, + 4, 6, 8, 4, 6, 8, 4, 6, 8, 4, + 6, 8, 4, 6, 8, 4, 4, 4, 6, 4, + 6, 4, 8, 6, 4, 4, 6, 4, 6, 8, + 4, 6, 8, 4, 4, 6, 8, 6, 4, 6, + 6, 8, 10, 7, 8, 8, 9, 4, 4, 4, + 4, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 4, 4, 4, 4, 4, 4, 6, 4, 6, + 5, 9, 6, 9, 8, 6, 8, 8, 8, 6, + 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, + 6, 8, 10, 12, 14, 6, 8, 8, 10, 12, + 14, 6, 8, 10, 12, 6, 8, 4, 4, 3, + 4, 6, 6, 4, 6, 4, 6, 8, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 0, 2, 0, 2, - 3, 4, 4, 4, 4, 4, 0, 3, 4, 7, - 3, 1, 1, 1, 0, 5, 5, 2, 3, 1, - 2, 2, 1, 2, 1, 2, 2, 1, 2, 2, - 1, 1, 0, 1, 0, 1, 0, 2, 1, 2, - 4, 0, 2, 1, 1, 3, 5, 1, 1, 1, - 2, 2, 0, 4, 0, 2, 0, 2, 2, 1, - 3, 0, 1, 0, 1, 3, 1, 3, 2, 0, - 1, 1, 0, 1, 2, 4, 4, 0, 2, 2, - 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, - 0, 1, 3, 3, 3, 0, 3, 1, 1, 0, - 4, 0, 1, 1, 0, 1, 1, 3, 3, 0, - 1, 1, 1, 0, 1, 3, 1, 3, 2, 1, - 1, 0, 1, 2, 3, 4, 2, 3, 4, 4, - 9, 3, 5, 2, 3, 1, 1, 1, 0, 3, - 3, 0, 1, 0, 2, 2, 0, 2, 2, 2, - 0, 2, 1, 2, 3, 3, 0, 2, 1, 2, - 3, 4, 3, 0, 1, 3, 1, 6, 5, 4, - 1, 3, 3, 5, 0, 2, 5, 0, 5, 1, - 3, 1, 3, 1, 3, 1, 2, 3, 4, 1, - 1, 1, 1, 3, 3, 1, 2, 1, 1, 1, - 1, 1, 1, 1, 0, 1, 0, 2, 0, 3, - 0, 1, 0, 1, 1, 5, 0, 1, 0, 1, - 2, 1, 1, 1, 1, 1, 1, 0, 1, 1, - 1, 3, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, + 0, 2, 3, 4, 4, 4, 4, 4, 0, 3, + 4, 7, 3, 1, 1, 1, 0, 5, 5, 2, + 3, 1, 2, 2, 1, 2, 1, 2, 2, 1, + 2, 2, 1, 1, 0, 1, 0, 1, 0, 2, + 1, 2, 4, 0, 2, 1, 1, 3, 5, 1, + 1, 1, 2, 2, 0, 4, 0, 2, 0, 2, + 2, 1, 3, 0, 1, 0, 1, 3, 1, 3, + 2, 0, 1, 1, 0, 1, 2, 4, 4, 0, + 2, 2, 1, 1, 3, 3, 3, 3, 3, 3, + 3, 3, 0, 1, 3, 3, 3, 0, 3, 1, + 1, 0, 4, 0, 1, 1, 0, 1, 1, 3, + 3, 0, 1, 1, 1, 0, 1, 3, 1, 3, + 2, 1, 1, 0, 1, 2, 3, 4, 2, 3, + 4, 4, 9, 3, 5, 2, 3, 1, 1, 1, + 0, 3, 3, 0, 1, 0, 2, 2, 0, 2, + 2, 2, 0, 2, 1, 2, 3, 3, 0, 2, + 1, 2, 3, 4, 3, 0, 1, 3, 1, 6, + 5, 4, 1, 3, 3, 5, 0, 2, 5, 0, + 5, 1, 3, 1, 3, 1, 3, 1, 2, 3, + 4, 1, 1, 1, 1, 3, 3, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 0, 1, 0, 2, + 0, 3, 0, 1, 0, 1, 1, 5, 0, 1, + 0, 1, 2, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 3, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -9813,7 +9945,7 @@ var yyR2 = [...]int{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 0, 0, 1, 1, } var yyChk = [...]int{ @@ -9927,57 +10059,57 @@ var yyChk = [...]int{ -263, -154, -265, -36, -34, -458, 11, -105, -34, -35, -33, -40, -105, -42, 649, -41, -337, -105, 108, -270, -287, 15, 66, 176, 47, 55, -299, -296, -295, 99, - 100, -268, -269, -37, -34, -174, 22, 40, 26, -158, - 184, -174, -337, -158, -315, 268, -105, -105, -304, -351, - 344, -306, 443, 741, 442, -294, -309, 99, -293, -308, - 441, 100, -393, 173, -379, -383, -331, 279, -409, 275, - -219, -402, -401, -331, -458, 27, -289, -331, -70, -71, - -72, -308, 192, 761, -137, 297, 301, 95, 95, -383, - -382, -381, -431, 301, 279, -408, -400, 271, 280, -389, - 272, 273, -384, 265, 150, -431, -384, 270, 280, 275, - 279, 301, 301, 138, 301, 138, 301, 301, 301, 301, - 301, 301, 301, 301, 301, 296, -390, 165, -390, 625, - 625, -396, -431, 275, 265, -431, -431, 271, -327, -384, - 267, 27, 267, 37, 37, -390, -390, -390, -308, 192, - -390, -390, -390, -390, 309, 309, -390, -390, -390, -390, + 100, -268, -269, -37, -34, -174, 22, 40, 26, 184, + -158, -174, -337, 184, -158, -315, 268, -105, -105, -304, + -351, 344, -306, 443, 741, 442, -294, -309, 99, -293, + -308, 441, 100, -393, 173, -379, -383, -331, 279, -409, + 275, -219, -402, -401, -331, -458, 27, -289, -331, -70, + -71, -72, -308, 192, 761, -137, 297, 301, 95, 95, + -383, -382, -381, -431, 301, 279, -408, -400, 271, 280, + -389, 272, 273, -384, 265, 150, -431, -384, 270, 280, + 275, 279, 301, 301, 138, 301, 138, 301, 301, 301, + 301, 301, 301, 301, 301, 301, 296, -390, 165, -390, + 625, 625, -396, -431, 275, 265, -431, -431, 271, -327, + -384, 267, 27, 267, 37, 37, -390, -390, -390, -308, + 192, -390, -390, -390, -390, 309, 309, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, -390, - -390, -390, -390, 264, -430, -163, 439, 329, 467, 263, - -164, 89, -73, 311, -43, -219, -325, 265, 266, -430, - 305, 298, 322, -219, 237, 264, 744, -319, 173, 18, - -319, -316, 428, 426, 413, 418, -319, -319, -319, -319, - 312, 411, -385, 265, 37, 276, 428, 312, 411, 312, - 313, 312, 313, 421, 431, 312, -342, 17, 176, 467, - 416, 420, 305, 264, 306, 266, 430, 313, -342, 97, - -320, 173, 312, 428, 422, 308, -319, -319, -349, -458, - -333, -331, -329, 246, 40, 155, 27, 29, 158, 193, - 141, 22, 159, 39, 248, 376, 275, 192, 271, 262, - 256, 512, 241, 80, 630, 468, 475, 466, 474, 478, - 514, 515, 467, 414, 253, 33, 16, 632, 30, 286, - 26, 43, 186, 243, 162, 163, 633, 289, 28, 257, - 287, 128, 132, 635, 25, 83, 280, 17, 273, 45, - 19, 636, 637, 20, 73, 269, 268, 176, 265, 78, - 725, 14, 236, 31, 172, 74, 638, 150, 144, 639, - 640, 641, 642, 142, 76, 173, 23, 781, 476, 477, - 35, 742, 617, 300, 188, 81, 64, 743, 156, 472, - 643, 644, 129, 645, 133, 84, 748, 152, 21, 724, - 79, 47, 646, 301, 647, 270, 782, 648, 446, 649, - 174, 244, 511, 77, 175, 755, 650, 756, 263, 427, - 11, 517, 34, 285, 284, 272, 72, 71, 259, 260, - 261, 140, 75, 482, 651, 264, 161, 267, 143, 131, - 258, 10, 149, 36, 15, 82, 85, 479, 480, 481, - 62, 139, 621, 160, 18, 652, 447, 154, -427, 744, - -349, -349, 312, 353, 34, 100, -453, -454, -455, 621, - 446, 267, -331, -219, -111, 734, 245, -112, 740, 40, - 252, 145, 37, -161, 428, -149, 193, 762, 745, 746, - 747, 744, 425, 752, 750, 748, 312, 749, 95, 152, - 154, 155, 178, -174, 172, -229, -230, 171, 165, 166, - 167, 168, 169, 170, 177, 176, 156, 158, 173, -280, - 153, 179, 180, 181, 182, 183, 184, 185, 187, 186, - 188, 189, 174, 175, 192, 239, 240, -182, -182, -182, - -182, -249, -255, -254, -458, -251, -427, -330, -337, -458, - -458, -182, -314, -458, -179, -458, -458, -458, -458, -458, - -258, -174, -458, -458, -462, -458, -462, -462, -462, -368, - -458, -368, -368, -458, -458, -458, -458, -458, -458, -458, + -390, -390, -390, -390, 264, -430, -163, 439, 329, 467, + 263, -164, 89, -73, 311, -43, -219, -325, 265, 266, + -430, 305, 298, 322, -219, 237, 264, 744, -319, 173, + 18, -319, -316, 428, 426, 413, 418, -319, -319, -319, + -319, 312, 411, -385, 265, 37, 276, 428, 312, 411, + 312, 313, 312, 313, 421, 431, 312, -342, 17, 176, + 467, 416, 420, 305, 264, 306, 266, 430, 313, -342, + 97, -320, 173, 312, 428, 422, 308, -319, -319, -349, + -458, -333, -331, -329, 246, 40, 155, 27, 29, 158, + 193, 141, 22, 159, 39, 248, 376, 275, 192, 271, + 262, 256, 512, 241, 80, 630, 468, 475, 466, 474, + 478, 514, 515, 467, 414, 253, 33, 16, 632, 30, + 286, 26, 43, 186, 243, 162, 163, 633, 289, 28, + 257, 287, 128, 132, 635, 25, 83, 280, 17, 273, + 45, 19, 636, 637, 20, 73, 269, 268, 176, 265, + 78, 725, 14, 236, 31, 172, 74, 638, 150, 144, + 639, 640, 641, 642, 142, 76, 173, 23, 781, 476, + 477, 35, 742, 617, 300, 188, 81, 64, 743, 156, + 472, 643, 644, 129, 645, 133, 84, 748, 152, 21, + 724, 79, 47, 646, 301, 647, 270, 782, 648, 446, + 649, 174, 244, 511, 77, 175, 755, 650, 756, 263, + 427, 11, 517, 34, 285, 284, 272, 72, 71, 259, + 260, 261, 140, 75, 482, 651, 264, 161, 267, 143, + 131, 258, 10, 149, 36, 15, 82, 85, 479, 480, + 481, 62, 139, 621, 160, 18, 652, 447, 154, -427, + 744, -349, -349, 312, 353, 34, 100, -453, -454, -455, + 621, 446, 267, -331, -219, -111, 734, 245, -112, 740, + 40, 252, 145, 37, -161, 428, -149, 193, 762, 745, + 746, 747, 744, 425, 752, 750, 748, 312, 749, 95, + 152, 154, 155, 178, -174, 172, -229, -230, 171, 165, + 166, 167, 168, 169, 170, 177, 176, 156, 158, 173, + -280, 153, 179, 180, 181, 182, 183, 184, 185, 187, + 186, 188, 189, 174, 175, 192, 239, 240, -182, -182, + -182, -182, -249, -255, -254, -458, -251, -427, -330, -337, + -458, -458, -182, -314, -458, -179, -458, -458, -458, -458, + -458, -258, -174, -458, -458, -462, -458, -462, -462, -462, + -368, -458, -368, -368, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, @@ -9989,725 +10121,725 @@ var yyChk = [...]int{ -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, - -458, -458, -458, -458, -458, -458, -458, -458, 237, -458, - -458, -458, -458, -458, -368, -368, -368, -368, -368, -368, - -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, - -458, -458, -458, -458, 97, 111, 107, 110, 102, 113, - 97, 97, 97, 97, -34, -35, -239, 62, -458, -348, - -440, -441, -222, -219, -458, 329, -331, -331, 298, 104, - -268, -37, -34, -263, -269, -265, -34, -105, -147, -160, - 68, 69, -159, -162, 26, 43, 73, 75, 98, 71, - 72, 70, 40, -459, 96, -459, -287, -459, -171, -325, - -155, -164, 265, 273, 272, 149, -430, -172, 152, 316, - 95, -42, -290, 114, -242, -247, -245, 755, 678, 708, - 678, 708, 66, 48, 97, 97, 95, 95, 24, -264, - -266, -174, 17, -335, 178, -334, 27, -331, 97, 237, - 17, -220, 31, -219, -315, -315, 95, 99, 344, -305, - -307, 444, 446, 165, -336, -331, 97, 33, 96, 95, - -219, -357, -360, -362, -361, -363, -358, -359, 373, 374, - 193, 377, 379, 380, 381, 382, 383, 384, 385, 386, - 387, 390, 402, 34, 288, 369, 370, 371, 372, 391, - 392, 393, 394, 396, 397, 398, 399, 354, 375, 619, - 355, 356, 357, 358, 359, 360, 362, 363, 366, 364, - 365, 367, 368, -332, -331, 94, 96, 95, -367, 94, - -174, -32, 96, 95, -390, -390, -390, 296, 22, -52, - -49, -416, 21, -48, -49, 246, 134, 135, 243, 94, - -379, 94, -388, -332, -331, 94, 150, 270, 149, -387, - -384, -387, -388, -331, -251, -331, 150, 150, -331, -331, - -301, -331, -301, -301, 40, -301, 40, -301, 40, 104, - -331, -301, 40, -301, 40, -301, 40, -301, 40, -301, - 40, 33, 86, 87, 88, 33, 90, 91, 92, -251, - -331, -331, -251, -379, -251, -219, -331, -308, 104, 104, - 104, -390, -390, 104, 97, 97, 97, -390, -390, 104, - 97, -339, -337, 97, 97, -432, 281, 326, 328, 104, - 104, 104, 104, 33, 97, -433, 33, 769, 768, 770, - 771, 772, 97, 104, 33, 104, 33, 104, -331, 94, - -219, -171, 241, 243, 246, 84, 97, 334, 332, 333, - 330, 335, 336, 337, 165, 49, 95, 267, 264, -331, - -321, 269, -321, -321, -331, -338, -337, -329, -219, 267, - 410, 97, -174, -386, 17, 176, -342, -342, -319, -219, - -386, -342, -319, -219, -319, -319, -319, -319, -342, -342, - -342, -319, -337, -337, -219, -219, -219, -219, -219, -219, - -219, -349, -320, -319, 744, 97, -313, 17, 84, -349, - -349, -328, 25, 25, 95, 350, 447, 448, -347, 347, - -107, -331, 97, -13, -32, -21, -20, -22, 165, -13, - 95, 621, -212, -219, 744, 744, 744, 744, 744, 744, - -174, -174, -174, -174, 645, -237, -451, 156, 131, 132, - 129, 130, -191, 41, 42, 40, -174, -238, -244, -249, - 114, 176, 158, 173, -280, -179, -182, -179, -179, -179, - -179, -179, -179, 236, -179, 236, -179, -179, -179, -179, - -179, -179, -350, -331, 97, 193, -187, -186, 113, -449, - -187, 618, 95, -254, 237, -174, -174, -427, -145, 484, - 485, 486, 487, 489, 490, 491, 494, 495, 499, 500, - 483, 501, 488, 493, 496, 497, 498, 492, 372, -174, - -240, -239, -240, -174, -174, -256, -257, 160, -251, -174, - -459, -459, 104, 184, -153, 26, 43, -153, -153, -153, - -153, -174, -174, -174, -174, -174, -174, -174, -174, -174, - -174, -153, -174, -146, 483, 501, 488, 493, 496, 497, - 498, 492, 372, 502, 503, 504, 505, 506, 507, 508, - 509, 510, -146, -145, -174, -174, -174, -174, -174, -174, - -174, -174, -113, -174, 141, 142, 143, -239, -174, -179, - -174, -174, -174, -459, -174, -174, -174, -240, -174, -174, - -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, + -458, -458, -458, -458, -458, -458, -458, -458, -458, 237, + -458, -458, -458, -458, -458, -368, -368, -368, -368, -368, + -368, -458, -458, -458, -458, -458, -458, -458, -458, -458, + -458, -458, -458, -458, -458, 97, 111, 107, 110, 102, + 113, 97, 97, 97, 97, -34, -35, -239, 62, -458, + -348, -440, -441, -222, -219, -458, 329, -331, -331, 298, + 104, -268, -37, -34, -263, -269, -265, -34, -105, -147, + -160, 68, 69, -159, -162, 26, 43, 73, 75, 98, + 71, 72, 70, 40, -459, 96, -459, -287, -459, -171, + -325, -155, -164, 265, 273, 272, 149, -430, -172, 152, + 316, 95, -42, -290, 114, -242, -247, -245, 755, 678, + 708, 678, 708, 66, 48, 97, 97, 95, 95, 24, + -264, -266, -174, 17, 17, -335, 178, -334, 27, -331, + 97, 237, 17, 17, -220, 31, -219, -315, -315, 95, + 99, 344, -305, -307, 444, 446, 165, -336, -331, 97, + 33, 96, 95, -219, -357, -360, -362, -361, -363, -358, + -359, 373, 374, 193, 377, 379, 380, 381, 382, 383, + 384, 385, 386, 387, 390, 402, 34, 288, 369, 370, + 371, 372, 391, 392, 393, 394, 396, 397, 398, 399, + 354, 375, 619, 355, 356, 357, 358, 359, 360, 362, + 363, 366, 364, 365, 367, 368, -332, -331, 94, 96, + 95, -367, 94, -174, -32, 96, 95, -390, -390, -390, + 296, 22, -52, -49, -416, 21, -48, -49, 246, 134, + 135, 243, 94, -379, 94, -388, -332, -331, 94, 150, + 270, 149, -387, -384, -387, -388, -331, -251, -331, 150, + 150, -331, -331, -301, -331, -301, -301, 40, -301, 40, + -301, 40, 104, -331, -301, 40, -301, 40, -301, 40, + -301, 40, -301, 40, 33, 86, 87, 88, 33, 90, + 91, 92, -251, -331, -331, -251, -379, -251, -219, -331, + -308, 104, 104, 104, -390, -390, 104, 97, 97, 97, + -390, -390, 104, 97, -339, -337, 97, 97, -432, 281, + 326, 328, 104, 104, 104, 104, 33, 97, -433, 33, + 769, 768, 770, 771, 772, 97, 104, 33, 104, 33, + 104, -331, 94, -219, -171, 241, 243, 246, 84, 97, + 334, 332, 333, 330, 335, 336, 337, 165, 49, 95, + 267, 264, -331, -321, 269, -321, -321, -331, -338, -337, + -329, -219, 267, 410, 97, -174, -386, 17, 176, -342, + -342, -319, -219, -386, -342, -319, -219, -319, -319, -319, + -319, -342, -342, -342, -319, -337, -337, -219, -219, -219, + -219, -219, -219, -219, -349, -320, -319, 744, 97, -313, + 17, 84, -349, -349, -328, 25, 25, 95, 350, 447, + 448, -347, 347, -107, -331, 97, -13, -32, -21, -20, + -22, 165, -13, 95, 621, -212, -219, 744, 744, 744, + 744, 744, 744, -174, -174, -174, -174, 645, -237, -451, + 156, 131, 132, 129, 130, -191, 41, 42, 40, -174, + -238, -244, -249, 114, 176, 158, 173, -280, -179, -182, + -179, -179, -179, -179, -179, -179, 236, -179, 236, -179, + -179, -179, -179, -179, -179, -350, -331, 97, 193, -187, + -186, 113, -449, -187, 618, 95, -254, 237, -174, -174, + -427, -145, 484, 485, 486, 487, 489, 490, 491, 494, + 495, 499, 500, 483, 501, 488, 493, 496, 497, 498, + 492, 372, -174, -240, -239, -240, -174, -174, -256, -257, + 160, -251, -174, -459, -459, 104, 184, -153, 26, 43, + -153, -153, -153, -153, -174, -174, -174, -174, -174, -174, + -174, -174, -174, -174, -153, -174, -146, 483, 501, 488, + 493, 496, 497, 498, 492, 372, 502, 503, 504, 505, + 506, 507, 508, 509, 510, -146, -145, -174, -174, -174, + -174, -174, -174, -174, -174, -113, -174, 141, 142, 143, + -239, -174, -179, -174, -174, -174, -459, -174, -174, -174, + -240, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, - -174, -174, -174, -174, -426, -425, -424, -174, -174, -174, + -174, -174, -174, -174, -174, -174, -174, -426, -425, -424, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, - -239, -239, -239, -239, -239, -174, -459, -174, -193, -177, - 104, -295, 113, -174, -174, -174, -174, -174, -174, -240, - -333, -338, -329, -330, -239, -240, -240, -239, -239, -174, - -174, -174, -174, -174, -174, -174, -174, -459, -174, -174, - -174, -174, -174, -287, -459, -239, 95, -442, 446, 447, - 742, -340, 301, -339, 27, -240, 97, 17, -298, 85, - -331, -268, -268, 68, 69, 64, -157, -158, -162, -459, - 305, -166, 318, 264, -163, -171, -331, 265, 265, 265, - -322, 269, 511, 165, -41, 27, 95, -458, 671, 671, - 67, 97, -369, -308, 400, 401, 193, -296, -174, -174, - 95, -267, 29, 30, -219, -334, 184, -338, -219, -300, - 301, -219, -197, -199, -200, -201, -222, -250, -458, -202, - -34, 641, 638, 17, -212, -213, -221, -337, -306, -351, - -305, 95, 445, 447, 448, 84, 133, -174, -370, 192, - -398, -397, -396, -379, -381, -382, -383, 96, -370, -375, - 407, 406, -367, -367, -367, -367, -367, -367, -369, -369, - -369, -367, 94, -367, 94, -367, -367, -367, -367, -372, - 94, -372, -372, -373, -372, 94, -373, -374, 94, -374, - -409, -174, -406, -405, -403, -404, 274, 109, 718, 670, - 621, 662, 704, 85, -401, -267, 104, -459, -108, 621, - -331, 99, 97, 99, 97, 99, 97, -138, -77, -1, - 781, 782, 783, 95, 22, -380, -379, -76, 326, -412, - -413, 301, -408, -402, -388, 150, -387, -388, -388, -331, - 95, 31, 138, 138, 138, 138, 621, 243, 34, -323, - 661, 156, 718, 670, -379, -76, 267, 267, -350, -350, - -350, 97, 97, -318, 777, -212, -166, 307, 307, 264, - 320, 264, 320, -219, 331, 334, 332, 333, 330, 335, - 336, 337, 338, 40, 40, 40, 40, 40, 40, 40, - 319, 321, 323, 309, -219, -219, -321, 84, -214, -219, - 28, -337, -219, 97, 97, -219, -319, -319, -219, -319, - -319, -219, 97, -337, -455, 351, -331, 387, 735, 737, - -149, 446, 95, 621, 25, -150, 25, -458, -451, 131, - 132, -249, -249, -249, -238, -179, -182, -179, 155, 289, - -179, -179, -458, -251, -459, -333, 27, 95, 85, -459, - 182, 95, -459, -459, 95, 17, 95, -259, -257, 162, - -174, -459, 95, -459, -459, -239, -174, -174, -174, -174, - -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, - -239, -459, 95, 95, 17, -354, 27, -459, -459, -459, - -459, 95, -459, -459, -258, -459, 17, -459, 85, 95, - 176, 95, -459, -459, -459, 95, 95, -459, -459, 95, - -459, 95, -459, -459, -459, -459, -459, -459, 95, -459, - 95, -459, -459, -459, 95, -459, 95, -459, -459, 95, + -174, -174, -174, -239, -239, -239, -239, -239, -174, -459, + -174, -193, -177, 104, -295, 113, -174, -174, -174, -174, + -174, -174, -240, -333, -338, -329, -330, -239, -240, -240, + -239, -239, -174, -174, -174, -174, -174, -174, -174, -174, + -459, -174, -174, -174, -174, -174, -287, -459, -239, 95, + -442, 446, 447, 742, -340, 301, -339, 27, -240, 97, + 17, -298, 85, -331, -268, -268, 68, 69, 64, -157, + 184, -158, -162, -459, 305, -166, 318, 264, -163, -171, + -331, 265, 265, 265, -322, 269, 511, 165, -41, 27, + 95, -458, 671, 671, 67, 97, -369, -308, 400, 401, + 193, -296, -174, -174, 95, -267, 29, 30, -219, -219, + -334, 184, -338, -219, -219, -300, 301, -219, -197, -199, + -200, -201, -222, -250, -458, -202, -34, 641, 638, 17, + -212, -213, -221, -337, -306, -351, -305, 95, 445, 447, + 448, 84, 133, -174, -370, 192, -398, -397, -396, -379, + -381, -382, -383, 96, -370, -375, 407, 406, -367, -367, + -367, -367, -367, -367, -369, -369, -369, -367, 94, -367, + 94, -367, -367, -367, -367, -372, 94, -372, -372, -373, + -372, 94, -373, -374, 94, -374, -409, -174, -406, -405, + -403, -404, 274, 109, 718, 670, 621, 662, 704, 85, + -401, -267, 104, -459, -108, 621, -331, 99, 97, 99, + 97, 99, 97, -138, -77, -1, 781, 782, 783, 95, + 22, -380, -379, -76, 326, -412, -413, 301, -408, -402, + -388, 150, -387, -388, -388, -331, 95, 31, 138, 138, + 138, 138, 621, 243, 34, -323, 661, 156, 718, 670, + -379, -76, 267, 267, -350, -350, -350, 97, 97, -318, + 777, -212, -166, 307, 307, 264, 320, 264, 320, -219, + 331, 334, 332, 333, 330, 335, 336, 337, 338, 40, + 40, 40, 40, 40, 40, 40, 319, 321, 323, 309, + -219, -219, -321, 84, -214, -219, 28, -337, -219, 97, + 97, -219, -319, -319, -219, -319, -319, -219, 97, -337, + -455, 351, -331, 387, 735, 737, -149, 446, 95, 621, + 25, -150, 25, -458, -451, 131, 132, -249, -249, -249, + -238, -179, -182, -179, 155, 289, -179, -179, -458, -251, + -459, -333, 27, 95, 85, -459, 182, 95, -459, -459, + 95, 17, 95, -259, -257, 162, -174, -459, 95, -459, + -459, -239, -174, -174, -174, -174, -459, -459, -459, -459, + -459, -459, -459, -459, -459, -459, -239, -459, 95, 95, + 17, -354, 27, -459, -459, -459, -459, 95, -459, -459, + -258, -459, 17, -459, 85, 95, 176, 95, -459, -459, + -459, 95, 95, -459, -459, 95, -459, 95, -459, -459, + -459, -459, -459, -459, 95, -459, 95, -459, -459, -459, + 95, -459, 95, -459, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, - -459, 95, -459, 95, -459, -459, -459, 95, -459, 95, - -459, 95, -459, -459, 95, -459, 95, -459, 95, -459, - 95, 95, -459, 95, 95, 95, -459, 95, 95, 95, - 95, -459, -459, -459, -459, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, -459, -459, -459, -459, -459, - -459, 95, -120, 646, -459, -459, 95, -459, 95, 95, - 95, 95, 95, -459, -458, 237, -459, -459, -459, -459, - -459, 95, 95, 95, 95, 95, 95, -459, -459, -459, - 95, 95, -459, 95, -459, 95, -459, -441, 741, 447, - -226, -225, -223, 82, 268, 83, -458, -339, -459, -187, - -295, -297, -295, -232, -331, 104, 113, -270, -196, 95, - -198, 17, -322, 266, 325, -322, -171, -166, -407, -404, - -331, -331, -331, -337, 156, -173, 478, -168, 97, 99, - -249, -247, -459, -369, -275, -281, -316, -331, 97, 193, - -371, 193, -371, 400, 401, -266, 237, -227, 18, -231, - 34, 62, -32, -458, -458, 34, 95, -215, -217, -216, - -218, 74, 78, 80, 75, 76, 77, 81, -345, 27, - -34, -197, -34, -458, -219, -212, -460, 17, 85, -460, - 95, 237, -307, -310, 449, 446, 452, -427, 97, -137, - 95, -396, -383, -271, -167, 45, -376, 408, -369, 629, - -369, -369, -378, 97, -378, 104, 104, 104, 96, -55, - -50, -51, 35, 89, -403, -390, 97, 44, -390, -390, - -331, 96, -267, -109, 315, 741, -2, 780, 786, 150, - 94, 413, 21, -289, 95, 96, -252, 327, 96, -139, - -331, 96, 94, -388, -388, -331, -458, 264, 33, 33, - 718, 670, 661, -76, -252, -251, -331, -370, 779, 778, - 96, 266, -219, -219, -219, -219, -219, -219, 246, 243, - 436, -450, 339, 97, -450, 310, 267, -212, -219, 95, - -110, 283, 278, -342, -342, 35, -219, 446, 753, 751, - -174, 155, 289, -191, -182, -145, -145, -179, -352, 193, - 373, 288, 371, 367, 387, 378, 406, 369, 407, 364, - 363, 362, -352, -350, -179, -239, -174, -174, -174, 164, - -174, 161, -174, -121, -120, -459, -459, -459, -459, -459, - -121, -121, -121, -121, -121, -121, -121, -121, -121, -121, - -263, -174, -174, -174, -459, 193, 373, -121, -174, 17, - -174, -350, -174, -174, -174, -174, -174, -174, -174, -174, + -459, -459, -459, 95, -459, 95, -459, 95, -459, -459, + 95, -459, 95, -459, 95, -459, 95, 95, -459, 95, + 95, 95, -459, 95, 95, 95, 95, -459, -459, -459, + -459, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, -459, -459, -459, -459, -459, -459, 95, -120, 646, + -459, -459, 95, -459, 95, 95, 95, 95, 95, -459, + -458, 237, -459, -459, -459, -459, -459, 95, 95, 95, + 95, 95, 95, -459, -459, -459, 95, 95, -459, 95, + -459, 95, -459, -441, 741, 447, -226, -225, -223, 82, + 268, 83, -458, -339, -459, -187, -295, -297, -295, -232, + -331, 104, 113, -270, -196, 95, -198, 17, -322, 266, + 325, -322, -171, -166, -407, -404, -331, -331, -331, -337, + 156, -173, 478, -168, 97, 99, -249, -247, -459, -369, + -275, -281, -316, -331, 97, 193, -371, 193, -371, 400, + 401, -266, 237, -227, 18, -227, -231, 34, 62, -32, + -458, -458, 34, 95, -215, -217, -216, -218, 74, 78, + 80, 75, 76, 77, 81, -345, 27, -34, -197, -34, + -458, -219, -212, -460, 17, 85, -460, 95, 237, -307, + -310, 449, 446, 452, -427, 97, -137, 95, -396, -383, + -271, -167, 45, -376, 408, -369, 629, -369, -369, -378, + 97, -378, 104, 104, 104, 96, -55, -50, -51, 35, + 89, -403, -390, 97, 44, -390, -390, -331, 96, -267, + -109, 315, 741, -2, 780, 786, 150, 94, 413, 21, + -289, 95, 96, -252, 327, 96, -139, -331, 96, 94, + -388, -388, -331, -458, 264, 33, 33, 718, 670, 661, + -76, -252, -251, -331, -370, 779, 778, 96, 266, -219, + -219, -219, -219, -219, -219, 246, 243, 436, -450, 339, + 97, -450, 310, 267, -212, -219, 95, -110, 283, 278, + -342, -342, 35, -219, 446, 753, 751, -174, 155, 289, + -191, -182, -145, -145, -179, -352, 193, 373, 288, 371, + 367, 387, 378, 406, 369, 407, 364, 363, 362, -352, + -350, -179, -239, -174, -174, -174, 164, -174, 161, -174, + -121, -120, -459, -459, -459, -459, -459, -121, -121, -121, + -121, -121, -121, -121, -121, -121, -121, -263, -174, -174, + -174, -459, 193, 373, -121, -174, 17, -174, -350, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, - -174, -174, -174, -174, -174, -174, -174, -424, -174, -239, - -174, -239, -174, -174, -174, -174, -174, -425, -425, -425, - -425, -425, -239, -239, -239, -239, -174, -458, -331, -124, - -123, -122, 697, 268, -120, -193, -124, -193, 236, -174, - 236, 236, 236, -174, -240, -333, -174, -174, -174, -174, - -174, -174, -174, -174, -174, -174, -223, -384, 307, -384, - 307, -384, -301, 95, -312, 25, 17, 62, 62, -196, - -227, -158, -197, -219, -219, -165, 316, 324, -219, -166, - 266, 84, -407, -407, -407, 28, 94, -169, 100, -278, - 734, -284, 51, -282, -283, 52, -279, 53, 61, -371, - -371, 184, -268, -174, -302, 84, -303, -311, -251, -243, - -246, -244, -458, -288, -459, -331, -301, -303, -199, -200, - -200, -199, -200, 74, 74, 74, 79, 74, 79, 74, - -216, -337, -459, -174, -340, 85, -197, -197, -221, -337, - 184, 446, 450, 451, -396, -448, 129, 156, 33, 84, - 404, 109, -446, 192, 658, 713, 718, 670, 662, 704, - -447, 270, 149, 150, 282, 27, 46, 96, 95, 96, - 95, 96, 96, 95, -324, -323, -51, -50, -390, -390, - 104, -427, 97, 97, 275, -140, 784, 104, 94, -3, - 89, -174, 94, 22, -379, -251, -414, -364, -415, -365, - -366, -5, -6, -391, -143, 62, 109, -80, 49, 265, - 764, 765, 138, -458, 777, -406, -289, -410, -412, -219, - -178, -458, -190, -176, -175, -177, -183, 182, 183, 288, - 369, 370, -252, -219, -429, 85, 307, 404, 307, 404, - 97, -452, 340, 97, -452, -219, -110, -55, -219, -319, - -319, 35, -427, -459, -191, -182, -152, 176, 621, -355, - 628, -367, -367, -367, -374, -367, 359, -367, 359, -367, - -459, -459, -459, 95, -459, 25, -459, 95, -174, 95, - -121, -121, -121, -121, -121, -148, 517, 95, 95, -459, - 94, 94, -459, -174, -459, -459, -459, 95, -459, -459, - -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, + -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, + -174, -174, -174, -174, -424, -174, -239, -174, -239, -174, + -174, -174, -174, -174, -425, -425, -425, -425, -425, -239, + -239, -239, -239, -174, -458, -331, -124, -123, -122, 697, + 268, -120, -193, -124, -193, 236, -174, 236, 236, 236, + -174, -240, -333, -174, -174, -174, -174, -174, -174, -174, + -174, -174, -174, -223, -384, 307, -384, 307, -384, -301, + 95, -312, 25, 17, 62, 62, -196, -227, -158, -197, + -219, -219, -165, 316, 324, -219, -166, 266, 84, -407, + -407, -407, 28, 94, -169, 100, -278, 734, -284, 51, + -282, -283, 52, -279, 53, 61, -371, -371, 184, -268, + -174, -268, -302, 84, -303, -311, -251, -243, -246, -244, + -458, -288, -459, -331, -301, -303, -199, -200, -200, -199, + -200, 74, 74, 74, 79, 74, 79, 74, -216, -337, + -459, -174, -340, 85, -197, -197, -221, -337, 184, 446, + 450, 451, -396, -448, 129, 156, 33, 84, 404, 109, + -446, 192, 658, 713, 718, 670, 662, 704, -447, 270, + 149, 150, 282, 27, 46, 96, 95, 96, 95, 96, + 96, 95, -324, -323, -51, -50, -390, -390, 104, -427, + 97, 97, 275, -140, 784, 104, 94, -3, 89, -174, + 94, 22, -379, -251, -414, -364, -415, -365, -366, -5, + -6, -391, -143, 62, 109, -80, 49, 265, 764, 765, + 138, -458, 777, -406, -289, -410, -412, -219, -178, -458, + -190, -176, -175, -177, -183, 182, 183, 288, 369, 370, + -252, -219, -429, 85, 307, 404, 307, 404, 97, -452, + 340, 97, -452, -219, -110, -55, -219, -319, -319, 35, + -427, -459, -191, -182, -152, 176, 621, -355, 628, -367, + -367, -367, -374, -367, 359, -367, 359, -367, -459, -459, + -459, 95, -459, 25, -459, 95, -174, 95, -121, -121, + -121, -121, -121, -148, 517, 95, 95, -459, 94, 94, + -459, -174, -459, -459, -459, 95, -459, -459, -459, -459, + -459, -459, -459, -459, -459, -459, -459, -459, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, -459, 95, - -459, 95, -459, -459, 95, -459, -459, -459, 95, -459, - 95, -459, 95, -459, -459, -459, 95, -353, 719, -459, - -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, - -119, -332, -120, 679, 679, -459, -120, -260, 95, -179, - -459, -179, -179, -179, -459, -459, -459, 95, -459, 95, - 95, -459, 95, -459, 95, -459, -459, -459, -459, 95, - -224, 25, -458, -224, -458, -224, -459, -295, -219, -227, - -261, 19, -458, 266, -219, -219, 84, 84, 84, 96, - -275, 56, 379, -286, -285, 60, 52, -283, 22, 54, - 22, 32, -302, 95, 165, -344, 95, 27, -459, -459, - 95, 62, 237, -459, -227, -210, -209, 84, 85, -211, - 84, -209, 74, 74, -290, 95, -300, -197, -227, -227, - 237, 129, -458, -178, 15, 97, 97, -427, -445, 768, - 769, 33, 770, 104, -390, -390, 150, 150, -219, 94, - -369, 97, -369, 104, 104, 33, 90, 91, 92, 33, - 86, 87, 88, 317, -411, 94, 22, -174, 94, 165, - 96, -289, -289, 303, 176, -390, 762, 309, 309, -390, - -390, -390, -142, -141, 784, 96, -459, 95, -377, 621, - 624, -174, -184, -184, -290, -423, 621, -428, -331, -331, - -331, -331, 104, 106, -459, 619, 81, 622, -459, -369, - -174, -174, -174, -174, -268, 97, -174, -174, 104, 104, - -121, -459, -174, -174, -174, -174, -174, -174, -174, -174, + -459, -459, 95, -459, -459, -459, 95, -459, 95, -459, + 95, -459, -459, -459, 95, -353, 719, -459, -459, -459, + -459, -459, -459, -459, -459, -459, -459, -459, -119, -332, + -120, 679, 679, -459, -120, -260, 95, -179, -459, -179, + -179, -179, -459, -459, -459, 95, -459, 95, 95, -459, + 95, -459, 95, -459, -459, -459, -459, 95, -224, 25, + -458, -224, -458, -224, -459, -295, -219, -227, -261, 19, + -458, 266, -219, -219, 84, 84, 84, 96, -275, 56, + 379, -286, -285, 60, 52, -283, 22, 54, 22, 32, + -302, 95, 165, -344, 95, 27, -459, -459, 95, 62, + 237, -459, -227, -210, -209, 84, 85, -211, 84, -209, + 74, 74, -290, 95, -300, -197, -227, -227, 237, 129, + -458, -178, 15, 97, 97, -427, -445, 768, 769, 33, + 770, 104, -390, -390, 150, 150, -219, 94, -369, 97, + -369, 104, 104, 33, 90, 91, 92, 33, 86, 87, + 88, 317, -411, 94, 22, -174, 94, 165, 96, -289, + -289, 303, 176, -390, 762, 309, 309, -390, -390, -390, + -142, -141, 784, 96, -459, 95, -377, 621, 624, -174, + -184, -184, -290, -423, 621, -428, -331, -331, -331, -331, + 104, 106, -459, 619, 81, 622, -459, -369, -174, -174, + -174, -174, -268, 97, -174, -174, 104, 104, -121, -459, + -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, - -174, -174, -239, -174, -459, -207, -206, -208, 745, 129, - 33, -352, -459, -241, 301, -127, -126, -125, 17, -459, - -174, -145, -145, -145, -145, -174, -174, -174, -174, -174, - -174, -458, 74, 21, 19, -292, -331, 270, -458, -292, - -458, -340, -261, -262, 20, 22, -420, -419, -417, -418, - 176, 725, 724, -219, -219, -219, -219, -276, 58, -274, - 57, -274, -285, 22, 22, 97, 22, 97, 150, -311, - -174, -246, -339, 62, -32, -331, -243, -331, -263, -174, - 94, -174, -187, -227, -227, -174, -234, 541, 543, 544, - 545, 542, 547, 548, 549, 550, 551, 552, 553, 554, - 555, 556, 546, 557, 518, 519, 520, 116, 118, 117, - 126, 127, 521, 522, 523, 373, 569, 570, 564, 567, - 568, 566, 565, 388, 389, 524, 587, 588, 592, 591, - 589, 590, 593, 596, 597, 598, 599, 600, 601, 603, - 602, 594, 595, 572, 571, 573, 574, 575, 576, 577, - 578, 580, 579, 581, 582, 583, 584, 585, 586, 604, - 605, 606, 607, 608, 610, 609, 614, 613, 611, 612, - 616, 615, 525, 526, 119, 120, 121, 122, 123, 124, - 125, 527, 530, 528, 531, 532, 533, 538, 539, 534, - 535, 536, 537, 540, 399, 397, 398, 394, 393, 392, - 465, 470, 471, 473, 558, 559, 560, 561, 562, 563, - 726, 727, 728, 729, 730, 731, 732, 733, 97, 97, - 94, -174, 96, 96, -410, -77, 96, -291, -289, 104, - 96, 304, -244, -458, 97, -390, -390, -390, 104, 104, - -339, -459, 95, -331, -447, -412, 625, 625, -459, 27, - -422, -421, -333, 94, 85, 67, 620, 623, -459, -459, - -459, 95, -459, -459, -459, 96, 96, -459, -459, -459, + -239, -174, -459, -207, -206, -208, 745, 129, 33, -352, + -459, -241, 301, -127, -126, -125, 17, -459, -174, -145, + -145, -145, -145, -174, -174, -174, -174, -174, -174, -458, + 74, 21, 19, -292, -331, 270, -458, -292, -458, -340, + -261, -262, 20, 22, -420, -419, -417, -418, 176, 725, + 724, -219, -219, -219, -219, -276, 58, -274, 57, -274, + -285, 22, 22, 97, 22, 97, 150, -311, -174, -246, + -339, 62, -32, -331, -243, -331, -263, -174, 94, -174, + -187, -227, -227, -174, -234, 541, 543, 544, 545, 542, + 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, + 546, 557, 518, 519, 520, 116, 118, 117, 126, 127, + 521, 522, 523, 373, 569, 570, 564, 567, 568, 566, + 565, 388, 389, 524, 587, 588, 592, 591, 589, 590, + 593, 596, 597, 598, 599, 600, 601, 603, 602, 594, + 595, 572, 571, 573, 574, 575, 576, 577, 578, 580, + 579, 581, 582, 583, 584, 585, 586, 604, 605, 606, + 607, 608, 610, 609, 614, 613, 611, 612, 616, 615, + 525, 526, 119, 120, 121, 122, 123, 124, 125, 527, + 530, 528, 531, 532, 533, 538, 539, 534, 535, 536, + 537, 540, 399, 397, 398, 394, 393, 392, 465, 470, + 471, 473, 558, 559, 560, 561, 562, 563, 726, 727, + 728, 729, 730, 731, 732, 733, 97, 97, 94, -174, + 96, 96, -410, -77, 96, -291, -289, 104, 96, 304, + -244, -458, 97, -390, -390, -390, 104, 104, -339, -459, + 95, -331, -447, -412, 625, 625, -459, 27, -422, -421, + -333, 94, 85, 67, 620, 623, -459, -459, -459, 95, + -459, -459, -459, 96, 96, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, -459, - -459, -459, -459, -459, -459, -459, -459, -459, -459, 95, - -459, -206, -208, -459, 84, -187, -263, 22, -124, 326, - 328, -124, -459, -459, -459, -459, -459, 95, -459, -459, - 95, -459, 95, -459, -459, -292, -459, 22, 22, 95, - -459, -292, -459, -292, -226, -262, -134, -133, -132, 652, - -174, -239, -459, 95, -331, -277, 59, 84, 133, 97, - 97, 97, 15, -458, -243, 237, -344, -268, -289, -204, - 413, -263, -459, -289, 96, 96, 786, 150, 96, -244, - -151, -458, 300, -339, 97, 97, -141, -144, -32, 95, - 165, -289, -219, 67, -174, -239, -459, 84, 633, 745, - -118, -117, -114, 756, 782, -239, -120, -120, -174, -174, - -174, -459, -331, 270, -459, -459, -134, 95, -131, -130, - -331, -356, 621, -81, -82, -83, -8, 342, 269, 253, - 284, -417, -357, 84, 133, -303, -289, -344, -331, 96, - -459, -458, -268, 96, -272, 94, -3, 300, -364, -415, - -365, -366, -5, -6, -391, -108, -421, -395, -337, -333, - 97, 104, 96, 621, -459, -459, -116, 158, 754, 716, - -183, 236, -459, 95, -459, 95, -459, 95, -132, 95, - 27, 626, 787, -84, -85, -83, -82, -174, -289, -59, - -331, 256, 257, 258, -65, -63, -64, 260, -331, -459, - -340, -205, -203, -331, 676, -438, -437, 617, -448, -444, - 129, 156, 109, -446, 713, 718, 670, 139, 140, -174, - 94, -459, 237, -429, 622, -116, 755, 690, 664, 690, - 664, -179, -174, -174, -174, -130, -458, 164, -83, 161, - -357, 255, 262, -66, -67, 34, -170, 65, -459, 95, - 25, -357, -79, 687, -435, -436, 84, -439, 419, 686, - 707, 129, 97, 104, 96, -289, -338, -423, 623, 155, - -145, -459, 95, -459, 95, -459, -119, -85, -273, 33, - 25, 25, -68, -69, 453, 454, 455, 456, 457, 458, - 459, 460, 461, 462, 463, 464, -68, 97, -203, 683, - -370, -187, -436, 84, -435, 84, 16, 15, -4, 785, - 96, -116, 690, 664, -174, -174, -459, -89, -88, -87, - 163, -458, -178, -60, -61, -62, -64, 261, 156, 259, - 104, -63, -62, 165, -78, 28, -204, -434, 283, 278, - 281, 34, -434, 104, -4, -459, -459, -86, 162, -87, - -174, -174, -82, 95, 254, -183, 687, 277, 33, 129, - 164, -85, 161, -459, -61, -187, 269, -85, -207, -206, - -206, + -459, -459, -459, -459, -459, -459, -459, 95, -459, -206, + -208, -459, 84, -187, -263, 22, -124, 326, 328, -124, + -459, -459, -459, -459, -459, 95, -459, -459, 95, -459, + 95, -459, -459, -292, -459, 22, 22, 95, -459, -292, + -459, -292, -226, -262, -134, -133, -132, 652, -174, -239, + -459, 95, -331, -277, 59, 84, 133, 97, 97, 97, + 15, -458, -243, 237, -344, -268, -289, -204, 413, -263, + -459, -289, 96, 96, 786, 150, 96, -244, -151, -458, + 300, -339, 97, 97, -141, -144, -32, 95, 165, -289, + -219, 67, -174, -239, -459, 84, 633, 745, -118, -117, + -114, 756, 782, -239, -120, -120, -174, -174, -174, -459, + -331, 270, -459, -459, -134, 95, -131, -130, -331, -356, + 621, -81, -82, -83, -8, 342, 269, 253, 284, -417, + -357, 84, 133, -303, -289, -344, -331, 96, -459, -458, + -268, 96, -272, 94, -3, 300, -364, -415, -365, -366, + -5, -6, -391, -108, -421, -395, -337, -333, 97, 104, + 96, 621, -459, -459, -116, 158, 754, 716, -183, 236, + -459, 95, -459, 95, -459, 95, -132, 95, 27, 626, + 787, -84, -85, -83, -82, -174, -289, -59, -331, 256, + 257, 258, -65, -63, -64, 260, -331, -459, -340, -205, + -203, -331, 676, -438, -437, 617, -448, -444, 129, 156, + 109, -446, 713, 718, 670, 139, 140, -174, 94, -459, + 237, -429, 622, -116, 755, 690, 664, 690, 664, -179, + -174, -174, -174, -130, -458, 164, -83, 161, -357, 255, + 262, -66, -67, 34, -170, 65, -459, 95, 25, -357, + -79, 687, -435, -436, 84, -439, 419, 686, 707, 129, + 97, 104, 96, -289, -338, -423, 623, 155, -145, -459, + 95, -459, 95, -459, -119, -85, -273, 33, 25, 25, + -68, -69, 453, 454, 455, 456, 457, 458, 459, 460, + 461, 462, 463, 464, -68, 97, -203, 683, -370, -187, + -436, 84, -435, 84, 16, 15, -4, 785, 96, -116, + 690, 664, -174, -174, -459, -89, -88, -87, 163, -458, + -178, -60, -61, -62, -64, 261, 156, 259, 104, -63, + -62, 165, -78, 28, -204, -434, 283, 278, 281, 34, + -434, 104, -4, -459, -459, -86, 162, -87, -174, -174, + -82, 95, 254, -183, 687, 277, 33, 129, 164, -85, + 161, -459, -61, -187, 269, -85, -207, -206, -206, } var yyDef = [...]int{ - 960, -2, 1, 2, -2, 962, 960, 4, 5, 7, + 962, -2, 1, 2, -2, 964, 962, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 131, 133, 134, 960, 960, - 960, 0, 960, 0, 192, 0, 1021, -2, -2, 960, - 1737, 0, 960, 0, 955, 0, -2, 875, 881, 0, - 890, -2, 0, 0, 960, 960, 2413, 2413, 955, 0, - 0, 0, 0, 0, 960, 960, 960, 960, 1742, 1573, - 111, 960, 0, 149, 150, 960, 910, 911, 912, 126, - 0, 2411, 146, 960, 961, 3, 132, 136, 0, 0, - 0, 119, 1582, 0, 139, 0, 0, 964, 0, 0, - 1720, 960, 960, 0, 190, 191, 0, 0, 0, 0, - 0, 195, -2, 227, 228, 229, 0, 234, 679, 596, - 648, 594, 633, -2, 582, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 599, 471, 471, - 0, 0, -2, 582, 582, 582, 1722, 0, 0, 0, - 630, 533, 471, 471, 471, 0, 471, 471, 471, 471, - 0, 0, 471, 471, 471, 471, 471, 471, 471, 471, - 471, 471, 471, 471, 471, 471, 471, 471, 471, 1600, - 233, 1738, 1735, 1736, 1910, 1911, 1912, 1913, 1914, 1915, - 1916, 1917, 1918, 1919, 1920, 1921, 1922, 1923, 1924, 1925, - 1926, 1927, 1928, 1929, 1930, 1931, 1932, 1933, 1934, 1935, - 1936, 1937, 1938, 1939, 1940, 1941, 1942, 1943, 1944, 1945, - 1946, 1947, 1948, 1949, 1950, 1951, 1952, 1953, 1954, 1955, - 1956, 1957, 1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965, - 1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, - 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, - 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, - 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, - 2026, 2027, 2028, 2029, 2030, 2031, 2032, 2033, 2034, 2035, - 2036, 2037, 2038, 2039, 2040, 2041, 2042, 2043, 2044, 2045, - 2046, 2047, 2048, 2049, 2050, 2051, 2052, 2053, 2054, 2055, - 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063, 2064, 2065, - 2066, 2067, 2068, 2069, 2070, 2071, 2072, 2073, 2074, 2075, - 2076, 2077, 2078, 2079, 2080, 2081, 2082, 2083, 2084, 2085, - 2086, 2087, 2088, 2089, 2090, 2091, 2092, 2093, 2094, 2095, - 2096, 2097, 2098, 2099, 2100, 2101, 2102, 2103, 2104, 2105, - 2106, 2107, 2108, 2109, 2110, 2111, 2112, 2113, 2114, 2115, - 2116, 2117, 2118, 2119, 2120, 2121, 2122, 2123, 2124, 2125, - 2126, 2127, 2128, 2129, 2130, 2131, 2132, 2133, 2134, 2135, - 2136, 2137, 2138, 2139, 2140, 2141, 2142, 2143, 2144, 2145, - 2146, 2147, 2148, 2149, 2150, 2151, 2152, 2153, 2154, 2155, - 2156, 2157, 2158, 2159, 2160, 2161, 2162, 2163, 2164, 2165, - 2166, 2167, 2168, 2169, 2170, 2171, 2172, 2173, 2174, 2175, - 2176, 2177, 2178, 2179, 2180, 2181, 2182, 2183, 2184, 2185, - 2186, 2187, 2188, 2189, 2190, 2191, 2192, 2193, 2194, 2195, - 2196, 2197, 2198, 2199, 2200, 2201, 2202, 2203, 2204, 2205, - 2206, 2207, 2208, 2209, 2210, 2211, 2212, 2213, 2214, 2215, - 2216, 2217, 2218, 2219, 2220, 2221, 2222, 2223, 2224, 2225, - 2226, 2227, 2228, 2229, 2230, 2231, 2232, 2233, 2234, 2235, - 2236, 2237, 2238, 2239, 2240, 2241, 2242, 2243, 2244, 2245, - 2246, 2247, 2248, 2249, 2250, 2251, 2252, 2253, 2254, 2255, - 2256, 2257, 2258, 2259, 2260, 2261, 2262, 2263, 2264, 2265, - 2266, 2267, 2268, 2269, 2270, 2271, 2272, 2273, 2274, 2275, - 2276, 2277, 2278, 2279, 2280, 2281, 2282, 2283, 2284, 2285, - 2286, 2287, 2288, 2289, 2290, 2291, 2292, 2293, 2294, 2295, - 2296, 2297, 2298, 2299, 2300, 2301, 2302, 2303, 2304, 2305, - 2306, 2307, 2308, 2309, 2310, 2311, 2312, 2313, 2314, 2315, - 2316, 2317, 2318, 2319, 2320, 2321, 2322, 2323, 2324, 2325, - 2326, 2327, 2328, 2329, 2330, 2331, 2332, 2333, 2334, 2335, - 2336, 2337, 2338, 2339, 2340, 2341, 2342, 2343, 2344, 2345, - 2346, 2347, 2348, 2349, 2350, 2351, 2352, 2353, 2354, 2355, - 2356, 2357, 2358, 2359, 2360, 2361, 2362, 2363, 2364, 2365, - 2366, 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, - 2376, 2377, 2378, 2379, 2380, 2381, 2382, 2383, 2384, 2385, - 2386, 2387, 2388, 2389, 2390, 2391, 2392, 2393, 2394, 2395, - 2396, 2397, 2398, 2399, 2400, 2401, 2402, 2403, 2404, 2405, - 2406, 2407, 2408, 2409, 2410, 0, 1714, 0, 793, 1064, - 0, 956, 957, 0, 864, 864, 0, 864, 864, 864, - 864, 0, 0, 0, 807, 0, 0, 0, 0, 861, - 0, 823, 824, 0, 861, 0, 830, 867, 0, 0, - 837, 864, 864, 840, 2414, 0, 2414, 2414, 0, 0, - 1705, 0, 858, 856, 870, 871, 103, 874, 877, 878, - 879, 880, 883, 0, 894, 897, 1731, 1732, 0, 899, - 904, 923, 924, 0, 106, 1224, 0, 1088, 0, 1099, - -2, 1110, 1127, 1128, 1129, 1130, 1131, 1133, 1134, 1135, - 0, 0, 0, 0, 1140, 1141, 0, 0, 0, 0, - 0, 1204, 0, 0, 0, 0, 2125, 1544, 0, 0, - 1506, 1506, 1240, 1506, 1506, 1508, 1508, 1508, 1969, 2116, - 2126, 2314, 1924, 1930, 1931, 1932, 2259, 2260, 2261, 2262, - 2357, 2358, 2362, 2036, 1919, 2329, 2330, 0, 2410, 2076, - 2084, 2085, 2061, 2070, 2109, 2216, 2341, 1943, 2104, 2178, - 2032, 2056, 2057, 2197, 2198, 2080, 2081, 2060, 2265, 2267, - 2283, 2284, 2269, 2271, 2280, 2286, 2291, 2270, 2282, 2287, - 2300, 2304, 2307, 2308, 2309, 2277, 2275, 2288, 2292, 2294, - 2296, 2302, 2305, 2278, 2276, 2289, 2293, 2295, 2297, 2303, - 2306, 2264, 2268, 2272, 2281, 2299, 2279, 2298, 2273, 2285, - 2290, 2301, 2274, 2266, 2074, 2077, 2064, 2065, 2067, 2069, - 2075, 2082, 2088, 2066, 2087, 2086, 0, 2062, 2063, 2068, - 2079, 2083, 2071, 2072, 2073, 2078, 2089, 2132, 2131, 2130, - 2177, 2100, 2176, 0, 0, 0, 0, 0, 1913, 1976, - 1977, 2311, 1428, 1429, 1430, 1431, 0, 0, 0, 0, - 0, 0, 0, 360, 361, 1557, 1558, 105, 1223, 1701, - 1508, 1508, 1508, 1508, 1508, 1508, 1162, 1163, 1164, 1165, - 1166, 1192, 1193, 1199, 1200, 2192, 2193, 2194, 2195, 2014, - 2352, 2023, 2024, 2173, 2174, 2038, 2039, 2384, 2385, -2, - -2, -2, 302, 303, 304, 305, 306, 307, 308, 309, - 0, 1975, 2327, 2328, 298, 0, 1699, 1700, 365, 362, - 363, 364, 1206, 1207, 318, 319, 320, 321, 322, 323, - 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, - 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, - 354, 355, 356, 357, 358, 359, 0, 367, 368, 2413, - 0, 933, 0, 0, 0, 0, 0, 0, 1743, 1744, - 1582, 0, 1574, 1573, 124, 0, 960, -2, 0, 0, - 0, 0, -2, 108, 0, 113, 1021, 0, 963, 138, - 137, 1633, 1636, 0, 0, 0, 1643, 1645, 1646, 1647, - 102, 120, 1583, 128, 130, 1584, 0, 965, 966, 0, - 997, 1001, 0, 0, 0, 1721, 1720, 1720, 166, 0, - 0, 167, 187, 188, 189, 0, 0, 173, 174, 1707, - 1708, 104, 0, 0, 245, 246, 0, 1180, 498, 0, - 241, 0, 491, 430, 0, 0, 0, 1025, 230, 231, - 232, 471, 471, 471, 645, 0, 0, 233, 233, 603, - 604, 605, 0, 0, -2, 496, 0, 583, 0, 0, - 485, 485, 489, 487, 488, 0, 0, 0, 0, 0, - 0, 0, 0, 622, 0, 623, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 740, 0, 472, 0, 643, - 644, 534, 0, 0, 0, 0, 0, 0, 0, 0, - 1723, 1724, 0, 620, 621, 0, 0, 0, 471, 471, - 0, 0, 0, 0, 471, 471, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 221, 1623, 0, 0, 222, 223, - 1601, 0, -2, 0, 784, 0, 0, 0, 1716, 1716, - 1716, 0, 1715, 792, 0, 0, 0, 797, 0, 0, - 798, 0, 861, 861, 859, 860, 800, 801, 802, 803, - 864, 0, 0, 480, 481, 482, 861, 864, 0, 864, - 864, 864, 864, 861, 861, 861, 864, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2414, 867, 864, 0, - 831, 0, 832, 833, 834, 835, 838, 839, 841, 2415, - 2416, 1733, 1734, 1745, 1746, 1747, 1748, 1749, 1750, 1751, - 1752, 1753, 1754, 1755, 1756, 1757, 1758, 1759, 1760, 1761, - 1762, 1763, 1764, 1765, 1766, 1767, 1768, 1769, 1770, 1771, - 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, - 1782, 1783, 1784, 1785, 1786, 1787, 1788, 1789, 1790, 1791, - 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, 1800, 1801, - 1802, 1803, 1804, 1805, 1806, 1807, 1808, 1809, 1810, 1811, - 1812, 1813, 1814, 1815, 1816, 1817, 1818, 1819, 1820, 1821, - 1822, 1823, 1824, 1825, 1826, 1827, 1828, 1829, 1830, 1831, - 1832, 1833, 1834, 1835, 1836, 1837, 1838, 1839, 1840, 1841, - 1842, 1843, 1844, 1845, 1846, 1847, 1848, 1849, 1850, 1851, - 1852, 1853, 1854, 1855, 1856, 1857, 1858, 1859, 1860, 1861, - 1862, 1863, 1864, 1865, 1866, 1867, 1868, 1869, 1870, 1871, - 1872, 1873, 1874, 1875, 1876, 1877, 1878, 1879, 1880, 1881, - 1882, 1883, 1884, 1885, 1886, 1887, 1888, 1889, 1890, 1891, - 1892, 1893, 1894, 1895, 1896, 1897, 1898, 1899, 1900, 1901, - 1902, 1903, 1904, 1905, 1906, 1907, 1908, 1909, 2414, 2414, - 845, 849, 853, 851, 1706, 876, 882, 884, 885, 0, - 0, 895, 898, 917, 110, 2022, 903, 110, 905, 906, - 907, 908, 909, 935, 936, 941, 0, 0, 0, 0, - 947, 948, 949, 0, 0, 952, 953, 954, 0, 0, - 0, 0, 0, 1086, 0, 0, 1212, 1213, 1214, 1215, - 1216, 1217, 1218, 1219, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1111, 1112, 0, 0, 0, 1136, 1137, 1138, - 1139, 1142, 0, 1153, 0, 1155, 1553, -2, 0, 0, - 0, 1147, 1148, 0, 0, 0, 1726, 1726, 0, 0, - 0, 1545, 0, 0, 1238, 0, 1239, 1241, 1242, 1243, - 0, 1244, 1245, 970, 970, 970, 970, 970, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 970, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1726, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 205, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1726, 0, 0, - 1726, 1726, 0, 0, 290, 291, 292, 293, 294, 295, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 366, 310, 311, 312, 313, 314, - 369, 315, 316, 317, 1223, 0, 0, 960, 0, 107, - 925, 926, 0, 1047, 1726, 0, 0, 976, 0, 1741, - 118, 127, 129, 1582, 122, 1582, 0, 980, 0, 0, - -2, -2, 981, 982, 986, 987, 988, 989, 990, 991, - 992, 993, 994, 115, 2412, 116, 0, 135, 1605, 0, - 1600, 1623, 0, 0, 0, 0, 1718, 1624, 0, 0, - 0, 109, 0, 140, 141, 1689, 1693, 0, 1634, 0, - 1637, 0, 0, 0, 444, 1641, 0, 0, 0, 1575, - 1576, 1579, 0, 998, 2122, 1002, 0, 1004, 1005, 0, - 0, 164, 0, 1063, 0, 0, 0, 175, 0, 177, - 178, 0, 0, 0, 455, 1709, 1710, 1711, -2, 478, - 0, 455, 439, 377, 378, 379, 430, 381, 430, 430, - 430, 430, 430, 444, 444, 444, 430, 413, 414, 415, - 416, 0, 430, 0, 398, 430, 430, 430, 430, 420, - 421, 422, 423, 424, 425, 426, 427, 382, 383, 384, - 385, 386, 387, 388, 389, 390, 432, 432, 432, 432, - 432, 436, 436, 0, 1181, 0, 459, 0, 1579, 0, - 0, 1609, 1022, 0, 0, 0, 0, 646, 690, 597, - 634, 647, 0, 600, 601, -2, 0, 0, 582, 0, - 584, 0, 479, 0, -2, 0, 489, 0, 485, 489, - 486, 489, 477, 490, 624, 625, 626, 0, 628, 629, - 720, 1033, 0, 0, 0, 0, 0, 726, 727, 728, - 0, 730, 731, 732, 733, 734, 735, 736, 737, 738, - 739, 635, 636, 637, 638, 639, 640, 641, 642, 0, - 0, 0, 0, 584, 0, 631, 0, 0, 535, 536, - 537, 0, 0, 540, 541, 542, 543, 0, 0, 546, - 547, 548, 1050, 1051, 549, 550, 575, 576, 577, 551, - 552, 553, 554, 555, 556, 557, 569, 570, 571, 572, - 573, 574, 558, 559, 560, 561, 562, 563, 566, 0, - 215, 1605, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1716, 0, - 0, 0, 0, 0, 979, 1065, 1739, 1740, 794, 0, - 0, 865, 866, 0, 483, 484, 864, 864, 804, 846, - 0, 864, 808, 847, 809, 811, 810, 812, 825, 826, - 864, 815, 862, 863, 816, 817, 818, 819, 820, 821, - 822, 842, 827, 828, 829, 868, 0, 872, 873, 843, - 844, 0, 854, 0, 0, 0, 888, 889, 0, 896, - 920, 918, 919, 921, 913, 914, 915, 916, 0, 922, - 0, 0, 938, 160, 943, 944, 945, 946, 958, 951, - 1225, 1083, 1084, 1085, 0, 1087, 1093, 0, 1208, 1210, - 1091, 1092, 1095, 0, 0, 0, 1089, 1100, 1220, 1221, - 1222, 0, 0, 0, 0, 0, 1104, 1108, 1113, 1114, - 1115, 1116, 1117, 0, 1118, 0, 1121, 1122, 1123, 1124, - 1125, 1126, 1132, 1521, 1522, 1523, 1151, 370, 371, 0, - 1152, 0, 0, 0, 0, 0, 0, 0, 0, 1468, - 1469, 1470, 1471, 1472, 1473, 1474, 1475, 1476, 1477, 1478, - 1479, 1480, 1481, 1482, 1483, 1484, 1485, 1486, 1487, 1224, - 0, 1727, 0, 0, 0, 1551, 1548, 0, 0, 0, - 1507, 1509, 0, 0, 0, 971, 972, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1488, 1489, 1490, 1491, 1492, 1493, - 1494, 1495, 1496, 1497, 1498, 1499, 1500, 1501, 1502, 1503, - 1504, 1505, 0, 0, 1524, 0, 0, 0, 0, 0, - 0, 0, 1544, 0, 1157, 1158, 1159, 0, 0, 0, - 0, 0, 0, 1286, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 206, 207, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1432, - 1433, 1434, 1435, 0, 0, 0, 0, 0, 0, 0, - 1555, 0, -2, -2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1457, 0, 0, - 0, 0, 0, 0, 1697, 0, 0, 928, 929, 931, - 0, 1067, 0, 1048, 0, 0, 934, 0, 975, 0, - 978, 121, 123, 984, 985, 0, 1006, 995, 983, 117, - 1718, 0, 0, 1718, 1623, 1605, 1728, 0, 0, 0, - 0, 0, 196, 0, 112, 0, 0, 0, 1635, 1638, - 1639, 444, 1666, 0, 453, 453, 450, 1644, 1585, 1586, - 0, 1578, 1580, 1581, 142, 1003, 999, 0, 1081, 0, - 0, 1062, 0, 1009, 1011, 1012, 1013, 1045, 0, 1016, - 1017, 0, 0, 0, 0, 0, 162, 1064, 168, 0, - 176, 0, 0, 181, 182, 169, 170, 171, 172, 0, - 679, -2, 530, 247, 249, 250, 251, 242, -2, 442, - 440, 441, 380, 444, 444, 406, 407, 444, 409, 410, - 411, 412, 0, 418, 0, 399, 400, 401, 402, 391, - 0, 392, 393, 394, 434, 0, 395, 396, 0, 397, - 497, 0, 1587, 460, 461, 463, 471, 0, 466, 467, - 0, 471, 471, 0, 492, 493, 0, 1579, 194, 1611, - 1026, 235, 236, 237, 238, 239, 240, 715, 0, 0, - 691, 713, 714, 233, 0, 0, 243, 586, 585, 0, - 747, 0, 495, 0, 0, 489, 489, 474, 475, 627, - 0, 0, 722, 723, 724, 725, 0, 0, 0, 613, - 524, 0, 614, 615, 584, 586, 0, 0, 455, 538, - 539, 544, 545, 564, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 662, 663, 665, 668, 670, 588, - 674, 676, 0, 664, 667, 669, 671, 588, 675, 677, - 1602, 1603, 1604, 0, 0, 785, 0, 0, 521, 158, - 1717, 790, 791, 795, 796, 861, 814, 848, 861, 806, - 813, 836, 850, 852, 886, 887, 892, 900, 901, 902, - 942, 0, 0, 0, 0, 950, 0, 0, 1094, 1209, - 1211, 1096, 1097, 1098, 1101, 0, 1105, 1109, 0, 0, - 0, 0, 0, 1156, 1154, 1555, 0, 0, 0, 1205, - 0, 0, 1228, 1229, 0, 0, 0, 0, 1549, 0, - 0, 1236, 0, 1510, 1186, 0, 0, 0, 0, 0, - 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, 1186, - 1573, 1263, 0, 0, 0, 0, 0, 1268, 1269, 1270, - 1186, 0, 1273, 1274, 0, 1276, 0, 1277, 0, 0, - 0, 0, 1284, 1285, 1287, 0, 0, 1290, 1291, 0, - 1293, 0, 1295, 1296, 1297, 1298, 1299, 1300, 0, 1302, - 0, 1304, 1305, 1306, 0, 1308, 0, 1310, 1311, 0, - 1313, 0, 1315, 0, 1318, 0, 1321, 0, 1324, 0, - 1327, 0, 1330, 0, 1333, 0, 1336, 0, 1339, 0, - 1342, 0, 1345, 0, 1348, 0, 1351, 0, 1354, 0, - 1357, 0, 1360, 0, 1363, 1364, 1365, 0, 1367, 0, - 1369, 0, 1372, 1373, 0, 1375, 0, 1378, 0, 1381, - 0, 0, 1382, 0, 0, 0, 1386, 0, 0, 0, - 0, 1395, 1396, 1397, 1398, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1409, 1410, 1411, 1412, 1413, - 1414, 0, 1416, 0, 1187, 0, 0, 1187, 0, 0, - 0, 0, 0, 1226, 1726, 0, 1511, 1512, 1513, 1514, - 1515, 0, 0, 0, 0, 0, 0, 1455, 1456, 1458, - 0, 0, 1461, 0, 1463, 0, 1698, 927, 930, 932, - 1019, 1068, 1069, 0, 0, 0, 0, 1049, 1725, 973, - 974, 977, 1027, 0, 1559, 0, 0, 1006, 1081, 0, - 1007, 0, 0, 0, 0, 0, 1605, 0, 0, 1729, - 1728, 1728, 1728, 220, 0, 1625, 1626, 1631, 1629, 1630, - 114, 1690, 1694, 1648, 1642, 1660, 1673, 453, 453, 447, - 448, 454, 449, 451, 452, 1577, 0, 1582, 0, 1687, - 0, 960, 1676, 0, 0, 0, 0, 0, 0, 0, - 0, 1052, 0, 0, 1055, 0, 0, 0, 0, 1046, - 1017, 0, 1018, 0, -2, 0, 0, 156, 157, 0, - 0, 0, 179, 180, 0, 0, 186, 456, 457, 224, - 233, 532, 248, 505, 0, 0, 376, 443, 403, 404, - 405, 408, 0, 428, 0, 0, 0, 0, 526, 193, - 1591, 1590, 471, 471, 462, 0, 465, 0, 0, 0, - 1730, 431, 494, 0, 1612, 1613, 685, 0, 0, 692, - 0, 0, 0, 595, 0, 606, 607, 0, 719, -2, - 781, 459, 0, 473, 476, 1034, 0, 0, 608, 0, - 611, 612, 525, 586, 617, 618, 632, 619, 567, 568, - 565, 0, 197, 653, 655, 659, 654, 658, 0, 0, - 0, 590, 0, 678, 590, 651, 0, 521, 1587, 0, - 789, 522, 523, 864, 864, 937, 161, 0, 940, 0, - 0, 0, 0, 1102, 1106, 1119, 1120, 1516, 1542, 430, - 430, 1529, 430, 436, 1532, 430, 1534, 430, 1537, 430, - 1540, 1541, 0, 0, 1149, 0, 0, 0, 0, 1235, - 1552, 0, 0, 1246, 1185, 1186, 1186, 1186, 1186, 1186, - 1252, 1253, 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, - 1546, 0, 0, 0, 1267, 0, 0, 1271, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 208, 209, 0, - 0, 0, 0, 0, 0, 1466, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1180, 1184, 0, - 1188, 1189, 0, 0, 1418, 0, 0, 1436, 0, 0, - 0, 0, 0, 0, 0, 1556, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1070, 1077, 0, 1077, - 0, 1077, 0, 0, 0, 1712, 1713, 1560, 1561, 1081, - 1562, 996, 1008, 0, 212, 1606, 1607, 1608, 211, 0, - 0, 0, 0, 0, 0, 1719, 0, 1628, 1632, 1666, - 0, 1659, 0, -2, 1668, 0, 0, 0, 1674, 445, - 446, 1000, 143, 1082, 147, 0, 1687, 1702, 0, 1684, - 1691, 1695, 0, 0, 0, 1680, 0, 1081, 1010, 1041, - 1043, 0, 1038, 1053, 1054, 1056, 0, 1058, 0, 1060, - 1061, 1021, 1015, 0, 164, 0, 1081, 1081, 163, 0, - 1066, 183, 184, 185, 531, 252, 257, 0, 0, 0, - 262, 0, 264, 0, 0, 0, 269, 270, 471, 471, - 506, 0, 373, 375, 0, 0, 255, 444, 0, 444, - 0, 435, 437, 0, 507, 527, 1588, 1589, 0, 0, - 464, 468, 469, 470, 0, 688, 0, 716, 0, 0, - 0, 0, 0, 0, 244, 587, 748, 749, 750, 751, - 752, 753, 754, 755, 756, 0, 471, 0, 0, 0, - 471, 471, 471, 0, 773, 458, 0, 0, 744, 741, - 609, 0, 288, 289, 296, 297, 299, 0, 0, 0, - 0, 0, 616, 1021, 200, 0, 0, 0, 0, 661, - 666, 672, 0, 589, 673, 786, 787, 788, 159, 799, - 805, 939, 959, 1090, 1103, 1107, 0, 0, 0, 0, - 1543, 1527, 444, 1530, 1531, 1533, 1535, 1536, 1538, 1539, - 1145, 1146, 1150, 0, 1232, 0, 1234, 0, 1550, 0, - 1247, 1248, 1249, 1250, 1251, 1582, 0, 0, 0, 1266, - 0, 0, 1186, 0, 1279, 1278, 1280, 0, 1282, 1283, - 1288, 1289, 1292, 1294, 1301, 1303, 1307, 1309, 1312, 1314, - 1316, 0, 1319, 0, 1322, 0, 1325, 0, 1328, 0, - 1331, 0, 1334, 0, 1337, 0, 1340, 0, 1343, 0, - 1346, 0, 1349, 0, 1352, 0, 1355, 0, 1358, 0, - 1361, 0, 1366, 1368, 0, 1371, 1374, 1376, 0, 1379, - 0, 1383, 0, 1385, 1387, 1388, 0, 0, 0, 1399, - 1400, 1401, 1402, 1403, 1404, 1405, 1406, 1407, 1408, 1415, - 0, 1178, 1417, 1190, 1191, 1196, 1420, 0, 0, 0, - 1423, 0, 0, 0, 1427, 1227, 1438, 0, 1443, 0, - 0, 1449, 0, 1453, 0, 1459, 1460, 1462, 1464, 0, - 0, 0, 0, 0, 0, 0, 1047, 1028, 125, 1562, - 1566, 0, -2, 0, 214, 216, 0, 0, 0, 1627, - 1653, 1651, 1651, 1661, 1662, 0, 0, 1669, 0, 0, - 0, 0, 148, 0, 0, 1675, 0, 0, 1696, 0, - 0, 0, 0, 165, 1573, 1035, 1042, 0, 0, 1036, - 0, 1037, 1057, 1059, 1014, 0, 1081, 1081, 154, 155, - 0, 258, 0, 260, 0, 263, 265, 266, 267, 273, - 274, 275, 276, 268, 0, 0, 372, 374, 0, 0, - 417, 429, 419, 0, 0, 1592, 1593, 1594, 1595, 1596, - 1597, 1598, 1599, 1610, 680, 0, 690, 0, 1023, 0, - 683, 0, 598, 0, 0, 0, 471, 471, 471, 0, - 0, 0, 0, 758, 0, 0, 721, 0, 729, 0, - 0, 0, 300, 301, 0, 652, 0, 198, 199, 0, - 0, 657, 591, 592, 1143, 0, 0, 0, 1144, 1528, - 0, 0, 0, 0, 0, 1547, 0, 0, 0, 0, - 1272, 1275, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1391, 0, 0, 0, 710, 711, - 0, 1467, 1183, 1573, 0, 1187, 1197, 1198, 0, 1187, - 1437, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1078, 0, 0, 0, 1029, 1030, 0, 0, - 0, 1067, 1566, 1571, 0, 0, 0, 1615, 1616, 0, - 1620, 1621, 1622, 213, 217, 218, 219, 1656, 0, 1649, - 1652, 1650, 1663, 0, 0, 1670, 0, 1672, 0, 1703, - 1704, 1692, 1685, 960, 1679, 1682, 1684, 1681, 1582, 1039, - 0, 1044, 0, 1573, 153, 0, 261, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 271, 272, - 0, 0, 433, 438, 0, 0, 681, 0, 1024, 693, - 684, 0, 771, 0, 775, 0, 0, 0, 778, 779, - 780, 757, 0, 761, 499, 745, 742, 743, 610, 0, - 201, 202, 0, 0, 0, 1517, 0, 1520, 1230, 1233, - 1231, 0, 1262, 1264, 1265, 1525, 1526, 1281, 1317, 1320, - 1323, 1326, 1329, 1332, 1335, 1338, 1341, 1344, 1347, 1350, - 1353, 1356, 1359, 1362, 1370, 1377, 1380, 1384, 1389, 0, - 1392, 0, 0, 1393, 0, 712, 1174, 0, 0, 1194, - 1195, 0, 1422, 1424, 1425, 1426, 1439, 0, 1444, 1445, - 0, 1450, 0, 1454, 1465, 0, 1072, 1079, 1080, 0, - 1075, 0, 1076, 0, 1020, 1571, 145, 1572, 1569, 0, - 1567, 1564, 110, 1619, 0, 1640, 0, 1654, 1655, 1664, - 1665, 1671, 0, 0, 1684, 0, 1678, 151, 0, 0, - 0, 1582, 259, 0, 279, 689, 0, 692, 682, 769, - 770, 0, 782, 774, 776, 777, 759, -2, 1609, 0, - 0, 0, 660, 1518, 0, 0, 1394, 0, 708, 709, - 1182, 1175, 0, 1160, 1161, 1179, 1419, 1421, 0, 0, - 0, 1071, 1031, 1032, 1073, 1074, 144, 0, 1568, 1202, - 0, 1563, 0, 210, 89, 90, 43, -2, 0, 0, - 0, 1617, 1618, 1657, 1658, 1688, 0, 1677, 1683, 1040, - 1047, 0, 152, 512, 505, 0, 0, 0, 762, 763, - 764, 765, 766, 767, 768, 649, 203, 204, 0, 579, - 580, 581, 197, 0, 1237, 1390, 1176, 0, 0, 0, - 0, 0, 1440, 0, 1446, 0, 1451, 0, 1570, 0, - 0, 1565, 88, 0, -2, 93, 0, 0, 0, 0, - 1025, 67, 68, 69, 50, 74, 75, 83, 77, 1686, - 694, 0, 696, 0, -2, 500, 513, 0, 253, 280, - 281, 0, 0, 284, 0, 286, 287, 277, 278, 0, - 0, 783, 0, 200, 0, 0, 1167, 1168, 1169, 1170, - 1172, 0, 0, 0, 0, 1203, 1180, 44, 94, 110, - 85, 0, 0, 49, 51, 0, 0, 84, 695, 0, - 0, 455, 0, 705, 501, 502, 0, 508, 509, 510, - 511, 282, 283, 285, 717, 0, 578, 656, 1519, 0, - 0, 1441, 0, 1447, 0, 1452, 0, -2, 46, 0, - 0, 0, 52, 0, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 53, 76, 697, 698, - 706, 0, 503, 0, 504, 0, 0, 0, 686, 0, - 717, 1177, 1171, 1173, 0, 0, 1201, 95, 98, 100, - 0, 0, 87, 110, 71, 78, 79, 80, 0, 82, - 72, 73, 48, 0, 0, 707, 703, 514, 516, 517, - 0, 0, 515, 718, 687, 1442, 1448, 0, 110, 99, - 0, 0, 47, 0, 81, 54, 0, 518, 519, 520, - 0, -2, 110, 86, 70, 699, 45, -2, 700, 701, - 702, + 38, 39, 40, 41, 42, 131, 133, 134, 962, 962, + 962, 0, 962, 0, 194, 0, 1023, -2, -2, 962, + 1739, 0, 962, 0, 957, 0, -2, 877, 883, 0, + 892, -2, 0, 0, 962, 962, 2415, 2415, 957, 0, + 0, 0, 0, 0, 962, 962, 962, 962, 1744, 1575, + 111, 962, 0, 151, 152, 962, 912, 913, 914, 126, + 0, 2413, 148, 962, 963, 3, 132, 136, 0, 0, + 0, 119, 1584, 0, 139, 0, 0, 966, 0, 0, + 1722, 962, 962, 0, 192, 193, 0, 0, 0, 0, + 0, 197, -2, 229, 230, 231, 0, 236, 681, 598, + 650, 596, 635, -2, 584, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 601, 473, 473, + 0, 0, -2, 584, 584, 584, 1724, 0, 0, 0, + 632, 535, 473, 473, 473, 0, 473, 473, 473, 473, + 0, 0, 473, 473, 473, 473, 473, 473, 473, 473, + 473, 473, 473, 473, 473, 473, 473, 473, 473, 1602, + 235, 1740, 1737, 1738, 1912, 1913, 1914, 1915, 1916, 1917, + 1918, 1919, 1920, 1921, 1922, 1923, 1924, 1925, 1926, 1927, + 1928, 1929, 1930, 1931, 1932, 1933, 1934, 1935, 1936, 1937, + 1938, 1939, 1940, 1941, 1942, 1943, 1944, 1945, 1946, 1947, + 1948, 1949, 1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, + 1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, + 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, + 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, + 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, + 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, + 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, + 2028, 2029, 2030, 2031, 2032, 2033, 2034, 2035, 2036, 2037, + 2038, 2039, 2040, 2041, 2042, 2043, 2044, 2045, 2046, 2047, + 2048, 2049, 2050, 2051, 2052, 2053, 2054, 2055, 2056, 2057, + 2058, 2059, 2060, 2061, 2062, 2063, 2064, 2065, 2066, 2067, + 2068, 2069, 2070, 2071, 2072, 2073, 2074, 2075, 2076, 2077, + 2078, 2079, 2080, 2081, 2082, 2083, 2084, 2085, 2086, 2087, + 2088, 2089, 2090, 2091, 2092, 2093, 2094, 2095, 2096, 2097, + 2098, 2099, 2100, 2101, 2102, 2103, 2104, 2105, 2106, 2107, + 2108, 2109, 2110, 2111, 2112, 2113, 2114, 2115, 2116, 2117, + 2118, 2119, 2120, 2121, 2122, 2123, 2124, 2125, 2126, 2127, + 2128, 2129, 2130, 2131, 2132, 2133, 2134, 2135, 2136, 2137, + 2138, 2139, 2140, 2141, 2142, 2143, 2144, 2145, 2146, 2147, + 2148, 2149, 2150, 2151, 2152, 2153, 2154, 2155, 2156, 2157, + 2158, 2159, 2160, 2161, 2162, 2163, 2164, 2165, 2166, 2167, + 2168, 2169, 2170, 2171, 2172, 2173, 2174, 2175, 2176, 2177, + 2178, 2179, 2180, 2181, 2182, 2183, 2184, 2185, 2186, 2187, + 2188, 2189, 2190, 2191, 2192, 2193, 2194, 2195, 2196, 2197, + 2198, 2199, 2200, 2201, 2202, 2203, 2204, 2205, 2206, 2207, + 2208, 2209, 2210, 2211, 2212, 2213, 2214, 2215, 2216, 2217, + 2218, 2219, 2220, 2221, 2222, 2223, 2224, 2225, 2226, 2227, + 2228, 2229, 2230, 2231, 2232, 2233, 2234, 2235, 2236, 2237, + 2238, 2239, 2240, 2241, 2242, 2243, 2244, 2245, 2246, 2247, + 2248, 2249, 2250, 2251, 2252, 2253, 2254, 2255, 2256, 2257, + 2258, 2259, 2260, 2261, 2262, 2263, 2264, 2265, 2266, 2267, + 2268, 2269, 2270, 2271, 2272, 2273, 2274, 2275, 2276, 2277, + 2278, 2279, 2280, 2281, 2282, 2283, 2284, 2285, 2286, 2287, + 2288, 2289, 2290, 2291, 2292, 2293, 2294, 2295, 2296, 2297, + 2298, 2299, 2300, 2301, 2302, 2303, 2304, 2305, 2306, 2307, + 2308, 2309, 2310, 2311, 2312, 2313, 2314, 2315, 2316, 2317, + 2318, 2319, 2320, 2321, 2322, 2323, 2324, 2325, 2326, 2327, + 2328, 2329, 2330, 2331, 2332, 2333, 2334, 2335, 2336, 2337, + 2338, 2339, 2340, 2341, 2342, 2343, 2344, 2345, 2346, 2347, + 2348, 2349, 2350, 2351, 2352, 2353, 2354, 2355, 2356, 2357, + 2358, 2359, 2360, 2361, 2362, 2363, 2364, 2365, 2366, 2367, + 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, + 2378, 2379, 2380, 2381, 2382, 2383, 2384, 2385, 2386, 2387, + 2388, 2389, 2390, 2391, 2392, 2393, 2394, 2395, 2396, 2397, + 2398, 2399, 2400, 2401, 2402, 2403, 2404, 2405, 2406, 2407, + 2408, 2409, 2410, 2411, 2412, 0, 1716, 0, 795, 1066, + 0, 958, 959, 0, 866, 866, 0, 866, 866, 866, + 866, 0, 0, 0, 809, 0, 0, 0, 0, 863, + 0, 825, 826, 0, 863, 0, 832, 869, 0, 0, + 839, 866, 866, 842, 2416, 0, 2416, 2416, 0, 0, + 1707, 0, 860, 858, 872, 873, 103, 876, 879, 880, + 881, 882, 885, 0, 896, 899, 1733, 1734, 0, 901, + 906, 925, 926, 0, 106, 1226, 0, 1090, 0, 1101, + -2, 1112, 1129, 1130, 1131, 1132, 1133, 1135, 1136, 1137, + 0, 0, 0, 0, 1142, 1143, 0, 0, 0, 0, + 0, 1206, 0, 0, 0, 0, 2127, 1546, 0, 0, + 1508, 1508, 1242, 1508, 1508, 1510, 1510, 1510, 1971, 2118, + 2128, 2316, 1926, 1932, 1933, 1934, 2261, 2262, 2263, 2264, + 2359, 2360, 2364, 2038, 1921, 2331, 2332, 0, 2412, 2078, + 2086, 2087, 2063, 2072, 2111, 2218, 2343, 1945, 2106, 2180, + 2034, 2058, 2059, 2199, 2200, 2082, 2083, 2062, 2267, 2269, + 2285, 2286, 2271, 2273, 2282, 2288, 2293, 2272, 2284, 2289, + 2302, 2306, 2309, 2310, 2311, 2279, 2277, 2290, 2294, 2296, + 2298, 2304, 2307, 2280, 2278, 2291, 2295, 2297, 2299, 2305, + 2308, 2266, 2270, 2274, 2283, 2301, 2281, 2300, 2275, 2287, + 2292, 2303, 2276, 2268, 2076, 2079, 2066, 2067, 2069, 2071, + 2077, 2084, 2090, 2068, 2089, 2088, 0, 2064, 2065, 2070, + 2081, 2085, 2073, 2074, 2075, 2080, 2091, 2134, 2133, 2132, + 2179, 2102, 2178, 0, 0, 0, 0, 0, 1915, 1978, + 1979, 2313, 1430, 1431, 1432, 1433, 0, 0, 0, 0, + 0, 0, 0, 362, 363, 1559, 1560, 105, 1225, 1703, + 1510, 1510, 1510, 1510, 1510, 1510, 1164, 1165, 1166, 1167, + 1168, 1194, 1195, 1201, 1202, 2194, 2195, 2196, 2197, 2016, + 2354, 2025, 2026, 2175, 2176, 2040, 2041, 2386, 2387, -2, + -2, -2, 304, 305, 306, 307, 308, 309, 310, 311, + 0, 1977, 2329, 2330, 300, 0, 1701, 1702, 367, 364, + 365, 366, 1208, 1209, 320, 321, 322, 323, 324, 325, + 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, + 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 0, 369, 370, 2415, + 0, 935, 0, 0, 0, 0, 0, 0, 1745, 1746, + 1584, 0, 1576, 1575, 124, 0, 962, -2, 0, 0, + 0, 0, -2, 108, 0, 113, 1023, 0, 965, 138, + 137, 1635, 1638, 0, 0, 0, 1645, 1647, 1648, 1649, + 102, 120, 1585, 128, 130, 1586, 0, 967, 968, 0, + 0, 1003, 0, 0, 0, 0, 1723, 1722, 1722, 168, + 0, 0, 169, 189, 190, 191, 0, 0, 175, 176, + 1709, 1710, 104, 0, 0, 247, 248, 0, 1182, 500, + 0, 243, 0, 493, 432, 0, 0, 0, 1027, 232, + 233, 234, 473, 473, 473, 647, 0, 0, 235, 235, + 605, 606, 607, 0, 0, -2, 498, 0, 585, 0, + 0, 487, 487, 491, 489, 490, 0, 0, 0, 0, + 0, 0, 0, 0, 624, 0, 625, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 742, 0, 474, 0, + 645, 646, 536, 0, 0, 0, 0, 0, 0, 0, + 0, 1725, 1726, 0, 622, 623, 0, 0, 0, 473, + 473, 0, 0, 0, 0, 473, 473, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 223, 1625, 0, 0, 224, + 225, 1603, 0, -2, 0, 786, 0, 0, 0, 1718, + 1718, 1718, 0, 1717, 794, 0, 0, 0, 799, 0, + 0, 800, 0, 863, 863, 861, 862, 802, 803, 804, + 805, 866, 0, 0, 482, 483, 484, 863, 866, 0, + 866, 866, 866, 866, 863, 863, 863, 866, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2416, 869, 866, + 0, 833, 0, 834, 835, 836, 837, 840, 841, 843, + 2417, 2418, 1735, 1736, 1747, 1748, 1749, 1750, 1751, 1752, + 1753, 1754, 1755, 1756, 1757, 1758, 1759, 1760, 1761, 1762, + 1763, 1764, 1765, 1766, 1767, 1768, 1769, 1770, 1771, 1772, + 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782, + 1783, 1784, 1785, 1786, 1787, 1788, 1789, 1790, 1791, 1792, + 1793, 1794, 1795, 1796, 1797, 1798, 1799, 1800, 1801, 1802, + 1803, 1804, 1805, 1806, 1807, 1808, 1809, 1810, 1811, 1812, + 1813, 1814, 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822, + 1823, 1824, 1825, 1826, 1827, 1828, 1829, 1830, 1831, 1832, + 1833, 1834, 1835, 1836, 1837, 1838, 1839, 1840, 1841, 1842, + 1843, 1844, 1845, 1846, 1847, 1848, 1849, 1850, 1851, 1852, + 1853, 1854, 1855, 1856, 1857, 1858, 1859, 1860, 1861, 1862, + 1863, 1864, 1865, 1866, 1867, 1868, 1869, 1870, 1871, 1872, + 1873, 1874, 1875, 1876, 1877, 1878, 1879, 1880, 1881, 1882, + 1883, 1884, 1885, 1886, 1887, 1888, 1889, 1890, 1891, 1892, + 1893, 1894, 1895, 1896, 1897, 1898, 1899, 1900, 1901, 1902, + 1903, 1904, 1905, 1906, 1907, 1908, 1909, 1910, 1911, 2416, + 2416, 847, 851, 855, 853, 1708, 878, 884, 886, 887, + 0, 0, 897, 900, 919, 110, 2024, 905, 110, 907, + 908, 909, 910, 911, 937, 938, 943, 0, 0, 0, + 0, 949, 950, 951, 0, 0, 954, 955, 956, 0, + 0, 0, 0, 0, 1088, 0, 0, 1214, 1215, 1216, + 1217, 1218, 1219, 1220, 1221, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1113, 1114, 0, 0, 0, 1138, 1139, + 1140, 1141, 1144, 0, 1155, 0, 1157, 1555, -2, 0, + 0, 0, 1149, 1150, 0, 0, 0, 1728, 1728, 0, + 0, 0, 1547, 0, 0, 1240, 0, 1241, 1243, 1244, + 1245, 0, 1246, 1247, 972, 972, 972, 972, 972, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 972, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1728, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 207, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1728, 0, + 0, 1728, 1728, 0, 0, 292, 293, 294, 295, 296, + 297, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 368, 312, 313, 314, 315, + 316, 371, 317, 318, 319, 1225, 0, 0, 962, 0, + 107, 927, 928, 0, 1049, 1728, 0, 0, 978, 0, + 1743, 118, 127, 129, 1584, 122, 1584, 0, 982, 0, + 0, -2, -2, 983, 984, 988, 989, 990, 991, 992, + 993, 994, 995, 996, 115, 2414, 116, 0, 135, 1607, + 0, 1602, 1625, 0, 0, 0, 0, 1720, 1626, 0, + 0, 0, 109, 0, 140, 141, 1691, 1695, 0, 1636, + 0, 1639, 0, 0, 0, 446, 1643, 0, 0, 0, + 1577, 1578, 1581, 0, 0, 1000, 2124, 1004, 0, 1006, + 1007, 0, 0, 0, 166, 0, 1065, 0, 0, 0, + 177, 0, 179, 180, 0, 0, 0, 457, 1711, 1712, + 1713, -2, 480, 0, 457, 441, 379, 380, 381, 432, + 383, 432, 432, 432, 432, 432, 446, 446, 446, 432, + 415, 416, 417, 418, 0, 432, 0, 400, 432, 432, + 432, 432, 422, 423, 424, 425, 426, 427, 428, 429, + 384, 385, 386, 387, 388, 389, 390, 391, 392, 434, + 434, 434, 434, 434, 438, 438, 0, 1183, 0, 461, + 0, 1581, 0, 0, 1611, 1024, 0, 0, 0, 0, + 648, 692, 599, 636, 649, 0, 602, 603, -2, 0, + 0, 584, 0, 586, 0, 481, 0, -2, 0, 491, + 0, 487, 491, 488, 491, 479, 492, 626, 627, 628, + 0, 630, 631, 722, 1035, 0, 0, 0, 0, 0, + 728, 729, 730, 0, 732, 733, 734, 735, 736, 737, + 738, 739, 740, 741, 637, 638, 639, 640, 641, 642, + 643, 644, 0, 0, 0, 0, 586, 0, 633, 0, + 0, 537, 538, 539, 0, 0, 542, 543, 544, 545, + 0, 0, 548, 549, 550, 1052, 1053, 551, 552, 577, + 578, 579, 553, 554, 555, 556, 557, 558, 559, 571, + 572, 573, 574, 575, 576, 560, 561, 562, 563, 564, + 565, 568, 0, 217, 1607, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1718, 0, 0, 0, 0, 0, 981, 1067, 1741, + 1742, 796, 0, 0, 867, 868, 0, 485, 486, 866, + 866, 806, 848, 0, 866, 810, 849, 811, 813, 812, + 814, 827, 828, 866, 817, 864, 865, 818, 819, 820, + 821, 822, 823, 824, 844, 829, 830, 831, 870, 0, + 874, 875, 845, 846, 0, 856, 0, 0, 0, 890, + 891, 0, 898, 922, 920, 921, 923, 915, 916, 917, + 918, 0, 924, 0, 0, 940, 162, 945, 946, 947, + 948, 960, 953, 1227, 1085, 1086, 1087, 0, 1089, 1095, + 0, 1210, 1212, 1093, 1094, 1097, 0, 0, 0, 1091, + 1102, 1222, 1223, 1224, 0, 0, 0, 0, 0, 1106, + 1110, 1115, 1116, 1117, 1118, 1119, 0, 1120, 0, 1123, + 1124, 1125, 1126, 1127, 1128, 1134, 1523, 1524, 1525, 1153, + 372, 373, 0, 1154, 0, 0, 0, 0, 0, 0, + 0, 0, 1470, 1471, 1472, 1473, 1474, 1475, 1476, 1477, + 1478, 1479, 1480, 1481, 1482, 1483, 1484, 1485, 1486, 1487, + 1488, 1489, 1226, 0, 1729, 0, 0, 0, 1553, 1550, + 0, 0, 0, 1509, 1511, 0, 0, 0, 973, 974, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1490, 1491, 1492, + 1493, 1494, 1495, 1496, 1497, 1498, 1499, 1500, 1501, 1502, + 1503, 1504, 1505, 1506, 1507, 0, 0, 1526, 0, 0, + 0, 0, 0, 0, 0, 1546, 0, 1159, 1160, 1161, + 0, 0, 0, 0, 0, 0, 1288, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 208, 209, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1434, 1435, 1436, 1437, 0, 0, 0, 0, + 0, 0, 0, 1557, 0, -2, -2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1459, 0, 0, 0, 0, 0, 0, 1699, 0, 0, + 930, 931, 933, 0, 1069, 0, 1050, 0, 0, 936, + 0, 977, 0, 980, 121, 123, 986, 987, 0, 1008, + 997, 998, 985, 117, 1720, 0, 0, 1720, 1625, 1607, + 1730, 0, 0, 0, 0, 0, 198, 0, 112, 0, + 0, 0, 1637, 1640, 1641, 446, 1668, 0, 455, 455, + 452, 1646, 1587, 1588, 0, 1580, 1582, 1583, 142, 143, + 1005, 1001, 0, 1083, 1083, 0, 0, 1064, 0, 1011, + 1013, 1014, 1015, 1047, 0, 1018, 1019, 0, 0, 0, + 0, 0, 164, 1066, 170, 0, 178, 0, 0, 183, + 184, 171, 172, 173, 174, 0, 681, -2, 532, 249, + 251, 252, 253, 244, -2, 444, 442, 443, 382, 446, + 446, 408, 409, 446, 411, 412, 413, 414, 0, 420, + 0, 401, 402, 403, 404, 393, 0, 394, 395, 396, + 436, 0, 397, 398, 0, 399, 499, 0, 1589, 462, + 463, 465, 473, 0, 468, 469, 0, 473, 473, 0, + 494, 495, 0, 1581, 196, 1613, 1028, 237, 238, 239, + 240, 241, 242, 717, 0, 0, 693, 715, 716, 235, + 0, 0, 245, 588, 587, 0, 749, 0, 497, 0, + 0, 491, 491, 476, 477, 629, 0, 0, 724, 725, + 726, 727, 0, 0, 0, 615, 526, 0, 616, 617, + 586, 588, 0, 0, 457, 540, 541, 546, 547, 566, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 664, 665, 667, 670, 672, 590, 676, 678, 0, 666, + 669, 671, 673, 590, 677, 679, 1604, 1605, 1606, 0, + 0, 787, 0, 0, 523, 160, 1719, 792, 793, 797, + 798, 863, 816, 850, 863, 808, 815, 838, 852, 854, + 888, 889, 894, 902, 903, 904, 944, 0, 0, 0, + 0, 952, 0, 0, 1096, 1211, 1213, 1098, 1099, 1100, + 1103, 0, 1107, 1111, 0, 0, 0, 0, 0, 1158, + 1156, 1557, 0, 0, 0, 1207, 0, 0, 1230, 1231, + 0, 0, 0, 0, 1551, 0, 0, 1238, 0, 1512, + 1188, 0, 0, 0, 0, 0, 1188, 1188, 1188, 1188, + 1188, 1188, 1188, 1188, 1188, 1188, 1575, 1265, 0, 0, + 0, 0, 0, 1270, 1271, 1272, 1188, 0, 1275, 1276, + 0, 1278, 0, 1279, 0, 0, 0, 0, 1286, 1287, + 1289, 0, 0, 1292, 1293, 0, 1295, 0, 1297, 1298, + 1299, 1300, 1301, 1302, 0, 1304, 0, 1306, 1307, 1308, + 0, 1310, 0, 1312, 1313, 0, 1315, 0, 1317, 0, + 1320, 0, 1323, 0, 1326, 0, 1329, 0, 1332, 0, + 1335, 0, 1338, 0, 1341, 0, 1344, 0, 1347, 0, + 1350, 0, 1353, 0, 1356, 0, 1359, 0, 1362, 0, + 1365, 1366, 1367, 0, 1369, 0, 1371, 0, 1374, 1375, + 0, 1377, 0, 1380, 0, 1383, 0, 0, 1384, 0, + 0, 0, 1388, 0, 0, 0, 0, 1397, 1398, 1399, + 1400, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1411, 1412, 1413, 1414, 1415, 1416, 0, 1418, 0, + 1189, 0, 0, 1189, 0, 0, 0, 0, 0, 1228, + 1728, 0, 1513, 1514, 1515, 1516, 1517, 0, 0, 0, + 0, 0, 0, 1457, 1458, 1460, 0, 0, 1463, 0, + 1465, 0, 1700, 929, 932, 934, 1021, 1070, 1071, 0, + 0, 0, 0, 1051, 1727, 975, 976, 979, 1029, 0, + 1561, 0, 0, 1008, 1083, 0, 1009, 0, 0, 0, + 0, 0, 1607, 0, 0, 1731, 1730, 1730, 1730, 222, + 0, 1627, 1628, 1633, 1631, 1632, 114, 1692, 1696, 1650, + 1644, 1662, 1675, 455, 455, 449, 450, 456, 451, 453, + 454, 1579, 0, 1584, 0, 1584, 1689, 0, 962, 1678, + 0, 0, 0, 0, 0, 0, 0, 0, 1054, 0, + 0, 1057, 0, 0, 0, 0, 1048, 1019, 0, 1020, + 0, -2, 0, 0, 158, 159, 0, 0, 0, 181, + 182, 0, 0, 188, 458, 459, 226, 235, 534, 250, + 507, 0, 0, 378, 445, 405, 406, 407, 410, 0, + 430, 0, 0, 0, 0, 528, 195, 1593, 1592, 473, + 473, 464, 0, 467, 0, 0, 0, 1732, 433, 496, + 0, 1614, 1615, 687, 0, 0, 694, 0, 0, 0, + 597, 0, 608, 609, 0, 721, -2, 783, 461, 0, + 475, 478, 1036, 0, 0, 610, 0, 613, 614, 527, + 588, 619, 620, 634, 621, 569, 570, 567, 0, 199, + 655, 657, 661, 656, 660, 0, 0, 0, 592, 0, + 680, 592, 653, 0, 523, 1589, 0, 791, 524, 525, + 866, 866, 939, 163, 0, 942, 0, 0, 0, 0, + 1104, 1108, 1121, 1122, 1518, 1544, 432, 432, 1531, 432, + 438, 1534, 432, 1536, 432, 1539, 432, 1542, 1543, 0, + 0, 1151, 0, 0, 0, 0, 1237, 1554, 0, 0, + 1248, 1187, 1188, 1188, 1188, 1188, 1188, 1254, 1255, 1256, + 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1548, 0, 0, + 0, 1269, 0, 0, 1273, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 210, 211, 0, 0, 0, 0, + 0, 0, 1468, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1182, 1186, 0, 1190, 1191, 0, + 0, 1420, 0, 0, 1438, 0, 0, 0, 0, 0, + 0, 0, 1558, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1072, 1079, 0, 1079, 0, 1079, 0, + 0, 0, 1714, 1715, 1562, 1563, 1083, 1564, 999, 1010, + 0, 214, 1608, 1609, 1610, 213, 0, 0, 0, 0, + 0, 0, 1721, 0, 1630, 1634, 1668, 0, 1661, 0, + -2, 1670, 0, 0, 0, 1676, 447, 448, 1002, 144, + 1084, 145, 149, 0, 1689, 1704, 0, 1686, 1693, 1697, + 0, 0, 0, 1682, 0, 1083, 1012, 1043, 1045, 0, + 1040, 1055, 1056, 1058, 0, 1060, 0, 1062, 1063, 1023, + 1017, 0, 166, 0, 1083, 1083, 165, 0, 1068, 185, + 186, 187, 533, 254, 259, 0, 0, 0, 264, 0, + 266, 0, 0, 0, 271, 272, 473, 473, 508, 0, + 375, 377, 0, 0, 257, 446, 0, 446, 0, 437, + 439, 0, 509, 529, 1590, 1591, 0, 0, 466, 470, + 471, 472, 0, 690, 0, 718, 0, 0, 0, 0, + 0, 0, 246, 589, 750, 751, 752, 753, 754, 755, + 756, 757, 758, 0, 473, 0, 0, 0, 473, 473, + 473, 0, 775, 460, 0, 0, 746, 743, 611, 0, + 290, 291, 298, 299, 301, 0, 0, 0, 0, 0, + 618, 1023, 202, 0, 0, 0, 0, 663, 668, 674, + 0, 591, 675, 788, 789, 790, 161, 801, 807, 941, + 961, 1092, 1105, 1109, 0, 0, 0, 0, 1545, 1529, + 446, 1532, 1533, 1535, 1537, 1538, 1540, 1541, 1147, 1148, + 1152, 0, 1234, 0, 1236, 0, 1552, 0, 1249, 1250, + 1251, 1252, 1253, 1584, 0, 0, 0, 1268, 0, 0, + 1188, 0, 1281, 1280, 1282, 0, 1284, 1285, 1290, 1291, + 1294, 1296, 1303, 1305, 1309, 1311, 1314, 1316, 1318, 0, + 1321, 0, 1324, 0, 1327, 0, 1330, 0, 1333, 0, + 1336, 0, 1339, 0, 1342, 0, 1345, 0, 1348, 0, + 1351, 0, 1354, 0, 1357, 0, 1360, 0, 1363, 0, + 1368, 1370, 0, 1373, 1376, 1378, 0, 1381, 0, 1385, + 0, 1387, 1389, 1390, 0, 0, 0, 1401, 1402, 1403, + 1404, 1405, 1406, 1407, 1408, 1409, 1410, 1417, 0, 1180, + 1419, 1192, 1193, 1198, 1422, 0, 0, 0, 1425, 0, + 0, 0, 1429, 1229, 1440, 0, 1445, 0, 0, 1451, + 0, 1455, 0, 1461, 1462, 1464, 1466, 0, 0, 0, + 0, 0, 0, 0, 1049, 1030, 125, 1564, 1568, 0, + -2, 0, 216, 218, 0, 0, 0, 1629, 1655, 1653, + 1653, 1663, 1664, 0, 0, 1671, 0, 0, 0, 0, + 150, 0, 0, 1677, 0, 0, 1698, 0, 0, 0, + 0, 167, 1575, 1037, 1044, 0, 0, 1038, 0, 1039, + 1059, 1061, 1016, 0, 1083, 1083, 156, 157, 0, 260, + 0, 262, 0, 265, 267, 268, 269, 275, 276, 277, + 278, 270, 0, 0, 374, 376, 0, 0, 419, 431, + 421, 0, 0, 1594, 1595, 1596, 1597, 1598, 1599, 1600, + 1601, 1612, 682, 0, 692, 0, 1025, 0, 685, 0, + 600, 0, 0, 0, 473, 473, 473, 0, 0, 0, + 0, 760, 0, 0, 723, 0, 731, 0, 0, 0, + 302, 303, 0, 654, 0, 200, 201, 0, 0, 659, + 593, 594, 1145, 0, 0, 0, 1146, 1530, 0, 0, + 0, 0, 0, 1549, 0, 0, 0, 0, 1274, 1277, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1393, 0, 0, 0, 712, 713, 0, 1469, + 1185, 1575, 0, 1189, 1199, 1200, 0, 1189, 1439, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1080, 0, 0, 0, 1031, 1032, 0, 0, 0, 1069, + 1568, 1573, 0, 0, 0, 1617, 1618, 0, 1622, 1623, + 1624, 215, 219, 220, 221, 1658, 0, 1651, 1654, 1652, + 1665, 0, 0, 1672, 0, 1674, 0, 1705, 1706, 1694, + 1687, 962, 1681, 1684, 1686, 1683, 1584, 1041, 0, 1046, + 0, 1575, 155, 0, 263, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 273, 274, 0, 0, + 435, 440, 0, 0, 683, 0, 1026, 695, 686, 0, + 773, 0, 777, 0, 0, 0, 780, 781, 782, 759, + 0, 763, 501, 747, 744, 745, 612, 0, 203, 204, + 0, 0, 0, 1519, 0, 1522, 1232, 1235, 1233, 0, + 1264, 1266, 1267, 1527, 1528, 1283, 1319, 1322, 1325, 1328, + 1331, 1334, 1337, 1340, 1343, 1346, 1349, 1352, 1355, 1358, + 1361, 1364, 1372, 1379, 1382, 1386, 1391, 0, 1394, 0, + 0, 1395, 0, 714, 1176, 0, 0, 1196, 1197, 0, + 1424, 1426, 1427, 1428, 1441, 0, 1446, 1447, 0, 1452, + 0, 1456, 1467, 0, 1074, 1081, 1082, 0, 1077, 0, + 1078, 0, 1022, 1573, 147, 1574, 1571, 0, 1569, 1566, + 110, 1621, 0, 1642, 0, 1656, 1657, 1666, 1667, 1673, + 0, 0, 1686, 0, 1680, 153, 0, 0, 0, 1584, + 261, 0, 281, 691, 0, 694, 684, 771, 772, 0, + 784, 776, 778, 779, 761, -2, 1611, 0, 0, 0, + 662, 1520, 0, 0, 1396, 0, 710, 711, 1184, 1177, + 0, 1162, 1163, 1181, 1421, 1423, 0, 0, 0, 1073, + 1033, 1034, 1075, 1076, 146, 0, 1570, 1204, 0, 1565, + 0, 212, 89, 90, 43, -2, 0, 0, 0, 1619, + 1620, 1659, 1660, 1690, 0, 1679, 1685, 1042, 1049, 0, + 154, 514, 507, 0, 0, 0, 764, 765, 766, 767, + 768, 769, 770, 651, 205, 206, 0, 581, 582, 583, + 199, 0, 1239, 1392, 1178, 0, 0, 0, 0, 0, + 1442, 0, 1448, 0, 1453, 0, 1572, 0, 0, 1567, + 88, 0, -2, 93, 0, 0, 0, 0, 1027, 67, + 68, 69, 50, 74, 75, 83, 77, 1688, 696, 0, + 698, 0, -2, 502, 515, 0, 255, 282, 283, 0, + 0, 286, 0, 288, 289, 279, 280, 0, 0, 785, + 0, 202, 0, 0, 1169, 1170, 1171, 1172, 1174, 0, + 0, 0, 0, 1205, 1182, 44, 94, 110, 85, 0, + 0, 49, 51, 0, 0, 84, 697, 0, 0, 457, + 0, 707, 503, 504, 0, 510, 511, 512, 513, 284, + 285, 287, 719, 0, 580, 658, 1521, 0, 0, 1443, + 0, 1449, 0, 1454, 0, -2, 46, 0, 0, 0, + 52, 0, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 53, 76, 699, 700, 708, 0, + 505, 0, 506, 0, 0, 0, 688, 0, 719, 1179, + 1173, 1175, 0, 0, 1203, 95, 98, 100, 0, 0, + 87, 110, 71, 78, 79, 80, 0, 82, 72, 73, + 48, 0, 0, 709, 705, 516, 518, 519, 0, 0, + 517, 720, 689, 1444, 1450, 0, 110, 99, 0, 0, + 47, 0, 81, 54, 0, 520, 521, 522, 0, -2, + 110, 86, 70, 701, 45, -2, 702, 703, 704, } var yyTok1 = [...]int{ @@ -12029,45 +12161,61 @@ yydefault: var yyLOCAL Statement //line sql.y:1239 { - yyLOCAL = &Stream{Comments: Comments(yyDollar[2].strs).Parsed(), SelectExpr: yyDollar[3].selectExprUnion(), Table: yyDollar[5].tableName} + yyLOCAL = &Stream{Comments: Comments(yyDollar[2].strs).Parsed(), SelectExpr: &StarExpr{}, Table: yyDollar[5].tableName} } yyVAL.union = yyLOCAL case 143: + yyDollar = yyS[yypt-5 : yypt+1] + var yyLOCAL Statement +//line sql.y:1243 + { + yyLOCAL = &Stream{Comments: Comments(yyDollar[2].strs).Parsed(), SelectExpr: yyDollar[3].selectExprUnion(), Table: yyDollar[5].tableName} + } + yyVAL.union = yyLOCAL + case 144: + yyDollar = yyS[yypt-7 : yypt+1] + var yyLOCAL Statement +//line sql.y:1249 + { + yyLOCAL = &VStream{Comments: Comments(yyDollar[2].strs).Parsed(), SelectExpr: &StarExpr{}, Table: yyDollar[5].tableName, Where: NewWhere(WhereClause, yyDollar[6].exprUnion()), Limit: yyDollar[7].limitUnion()} + } + yyVAL.union = yyLOCAL + case 145: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:1245 +//line sql.y:1253 { yyLOCAL = &VStream{Comments: Comments(yyDollar[2].strs).Parsed(), SelectExpr: yyDollar[3].selectExprUnion(), Table: yyDollar[5].tableName, Where: NewWhere(WhereClause, yyDollar[6].exprUnion()), Limit: yyDollar[7].limitUnion()} } yyVAL.union = yyLOCAL - case 144: + case 146: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL TableStatement -//line sql.y:1253 +//line sql.y:1261 { yyLOCAL = NewSelect(Comments(yyDollar[2].strs), yyDollar[4].selectExprsUnion() /*SelectExprs*/, yyDollar[3].strs /*options*/, yyDollar[5].selectIntoUnion() /*into*/, yyDollar[6].tableExprsUnion() /*from*/, NewWhere(WhereClause, yyDollar[7].exprUnion()), yyDollar[8].groupByUnion(), NewWhere(HavingClause, yyDollar[9].exprUnion()), yyDollar[10].namedWindowsUnion()) } yyVAL.union = yyLOCAL - case 145: + case 147: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL TableStatement -//line sql.y:1257 +//line sql.y:1265 { yyLOCAL = NewSelect(Comments(yyDollar[2].strs), yyDollar[4].selectExprsUnion() /*SelectExprs*/, yyDollar[3].strs /*options*/, nil, yyDollar[5].tableExprsUnion() /*from*/, NewWhere(WhereClause, yyDollar[6].exprUnion()), yyDollar[7].groupByUnion(), NewWhere(HavingClause, yyDollar[8].exprUnion()), yyDollar[9].namedWindowsUnion()) } yyVAL.union = yyLOCAL - case 146: + case 148: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableStatement -//line sql.y:1261 +//line sql.y:1269 { yyLOCAL = yyDollar[1].tableStmtUnion() } yyVAL.union = yyLOCAL - case 147: + case 149: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:1267 +//line sql.y:1275 { // insert_data returns a *Insert pre-filled with Columns & Values ins := yyDollar[6].insUnion() @@ -12080,10 +12228,10 @@ yydefault: yyLOCAL = ins } yyVAL.union = yyLOCAL - case 148: + case 150: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Statement -//line sql.y:1279 +//line sql.y:1287 { cols := make(Columns, 0, len(yyDollar[7].updateExprsUnion())) vals := make(ValTuple, 0, len(yyDollar[8].updateExprsUnion())) @@ -12094,329 +12242,329 @@ yydefault: yyLOCAL = &Insert{Action: yyDollar[1].insertActionUnion(), Comments: Comments(yyDollar[2].strs).Parsed(), Ignore: yyDollar[3].ignoreUnion(), Table: getAliasedTableExprFromTableName(yyDollar[4].tableName), Partitions: yyDollar[5].partitionsUnion(), Columns: cols, Rows: Values{vals}, OnDup: OnDup(yyDollar[8].updateExprsUnion())} } yyVAL.union = yyLOCAL - case 149: + case 151: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL InsertAction -//line sql.y:1291 +//line sql.y:1299 { yyLOCAL = InsertAct } yyVAL.union = yyLOCAL - case 150: + case 152: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL InsertAction -//line sql.y:1295 +//line sql.y:1303 { yyLOCAL = ReplaceAct } yyVAL.union = yyLOCAL - case 151: + case 153: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Statement -//line sql.y:1301 +//line sql.y:1309 { yyLOCAL = &Update{With: yyDollar[1].withUnion(), Comments: Comments(yyDollar[3].strs).Parsed(), Ignore: yyDollar[4].ignoreUnion(), TableExprs: yyDollar[5].tableExprsUnion(), Exprs: yyDollar[7].updateExprsUnion(), Where: NewWhere(WhereClause, yyDollar[8].exprUnion()), OrderBy: yyDollar[9].orderByUnion(), Limit: yyDollar[10].limitUnion()} } yyVAL.union = yyLOCAL - case 152: + case 154: yyDollar = yyS[yypt-11 : yypt+1] var yyLOCAL Statement -//line sql.y:1307 +//line sql.y:1315 { yyLOCAL = &Delete{With: yyDollar[1].withUnion(), Comments: Comments(yyDollar[3].strs).Parsed(), Ignore: yyDollar[4].ignoreUnion(), TableExprs: TableExprs{&AliasedTableExpr{Expr: yyDollar[6].tableName, As: yyDollar[7].identifierCS}}, Partitions: yyDollar[8].partitionsUnion(), Where: NewWhere(WhereClause, yyDollar[9].exprUnion()), OrderBy: yyDollar[10].orderByUnion(), Limit: yyDollar[11].limitUnion()} } yyVAL.union = yyLOCAL - case 153: + case 155: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL Statement -//line sql.y:1311 +//line sql.y:1319 { yyLOCAL = &Delete{With: yyDollar[1].withUnion(), Comments: Comments(yyDollar[3].strs).Parsed(), Ignore: yyDollar[4].ignoreUnion(), Targets: yyDollar[6].tableNamesUnion(), TableExprs: yyDollar[8].tableExprsUnion(), Where: NewWhere(WhereClause, yyDollar[9].exprUnion())} } yyVAL.union = yyLOCAL - case 154: + case 156: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Statement -//line sql.y:1315 +//line sql.y:1323 { yyLOCAL = &Delete{With: yyDollar[1].withUnion(), Comments: Comments(yyDollar[3].strs).Parsed(), Ignore: yyDollar[4].ignoreUnion(), Targets: yyDollar[5].tableNamesUnion(), TableExprs: yyDollar[7].tableExprsUnion(), Where: NewWhere(WhereClause, yyDollar[8].exprUnion())} } yyVAL.union = yyLOCAL - case 155: + case 157: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Statement -//line sql.y:1319 +//line sql.y:1327 { yyLOCAL = &Delete{With: yyDollar[1].withUnion(), Comments: Comments(yyDollar[3].strs).Parsed(), Ignore: yyDollar[4].ignoreUnion(), Targets: yyDollar[5].tableNamesUnion(), TableExprs: yyDollar[7].tableExprsUnion(), Where: NewWhere(WhereClause, yyDollar[8].exprUnion())} } yyVAL.union = yyLOCAL - case 156: + case 158: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1324 +//line sql.y:1332 { } - case 157: + case 159: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1325 +//line sql.y:1333 { } - case 158: + case 160: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableNames -//line sql.y:1329 +//line sql.y:1337 { yyLOCAL = TableNames{yyDollar[1].tableName} } yyVAL.union = yyLOCAL - case 159: + case 161: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1333 +//line sql.y:1341 { yySLICE := (*TableNames)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableName) } - case 160: + case 162: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableNames -//line sql.y:1339 +//line sql.y:1347 { yyLOCAL = TableNames{yyDollar[1].tableName} } yyVAL.union = yyLOCAL - case 161: + case 163: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1343 +//line sql.y:1351 { yySLICE := (*TableNames)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableName) } - case 162: + case 164: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableNames -//line sql.y:1349 +//line sql.y:1357 { yyLOCAL = TableNames{yyDollar[1].tableName} } yyVAL.union = yyLOCAL - case 163: + case 165: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1353 +//line sql.y:1361 { yySLICE := (*TableNames)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableName) } - case 164: + case 166: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Partitions -//line sql.y:1358 +//line sql.y:1366 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 165: + case 167: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Partitions -//line sql.y:1362 +//line sql.y:1370 { yyLOCAL = yyDollar[3].partitionsUnion() } yyVAL.union = yyLOCAL - case 166: + case 168: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:1368 +//line sql.y:1376 { yyLOCAL = NewSetStatement(Comments(yyDollar[2].strs).Parsed(), yyDollar[3].setExprsUnion()) } yyVAL.union = yyLOCAL - case 167: + case 169: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SetExprs -//line sql.y:1374 +//line sql.y:1382 { yyLOCAL = SetExprs{yyDollar[1].setExprUnion()} } yyVAL.union = yyLOCAL - case 168: + case 170: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1378 +//line sql.y:1386 { yySLICE := (*SetExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].setExprUnion()) } - case 169: + case 171: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:1384 +//line sql.y:1392 { yyLOCAL = &SetExpr{Var: yyDollar[1].variableUnion(), Expr: NewStrLiteral("on")} } yyVAL.union = yyLOCAL - case 170: + case 172: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:1388 +//line sql.y:1396 { yyLOCAL = &SetExpr{Var: yyDollar[1].variableUnion(), Expr: NewStrLiteral("off")} } yyVAL.union = yyLOCAL - case 171: + case 173: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:1392 +//line sql.y:1400 { yyLOCAL = &SetExpr{Var: yyDollar[1].variableUnion(), Expr: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 172: + case 174: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:1396 +//line sql.y:1404 { yyLOCAL = &SetExpr{Var: NewSetVariable(string(yyDollar[1].str), SessionScope), Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 173: + case 175: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Variable -//line sql.y:1402 +//line sql.y:1410 { yyLOCAL = NewSetVariable(string(yyDollar[1].str), NoScope) } yyVAL.union = yyLOCAL - case 174: + case 176: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Variable -//line sql.y:1406 +//line sql.y:1414 { yyLOCAL = yyDollar[1].variableUnion() } yyVAL.union = yyLOCAL - case 175: + case 177: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Variable -//line sql.y:1410 +//line sql.y:1418 { yyLOCAL = NewSetVariable(string(yyDollar[2].str), yyDollar[1].scopeUnion()) } yyVAL.union = yyLOCAL - case 176: + case 178: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:1416 +//line sql.y:1424 { yyLOCAL = NewSetStatement(Comments(yyDollar[2].strs).Parsed(), UpdateSetExprsScope(yyDollar[5].setExprsUnion(), yyDollar[3].scopeUnion())) } yyVAL.union = yyLOCAL - case 177: + case 179: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:1420 +//line sql.y:1428 { yyLOCAL = NewSetStatement(Comments(yyDollar[2].strs).Parsed(), yyDollar[4].setExprsUnion()) } yyVAL.union = yyLOCAL - case 178: + case 180: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SetExprs -//line sql.y:1426 +//line sql.y:1434 { yyLOCAL = SetExprs{yyDollar[1].setExprUnion()} } yyVAL.union = yyLOCAL - case 179: + case 181: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1430 +//line sql.y:1438 { yySLICE := (*SetExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].setExprUnion()) } - case 180: + case 182: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:1436 +//line sql.y:1444 { yyLOCAL = &SetExpr{Var: NewSetVariable(TransactionIsolationStr, NextTxScope), Expr: NewStrLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 181: + case 183: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:1440 +//line sql.y:1448 { yyLOCAL = &SetExpr{Var: NewSetVariable(TransactionReadOnlyStr, NextTxScope), Expr: NewStrLiteral("off")} } yyVAL.union = yyLOCAL - case 182: + case 184: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:1444 +//line sql.y:1452 { yyLOCAL = &SetExpr{Var: NewSetVariable(TransactionReadOnlyStr, NextTxScope), Expr: NewStrLiteral("on")} } yyVAL.union = yyLOCAL - case 183: + case 185: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1450 +//line sql.y:1458 { yyVAL.str = RepeatableReadStr } - case 184: + case 186: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1454 +//line sql.y:1462 { yyVAL.str = ReadCommittedStr } - case 185: + case 187: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1458 +//line sql.y:1466 { yyVAL.str = ReadUncommittedStr } - case 186: + case 188: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1462 +//line sql.y:1470 { yyVAL.str = SerializableStr } - case 187: + case 189: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Scope -//line sql.y:1468 +//line sql.y:1476 { yyLOCAL = SessionScope } yyVAL.union = yyLOCAL - case 188: + case 190: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Scope -//line sql.y:1472 +//line sql.y:1480 { yyLOCAL = SessionScope } yyVAL.union = yyLOCAL - case 189: + case 191: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Scope -//line sql.y:1476 +//line sql.y:1484 { yyLOCAL = GlobalScope } yyVAL.union = yyLOCAL - case 190: + case 192: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:1482 +//line sql.y:1490 { yyDollar[1].createTableUnion().TableSpec = yyDollar[2].tableSpecUnion() yyDollar[1].createTableUnion().FullyParsed = true yyLOCAL = yyDollar[1].createTableUnion() } yyVAL.union = yyLOCAL - case 191: + case 193: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:1488 +//line sql.y:1496 { // Create table [name] like [name] yyDollar[1].createTableUnion().OptLike = yyDollar[2].optLikeUnion() @@ -12424,18 +12572,18 @@ yydefault: yyLOCAL = yyDollar[1].createTableUnion() } yyVAL.union = yyLOCAL - case 192: + case 194: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:1495 +//line sql.y:1503 { yyLOCAL = yyDollar[1].createProcedureUnion() } yyVAL.union = yyLOCAL - case 193: + case 195: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:1499 +//line sql.y:1507 { indexDef := yyDollar[1].alterTableUnion().AlterOptions[0].(*AddIndexDefinition).IndexDefinition indexDef.Columns = yyDollar[3].indexColumnsUnion() @@ -12445,10 +12593,10 @@ yydefault: yyLOCAL = yyDollar[1].alterTableUnion() } yyVAL.union = yyLOCAL - case 194: + case 196: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:1508 +//line sql.y:1516 { yyDollar[1].createViewUnion().Columns = yyDollar[2].columnsUnion() yyDollar[1].createViewUnion().Select = yyDollar[4].tableStmtUnion() @@ -12456,429 +12604,429 @@ yydefault: yyLOCAL = yyDollar[1].createViewUnion() } yyVAL.union = yyLOCAL - case 195: + case 197: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:1515 +//line sql.y:1523 { yyDollar[1].createDatabaseUnion().FullyParsed = true yyDollar[1].createDatabaseUnion().CreateOptions = yyDollar[2].databaseOptionsUnion() yyLOCAL = yyDollar[1].createDatabaseUnion() } yyVAL.union = yyLOCAL - case 196: + case 198: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:1523 +//line sql.y:1531 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 197: + case 199: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1528 +//line sql.y:1536 { yyVAL.identifierCI = NewIdentifierCI("") } - case 198: + case 200: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1532 +//line sql.y:1540 { yyVAL.identifierCI = yyDollar[2].identifierCI } - case 199: + case 201: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1538 +//line sql.y:1546 { yyVAL.identifierCI = yyDollar[1].identifierCI } - case 200: + case 202: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []VindexParam -//line sql.y:1543 +//line sql.y:1551 { var v []VindexParam yyLOCAL = v } yyVAL.union = yyLOCAL - case 201: + case 203: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []VindexParam -//line sql.y:1548 +//line sql.y:1556 { yyLOCAL = yyDollar[2].vindexParamsUnion() } yyVAL.union = yyLOCAL - case 202: + case 204: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []VindexParam -//line sql.y:1554 +//line sql.y:1562 { yyLOCAL = make([]VindexParam, 0, 4) yyLOCAL = append(yyLOCAL, yyDollar[1].vindexParam) } yyVAL.union = yyLOCAL - case 203: + case 205: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1559 +//line sql.y:1567 { yySLICE := (*[]VindexParam)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].vindexParam) } - case 204: + case 206: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1565 +//line sql.y:1573 { yyVAL.vindexParam = VindexParam{Key: yyDollar[1].identifierCI, Val: yyDollar[3].str} } - case 205: + case 207: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*JSONObjectParam -//line sql.y:1570 +//line sql.y:1578 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 206: + case 208: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*JSONObjectParam -//line sql.y:1574 +//line sql.y:1582 { yyLOCAL = yyDollar[1].jsonObjectParamsUnion() } yyVAL.union = yyLOCAL - case 207: + case 209: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*JSONObjectParam -//line sql.y:1580 +//line sql.y:1588 { yyLOCAL = []*JSONObjectParam{yyDollar[1].jsonObjectParam} } yyVAL.union = yyLOCAL - case 208: + case 210: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1584 +//line sql.y:1592 { yySLICE := (*[]*JSONObjectParam)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].jsonObjectParam) } - case 209: + case 211: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1590 +//line sql.y:1598 { yyVAL.jsonObjectParam = &JSONObjectParam{Key: yyDollar[1].exprUnion(), Value: yyDollar[3].exprUnion()} } - case 210: + case 212: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL *CreateProcedure -//line sql.y:1596 +//line sql.y:1604 { yyLOCAL = &CreateProcedure{Comments: Comments(yyDollar[2].strs).Parsed(), Name: yyDollar[6].tableName, IfNotExists: yyDollar[5].booleanUnion(), Definer: yyDollar[3].definerUnion(), Params: yyDollar[8].procParamsUnion(), Body: yyDollar[10].compoundStatementUnion()} } yyVAL.union = yyLOCAL - case 211: + case 213: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *CreateTable -//line sql.y:1602 +//line sql.y:1610 { yyLOCAL = &CreateTable{Comments: Comments(yyDollar[2].strs).Parsed(), Table: yyDollar[6].tableName, IfNotExists: yyDollar[5].booleanUnion(), Temp: yyDollar[3].booleanUnion()} setDDL(yylex, yyLOCAL) } yyVAL.union = yyLOCAL - case 212: + case 214: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *CreateView -//line sql.y:1618 +//line sql.y:1626 { yyLOCAL = &CreateView{ViewName: yyDollar[6].tableName, Comments: Comments(yyDollar[2].strs).Parsed(), Definer: yyDollar[3].definerUnion(), Security: yyDollar[4].str} } yyVAL.union = yyLOCAL - case 213: + case 215: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *CreateView -//line sql.y:1622 +//line sql.y:1630 { yyLOCAL = &CreateView{ViewName: yyDollar[8].tableName, Comments: Comments(yyDollar[2].strs).Parsed(), IsReplace: yyDollar[3].booleanUnion(), Algorithm: yyDollar[4].str, Definer: yyDollar[5].definerUnion(), Security: yyDollar[6].str} } yyVAL.union = yyLOCAL - case 214: + case 216: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *CreateView -//line sql.y:1626 +//line sql.y:1634 { yyLOCAL = &CreateView{ViewName: yyDollar[7].tableName, Comments: Comments(yyDollar[2].strs).Parsed(), Algorithm: yyDollar[3].str, Definer: yyDollar[4].definerUnion(), Security: yyDollar[5].str} } yyVAL.union = yyLOCAL - case 215: + case 217: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *AlterTable -//line sql.y:1633 +//line sql.y:1641 { yyLOCAL = &AlterTable{Comments: Comments(yyDollar[2].strs).Parsed(), Table: yyDollar[4].tableName} setDDL(yylex, yyLOCAL) } yyVAL.union = yyLOCAL - case 216: + case 218: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *AlterTable -//line sql.y:1640 +//line sql.y:1648 { yyLOCAL = &AlterTable{Comments: Comments(yyDollar[2].strs).Parsed(), Table: yyDollar[7].tableName, AlterOptions: []AlterOption{&AddIndexDefinition{IndexDefinition: &IndexDefinition{Info: &IndexInfo{Name: yyDollar[4].identifierCI}, Options: yyDollar[5].indexOptionsUnion()}}}} setDDL(yylex, yyLOCAL) } yyVAL.union = yyLOCAL - case 217: + case 219: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *AlterTable -//line sql.y:1645 +//line sql.y:1653 { yyLOCAL = &AlterTable{Comments: Comments(yyDollar[2].strs).Parsed(), Table: yyDollar[8].tableName, AlterOptions: []AlterOption{&AddIndexDefinition{IndexDefinition: &IndexDefinition{Info: &IndexInfo{Name: yyDollar[5].identifierCI, Type: IndexTypeFullText}, Options: yyDollar[6].indexOptionsUnion()}}}} setDDL(yylex, yyLOCAL) } yyVAL.union = yyLOCAL - case 218: + case 220: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *AlterTable -//line sql.y:1650 +//line sql.y:1658 { yyLOCAL = &AlterTable{Comments: Comments(yyDollar[2].strs).Parsed(), Table: yyDollar[8].tableName, AlterOptions: []AlterOption{&AddIndexDefinition{IndexDefinition: &IndexDefinition{Info: &IndexInfo{Name: yyDollar[5].identifierCI, Type: IndexTypeSpatial}, Options: yyDollar[6].indexOptionsUnion()}}}} setDDL(yylex, yyLOCAL) } yyVAL.union = yyLOCAL - case 219: + case 221: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *AlterTable -//line sql.y:1655 +//line sql.y:1663 { yyLOCAL = &AlterTable{Comments: Comments(yyDollar[2].strs).Parsed(), Table: yyDollar[8].tableName, AlterOptions: []AlterOption{&AddIndexDefinition{IndexDefinition: &IndexDefinition{Info: &IndexInfo{Name: yyDollar[5].identifierCI, Type: IndexTypeUnique}, Options: yyDollar[6].indexOptionsUnion()}}}} setDDL(yylex, yyLOCAL) } yyVAL.union = yyLOCAL - case 220: + case 222: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *CreateDatabase -//line sql.y:1662 +//line sql.y:1670 { yyLOCAL = &CreateDatabase{Comments: Comments(yyDollar[2].strs).Parsed(), DBName: yyDollar[5].identifierCS, IfNotExists: yyDollar[4].booleanUnion()} setDDL(yylex, yyLOCAL) } yyVAL.union = yyLOCAL - case 221: + case 223: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *AlterDatabase -//line sql.y:1669 +//line sql.y:1677 { yyLOCAL = &AlterDatabase{Comments: Comments(yyDollar[2].strs).Parsed()} setDDL(yylex, yyLOCAL) } yyVAL.union = yyLOCAL - case 224: + case 226: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *TableSpec -//line sql.y:1680 +//line sql.y:1688 { yyLOCAL = yyDollar[2].tableSpecUnion() yyLOCAL.Options = yyDollar[4].tableOptionsUnion() yyLOCAL.PartitionOption = yyDollar[5].partitionOptionUnion() } yyVAL.union = yyLOCAL - case 225: + case 227: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []DatabaseOption -//line sql.y:1687 +//line sql.y:1695 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 226: + case 228: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []DatabaseOption -//line sql.y:1691 +//line sql.y:1699 { yyLOCAL = yyDollar[1].databaseOptionsUnion() } yyVAL.union = yyLOCAL - case 227: + case 229: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []DatabaseOption -//line sql.y:1697 +//line sql.y:1705 { yyLOCAL = []DatabaseOption{yyDollar[1].databaseOption} } yyVAL.union = yyLOCAL - case 228: + case 230: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []DatabaseOption -//line sql.y:1701 +//line sql.y:1709 { yyLOCAL = []DatabaseOption{yyDollar[1].databaseOption} } yyVAL.union = yyLOCAL - case 229: + case 231: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []DatabaseOption -//line sql.y:1705 +//line sql.y:1713 { yyLOCAL = []DatabaseOption{yyDollar[1].databaseOption} } yyVAL.union = yyLOCAL - case 230: + case 232: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1709 +//line sql.y:1717 { yySLICE := (*[]DatabaseOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].databaseOption) } - case 231: + case 233: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1713 +//line sql.y:1721 { yySLICE := (*[]DatabaseOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].databaseOption) } - case 232: + case 234: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1717 +//line sql.y:1725 { yySLICE := (*[]DatabaseOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].databaseOption) } - case 233: + case 235: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:1723 +//line sql.y:1731 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 234: + case 236: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:1727 +//line sql.y:1735 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 235: + case 237: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1733 +//line sql.y:1741 { yyVAL.databaseOption = DatabaseOption{Type: CharacterSetType, Value: string(yyDollar[4].str), IsDefault: yyDollar[1].booleanUnion()} } - case 236: + case 238: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1737 +//line sql.y:1745 { yyVAL.databaseOption = DatabaseOption{Type: CharacterSetType, Value: encodeSQLString(yyDollar[4].str), IsDefault: yyDollar[1].booleanUnion()} } - case 237: + case 239: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1743 +//line sql.y:1751 { yyVAL.databaseOption = DatabaseOption{Type: CollateType, Value: string(yyDollar[4].str), IsDefault: yyDollar[1].booleanUnion()} } - case 238: + case 240: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1747 +//line sql.y:1755 { yyVAL.databaseOption = DatabaseOption{Type: CollateType, Value: encodeSQLString(yyDollar[4].str), IsDefault: yyDollar[1].booleanUnion()} } - case 239: + case 241: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1753 +//line sql.y:1761 { yyVAL.databaseOption = DatabaseOption{Type: EncryptionType, Value: string(yyDollar[4].str), IsDefault: yyDollar[1].booleanUnion()} } - case 240: + case 242: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1757 +//line sql.y:1765 { yyVAL.databaseOption = DatabaseOption{Type: EncryptionType, Value: encodeSQLString(yyDollar[4].str), IsDefault: yyDollar[1].booleanUnion()} } - case 241: + case 243: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *OptLike -//line sql.y:1763 +//line sql.y:1771 { yyLOCAL = &OptLike{LikeTable: yyDollar[2].tableName} } yyVAL.union = yyLOCAL - case 242: + case 244: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *OptLike -//line sql.y:1767 +//line sql.y:1775 { yyLOCAL = &OptLike{LikeTable: yyDollar[3].tableName} } yyVAL.union = yyLOCAL - case 243: + case 245: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*ColumnDefinition -//line sql.y:1773 +//line sql.y:1781 { yyLOCAL = []*ColumnDefinition{yyDollar[1].columnDefinitionUnion()} } yyVAL.union = yyLOCAL - case 244: + case 246: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1777 +//line sql.y:1785 { yySLICE := (*[]*ColumnDefinition)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].columnDefinitionUnion()) } - case 245: + case 247: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *TableSpec -//line sql.y:1783 +//line sql.y:1791 { yyLOCAL = &TableSpec{} yyLOCAL.AddColumn(yyDollar[1].columnDefinitionUnion()) } yyVAL.union = yyLOCAL - case 246: + case 248: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *TableSpec -//line sql.y:1788 +//line sql.y:1796 { yyLOCAL = &TableSpec{} yyLOCAL.AddConstraint(yyDollar[1].constraintDefinitionUnion()) } yyVAL.union = yyLOCAL - case 247: + case 249: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1793 +//line sql.y:1801 { yyVAL.tableSpecUnion().AddColumn(yyDollar[3].columnDefinitionUnion()) } - case 248: + case 250: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1797 +//line sql.y:1805 { yyVAL.tableSpecUnion().AddColumn(yyDollar[3].columnDefinitionUnion()) yyVAL.tableSpecUnion().AddConstraint(yyDollar[4].constraintDefinitionUnion()) } - case 249: + case 251: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1802 +//line sql.y:1810 { yyVAL.tableSpecUnion().AddIndex(yyDollar[3].indexDefinitionUnion()) } - case 250: + case 252: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1806 +//line sql.y:1814 { yyVAL.tableSpecUnion().AddConstraint(yyDollar[3].constraintDefinitionUnion()) } - case 251: + case 253: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1810 +//line sql.y:1818 { yyVAL.tableSpecUnion().AddConstraint(yyDollar[3].constraintDefinitionUnion()) } - case 252: + case 254: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ColumnDefinition -//line sql.y:1821 +//line sql.y:1829 { yyDollar[2].columnType.Options = yyDollar[4].columnTypeOptionsUnion() if yyDollar[2].columnType.Options.Collate == "" { @@ -12888,10 +13036,10 @@ yydefault: yyLOCAL = &ColumnDefinition{Name: yyDollar[1].identifierCI, Type: yyDollar[2].columnType} } yyVAL.union = yyLOCAL - case 253: + case 255: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL *ColumnDefinition -//line sql.y:1830 +//line sql.y:1838 { yyDollar[2].columnType.Options = yyDollar[9].columnTypeOptionsUnion() yyDollar[2].columnType.Options.As = yyDollar[7].exprUnion() @@ -12900,389 +13048,373 @@ yydefault: yyLOCAL = &ColumnDefinition{Name: yyDollar[1].identifierCI, Type: yyDollar[2].columnType} } yyVAL.union = yyLOCAL - case 254: + case 256: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1839 +//line sql.y:1847 { yyVAL.str = "" } - case 255: + case 257: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1843 +//line sql.y:1851 { yyVAL.str = "" } - case 256: + case 258: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1852 +//line sql.y:1860 { yyLOCAL = &ColumnTypeOptions{Null: nil, Default: nil, OnUpdate: nil, Autoincrement: false, KeyOpt: ColKeyNone, Comment: nil, As: nil, Invisible: nil, Format: UnspecifiedFormat, EngineAttribute: nil, SecondaryEngineAttribute: nil} } yyVAL.union = yyLOCAL - case 257: + case 259: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1856 +//line sql.y:1864 { yyDollar[1].columnTypeOptionsUnion().Null = ptr.Of(true) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 258: + case 260: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1861 +//line sql.y:1869 { yyDollar[1].columnTypeOptionsUnion().Null = ptr.Of(false) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 259: + case 261: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1866 +//line sql.y:1874 { yyDollar[1].columnTypeOptionsUnion().Default = yyDollar[4].exprUnion() yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 260: + case 262: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1871 +//line sql.y:1879 { yyDollar[1].columnTypeOptionsUnion().Default = yyDollar[3].exprUnion() yyDollar[1].columnTypeOptionsUnion().DefaultLiteral = true yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 261: + case 263: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1877 +//line sql.y:1885 { yyDollar[1].columnTypeOptionsUnion().OnUpdate = yyDollar[4].exprUnion() yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 262: + case 264: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1882 +//line sql.y:1890 { yyDollar[1].columnTypeOptionsUnion().Autoincrement = true yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 263: + case 265: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1887 +//line sql.y:1895 { yyDollar[1].columnTypeOptionsUnion().Comment = NewStrLiteral(yyDollar[3].str) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 264: + case 266: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1892 +//line sql.y:1900 { yyDollar[1].columnTypeOptionsUnion().KeyOpt = yyDollar[2].colKeyOptUnion() yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 265: + case 267: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1897 +//line sql.y:1905 { yyDollar[1].columnTypeOptionsUnion().Collate = encodeSQLString(yyDollar[3].str) } - case 266: + case 268: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1901 +//line sql.y:1909 { yyDollar[1].columnTypeOptionsUnion().Collate = string(yyDollar[3].identifierCI.String()) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 267: + case 269: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1906 +//line sql.y:1914 { yyDollar[1].columnTypeOptionsUnion().Format = yyDollar[3].columnFormatUnion() } - case 268: + case 270: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1910 +//line sql.y:1918 { yyDollar[1].columnTypeOptionsUnion().SRID = NewIntLiteral(yyDollar[3].str) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 269: + case 271: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1915 +//line sql.y:1923 { yyDollar[1].columnTypeOptionsUnion().Invisible = ptr.Of(false) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 270: + case 272: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1920 +//line sql.y:1928 { yyDollar[1].columnTypeOptionsUnion().Invisible = ptr.Of(true) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 271: + case 273: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1925 +//line sql.y:1933 { yyDollar[1].columnTypeOptionsUnion().EngineAttribute = NewStrLiteral(yyDollar[4].str) } - case 272: + case 274: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1929 +//line sql.y:1937 { yyDollar[1].columnTypeOptionsUnion().SecondaryEngineAttribute = NewStrLiteral(yyDollar[4].str) } - case 273: + case 275: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColumnFormat -//line sql.y:1935 +//line sql.y:1943 { yyLOCAL = FixedFormat } yyVAL.union = yyLOCAL - case 274: + case 276: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColumnFormat -//line sql.y:1939 +//line sql.y:1947 { yyLOCAL = DynamicFormat } yyVAL.union = yyLOCAL - case 275: + case 277: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColumnFormat -//line sql.y:1943 +//line sql.y:1951 { yyLOCAL = DefaultFormat } yyVAL.union = yyLOCAL - case 276: + case 278: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColumnFormat -//line sql.y:1947 +//line sql.y:1955 { yyLOCAL = CompressedFormat } yyVAL.union = yyLOCAL - case 277: + case 279: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColumnStorage -//line sql.y:1953 +//line sql.y:1961 { yyLOCAL = VirtualStorage } yyVAL.union = yyLOCAL - case 278: + case 280: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColumnStorage -//line sql.y:1957 +//line sql.y:1965 { yyLOCAL = StoredStorage } yyVAL.union = yyLOCAL - case 279: + case 281: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1962 +//line sql.y:1970 { yyLOCAL = &ColumnTypeOptions{} } yyVAL.union = yyLOCAL - case 280: + case 282: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1966 +//line sql.y:1974 { yyDollar[1].columnTypeOptionsUnion().Storage = yyDollar[2].columnStorageUnion() yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 281: + case 283: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1971 +//line sql.y:1979 { yyDollar[1].columnTypeOptionsUnion().Null = ptr.Of(true) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 282: + case 284: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1976 +//line sql.y:1984 { yyDollar[1].columnTypeOptionsUnion().Null = ptr.Of(false) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 283: + case 285: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1981 +//line sql.y:1989 { yyDollar[1].columnTypeOptionsUnion().Comment = NewStrLiteral(yyDollar[3].str) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 284: + case 286: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1986 +//line sql.y:1994 { yyDollar[1].columnTypeOptionsUnion().KeyOpt = yyDollar[2].colKeyOptUnion() yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 285: + case 287: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1991 +//line sql.y:1999 { yyDollar[1].columnTypeOptionsUnion().SRID = NewIntLiteral(yyDollar[3].str) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 286: + case 288: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:1996 +//line sql.y:2004 { yyDollar[1].columnTypeOptionsUnion().Invisible = ptr.Of(false) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 287: + case 289: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColumnTypeOptions -//line sql.y:2001 +//line sql.y:2009 { yyDollar[1].columnTypeOptionsUnion().Invisible = ptr.Of(true) yyLOCAL = yyDollar[1].columnTypeOptionsUnion() } yyVAL.union = yyLOCAL - case 288: + case 290: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:2008 +//line sql.y:2016 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 290: + case 292: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:2015 +//line sql.y:2023 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("current_timestamp"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL - case 291: + case 293: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:2019 +//line sql.y:2027 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("localtime"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL - case 292: + case 294: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:2023 +//line sql.y:2031 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("localtimestamp"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL - case 293: + case 295: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:2027 +//line sql.y:2035 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("utc_timestamp"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL - case 294: + case 296: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:2031 +//line sql.y:2039 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("now"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL - case 295: + case 297: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:2035 +//line sql.y:2043 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("sysdate"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL - case 298: + case 300: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:2045 +//line sql.y:2053 { yyLOCAL = &NullVal{} } yyVAL.union = yyLOCAL - case 300: + case 302: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:2052 +//line sql.y:2060 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 301: + case 303: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:2056 +//line sql.y:2064 { yyLOCAL = &UnaryExpr{Operator: UMinusOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 302: - yyDollar = yyS[yypt-1 : yypt+1] - var yyLOCAL Expr -//line sql.y:2062 - { - yyLOCAL = yyDollar[1].exprUnion() - } - yyVAL.union = yyLOCAL - case 303: - yyDollar = yyS[yypt-1 : yypt+1] - var yyLOCAL Expr -//line sql.y:2066 - { - yyLOCAL = yyDollar[1].exprUnion() - } - yyVAL.union = yyLOCAL case 304: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr //line sql.y:2070 { - yyLOCAL = yyDollar[1].boolValUnion() + yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL case 305: @@ -13290,7 +13422,7 @@ yydefault: var yyLOCAL Expr //line sql.y:2074 { - yyLOCAL = NewHexLiteral(yyDollar[1].str) + yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL case 306: @@ -13298,7 +13430,7 @@ yydefault: var yyLOCAL Expr //line sql.y:2078 { - yyLOCAL = NewHexNumLiteral(yyDollar[1].str) + yyLOCAL = yyDollar[1].boolValUnion() } yyVAL.union = yyLOCAL case 307: @@ -13306,7 +13438,7 @@ yydefault: var yyLOCAL Expr //line sql.y:2082 { - yyLOCAL = NewBitLiteral(yyDollar[1].str) + yyLOCAL = NewHexLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL case 308: @@ -13314,7 +13446,7 @@ yydefault: var yyLOCAL Expr //line sql.y:2086 { - yyLOCAL = NewBitLiteral("0b" + yyDollar[1].str) + yyLOCAL = NewHexNumLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL case 309: @@ -13322,23 +13454,23 @@ yydefault: var yyLOCAL Expr //line sql.y:2090 { - yyLOCAL = parseBindVariable(yylex, yyDollar[1].str[1:]) + yyLOCAL = NewBitLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL case 310: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr //line sql.y:2094 { - yyLOCAL = &IntroducerExpr{CharacterSet: yyDollar[1].str, Expr: NewBitLiteral("0b" + yyDollar[2].str)} + yyLOCAL = NewBitLiteral("0b" + yyDollar[1].str) } yyVAL.union = yyLOCAL case 311: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr //line sql.y:2098 { - yyLOCAL = &IntroducerExpr{CharacterSet: yyDollar[1].str, Expr: NewHexNumLiteral(yyDollar[2].str)} + yyLOCAL = parseBindVariable(yylex, yyDollar[1].str[1:]) } yyVAL.union = yyLOCAL case 312: @@ -13346,7 +13478,7 @@ yydefault: var yyLOCAL Expr //line sql.y:2102 { - yyLOCAL = &IntroducerExpr{CharacterSet: yyDollar[1].str, Expr: NewBitLiteral(yyDollar[2].str)} + yyLOCAL = &IntroducerExpr{CharacterSet: yyDollar[1].str, Expr: NewBitLiteral("0b" + yyDollar[2].str)} } yyVAL.union = yyLOCAL case 313: @@ -13354,7 +13486,7 @@ yydefault: var yyLOCAL Expr //line sql.y:2106 { - yyLOCAL = &IntroducerExpr{CharacterSet: yyDollar[1].str, Expr: NewHexLiteral(yyDollar[2].str)} + yyLOCAL = &IntroducerExpr{CharacterSet: yyDollar[1].str, Expr: NewHexNumLiteral(yyDollar[2].str)} } yyVAL.union = yyLOCAL case 314: @@ -13362,24 +13494,24 @@ yydefault: var yyLOCAL Expr //line sql.y:2110 { - arg := parseBindVariable(yylex, yyDollar[2].str[1:]) - yyLOCAL = &IntroducerExpr{CharacterSet: yyDollar[1].str, Expr: arg} + yyLOCAL = &IntroducerExpr{CharacterSet: yyDollar[1].str, Expr: NewBitLiteral(yyDollar[2].str)} } yyVAL.union = yyLOCAL case 315: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:2115 +//line sql.y:2114 { - yyLOCAL = NewDateLiteral(yyDollar[2].str) + yyLOCAL = &IntroducerExpr{CharacterSet: yyDollar[1].str, Expr: NewHexLiteral(yyDollar[2].str)} } yyVAL.union = yyLOCAL case 316: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:2119 +//line sql.y:2118 { - yyLOCAL = NewTimeLiteral(yyDollar[2].str) + arg := parseBindVariable(yylex, yyDollar[2].str[1:]) + yyLOCAL = &IntroducerExpr{CharacterSet: yyDollar[1].str, Expr: arg} } yyVAL.union = yyLOCAL case 317: @@ -13387,254 +13519,258 @@ yydefault: var yyLOCAL Expr //line sql.y:2123 { - yyLOCAL = NewTimestampLiteral(yyDollar[2].str) + yyLOCAL = NewDateLiteral(yyDollar[2].str) } yyVAL.union = yyLOCAL case 318: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2129 + yyDollar = yyS[yypt-2 : yypt+1] + var yyLOCAL Expr +//line sql.y:2127 { - yyVAL.str = Armscii8Str + yyLOCAL = NewTimeLiteral(yyDollar[2].str) } + yyVAL.union = yyLOCAL case 319: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2133 + yyDollar = yyS[yypt-2 : yypt+1] + var yyLOCAL Expr +//line sql.y:2131 { - yyVAL.str = ASCIIStr + yyLOCAL = NewTimestampLiteral(yyDollar[2].str) } + yyVAL.union = yyLOCAL case 320: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2137 { - yyVAL.str = Big5Str + yyVAL.str = Armscii8Str } case 321: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2141 { - yyVAL.str = UBinaryStr + yyVAL.str = ASCIIStr } case 322: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2145 { - yyVAL.str = Cp1250Str + yyVAL.str = Big5Str } case 323: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2149 { - yyVAL.str = Cp1251Str + yyVAL.str = UBinaryStr } case 324: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2153 { - yyVAL.str = Cp1256Str + yyVAL.str = Cp1250Str } case 325: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2157 { - yyVAL.str = Cp1257Str + yyVAL.str = Cp1251Str } case 326: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2161 { - yyVAL.str = Cp850Str + yyVAL.str = Cp1256Str } case 327: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2165 { - yyVAL.str = Cp852Str + yyVAL.str = Cp1257Str } case 328: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2169 { - yyVAL.str = Cp866Str + yyVAL.str = Cp850Str } case 329: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2173 { - yyVAL.str = Cp932Str + yyVAL.str = Cp852Str } case 330: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2177 { - yyVAL.str = Dec8Str + yyVAL.str = Cp866Str } case 331: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2181 { - yyVAL.str = EucjpmsStr + yyVAL.str = Cp932Str } case 332: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2185 { - yyVAL.str = EuckrStr + yyVAL.str = Dec8Str } case 333: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2189 { - yyVAL.str = Gb18030Str + yyVAL.str = EucjpmsStr } case 334: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2193 { - yyVAL.str = Gb2312Str + yyVAL.str = EuckrStr } case 335: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2197 { - yyVAL.str = GbkStr + yyVAL.str = Gb18030Str } case 336: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2201 { - yyVAL.str = Geostd8Str + yyVAL.str = Gb2312Str } case 337: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2205 { - yyVAL.str = GreekStr + yyVAL.str = GbkStr } case 338: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2209 { - yyVAL.str = HebrewStr + yyVAL.str = Geostd8Str } case 339: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2213 { - yyVAL.str = Hp8Str + yyVAL.str = GreekStr } case 340: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2217 { - yyVAL.str = Keybcs2Str + yyVAL.str = HebrewStr } case 341: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2221 { - yyVAL.str = Koi8rStr + yyVAL.str = Hp8Str } case 342: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2225 { - yyVAL.str = Koi8uStr + yyVAL.str = Keybcs2Str } case 343: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2229 { - yyVAL.str = Latin1Str + yyVAL.str = Koi8rStr } case 344: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2233 { - yyVAL.str = Latin2Str + yyVAL.str = Koi8uStr } case 345: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2237 { - yyVAL.str = Latin5Str + yyVAL.str = Latin1Str } case 346: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2241 { - yyVAL.str = Latin7Str + yyVAL.str = Latin2Str } case 347: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2245 { - yyVAL.str = MacceStr + yyVAL.str = Latin5Str } case 348: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2249 { - yyVAL.str = MacromanStr + yyVAL.str = Latin7Str } case 349: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2253 { - yyVAL.str = SjisStr + yyVAL.str = MacceStr } case 350: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2257 { - yyVAL.str = Swe7Str + yyVAL.str = MacromanStr } case 351: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2261 { - yyVAL.str = Tis620Str + yyVAL.str = SjisStr } case 352: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2265 { - yyVAL.str = Ucs2Str + yyVAL.str = Swe7Str } case 353: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2269 { - yyVAL.str = UjisStr + yyVAL.str = Tis620Str } case 354: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2273 { - yyVAL.str = Utf16Str + yyVAL.str = Ucs2Str } case 355: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2277 { - yyVAL.str = Utf16leStr + yyVAL.str = UjisStr } case 356: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2281 { - yyVAL.str = Utf32Str + yyVAL.str = Utf16Str } case 357: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2285 { - yyVAL.str = Utf8mb3Str + yyVAL.str = Utf16leStr } case 358: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2289 { - yyVAL.str = Utf8mb4Str + yyVAL.str = Utf32Str } case 359: yyDollar = yyS[yypt-1 : yypt+1] @@ -13642,150 +13778,150 @@ yydefault: { yyVAL.str = Utf8mb3Str } - case 362: + case 360: + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:2297 + { + yyVAL.str = Utf8mb4Str + } + case 361: + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:2301 + { + yyVAL.str = Utf8mb3Str + } + case 364: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:2303 +//line sql.y:2311 { yyLOCAL = NewIntLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 363: + case 365: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:2307 +//line sql.y:2315 { yyLOCAL = NewFloatLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 364: + case 366: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:2311 +//line sql.y:2319 { yyLOCAL = NewDecimalLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 365: + case 367: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:2317 +//line sql.y:2325 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 366: + case 368: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:2321 +//line sql.y:2329 { yyLOCAL = AppendString(yyDollar[1].exprUnion(), yyDollar[2].str) } yyVAL.union = yyLOCAL - case 367: + case 369: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:2327 +//line sql.y:2335 { yyLOCAL = NewStrLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 368: + case 370: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:2331 +//line sql.y:2339 { yyLOCAL = &UnaryExpr{Operator: NStringOp, Expr: NewStrLiteral(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 369: + case 371: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:2335 +//line sql.y:2343 { yyLOCAL = &IntroducerExpr{CharacterSet: yyDollar[1].str, Expr: NewStrLiteral(yyDollar[2].str)} } yyVAL.union = yyLOCAL - case 370: + case 372: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:2341 +//line sql.y:2349 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 371: + case 373: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:2345 +//line sql.y:2353 { yyLOCAL = parseBindVariable(yylex, yyDollar[1].str[1:]) } yyVAL.union = yyLOCAL - case 372: + case 374: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL ColumnKeyOption -//line sql.y:2351 +//line sql.y:2359 { yyLOCAL = ColKeyPrimary } yyVAL.union = yyLOCAL - case 373: + case 375: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColumnKeyOption -//line sql.y:2355 +//line sql.y:2363 { yyLOCAL = ColKeyUnique } yyVAL.union = yyLOCAL - case 374: + case 376: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL ColumnKeyOption -//line sql.y:2359 +//line sql.y:2367 { yyLOCAL = ColKeyUniqueKey } yyVAL.union = yyLOCAL - case 375: + case 377: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColumnKeyOption -//line sql.y:2363 +//line sql.y:2371 { yyLOCAL = ColKey } yyVAL.union = yyLOCAL - case 376: + case 378: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2369 +//line sql.y:2377 { yyVAL.columnType = yyDollar[1].columnType yyVAL.columnType.Unsigned = yyDollar[2].booleanUnion() yyVAL.columnType.Zerofill = yyDollar[3].booleanUnion() } - case 380: - yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2380 - { - yyVAL.columnType = yyDollar[1].columnType - yyVAL.columnType.Length = yyDollar[2].intPtrUnion() - } - case 381: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2385 - { - yyVAL.columnType = yyDollar[1].columnType - } case 382: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2391 + yyDollar = yyS[yypt-2 : yypt+1] +//line sql.y:2388 { - yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} + yyVAL.columnType = yyDollar[1].columnType + yyVAL.columnType.Length = yyDollar[2].intPtrUnion() } case 383: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2395 +//line sql.y:2393 { - yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} + yyVAL.columnType = yyDollar[1].columnType } case 384: yyDollar = yyS[yypt-1 : yypt+1] @@ -13830,24 +13966,20 @@ yydefault: yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 391: - yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2429 + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:2427 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} - yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length - yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale } case 392: - yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2435 + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:2431 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} - yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length - yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale } case 393: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2441 +//line sql.y:2437 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -13855,7 +13987,7 @@ yydefault: } case 394: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2447 +//line sql.y:2443 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -13863,7 +13995,7 @@ yydefault: } case 395: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2453 +//line sql.y:2449 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -13871,7 +14003,7 @@ yydefault: } case 396: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2459 +//line sql.y:2455 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -13879,29 +14011,33 @@ yydefault: } case 397: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2465 +//line sql.y:2461 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale } case 398: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2473 + yyDollar = yyS[yypt-2 : yypt+1] +//line sql.y:2467 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} + yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length + yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale } case 399: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2477 +//line sql.y:2473 { - yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} + yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} + yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length + yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale } case 400: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2481 { - yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} + yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 401: yyDollar = yyS[yypt-2 : yypt+1] @@ -13916,54 +14052,54 @@ yydefault: yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } case 403: - yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2495 + yyDollar = yyS[yypt-2 : yypt+1] +//line sql.y:2493 { - yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion(), Charset: yyDollar[3].columnCharset} + yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } case 404: - yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2499 + yyDollar = yyS[yypt-2 : yypt+1] +//line sql.y:2497 { - // CHAR BYTE is an alias for binary. See also: - // https://dev.mysql.com/doc/refman/8.0/en/string-type-syntax.html - yyVAL.columnType = &ColumnType{Type: "binary", Length: yyDollar[2].intPtrUnion()} + yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } case 405: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2505 +//line sql.y:2503 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion(), Charset: yyDollar[3].columnCharset} } case 406: - yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2509 + yyDollar = yyS[yypt-3 : yypt+1] +//line sql.y:2507 { - yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} + // CHAR BYTE is an alias for binary. See also: + // https://dev.mysql.com/doc/refman/8.0/en/string-type-syntax.html + yyVAL.columnType = &ColumnType{Type: "binary", Length: yyDollar[2].intPtrUnion()} } case 407: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:2513 { - yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} + yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion(), Charset: yyDollar[3].columnCharset} } case 408: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:2517 { - yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion(), Charset: yyDollar[3].columnCharset} + yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } case 409: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:2521 { - yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Charset: yyDollar[2].columnCharset} + yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } case 410: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:2525 { - yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Charset: yyDollar[2].columnCharset} + yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion(), Charset: yyDollar[3].columnCharset} } case 411: yyDollar = yyS[yypt-2 : yypt+1] @@ -13975,19 +14111,19 @@ yydefault: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:2533 { - yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} + yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Charset: yyDollar[2].columnCharset} } case 413: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:2537 { - yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} + yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Charset: yyDollar[2].columnCharset} } case 414: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:2541 { - yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} + yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } case 415: yyDollar = yyS[yypt-1 : yypt+1] @@ -14002,34 +14138,34 @@ yydefault: yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 417: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2553 { - yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), EnumValues: yyDollar[3].strs, Charset: yyDollar[5].columnCharset} + yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 418: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2557 { - yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} + yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} } case 419: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2562 +//line sql.y:2561 { yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), EnumValues: yyDollar[3].strs, Charset: yyDollar[5].columnCharset} } case 420: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2568 + yyDollar = yyS[yypt-2 : yypt+1] +//line sql.y:2565 { - yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} + yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } case 421: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2572 + yyDollar = yyS[yypt-5 : yypt+1] +//line sql.y:2570 { - yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} + yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str), EnumValues: yyDollar[3].strs, Charset: yyDollar[5].columnCharset} } case 422: yyDollar = yyS[yypt-1 : yypt+1] @@ -14069,810 +14205,806 @@ yydefault: } case 428: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2602 +//line sql.y:2600 + { + yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} + } + case 429: + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:2604 + { + yyVAL.columnType = &ColumnType{Type: string(yyDollar[1].str)} + } + case 430: + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:2610 { yyVAL.strs = make([]string, 0, 4) yyVAL.strs = append(yyVAL.strs, encodeSQLString(yyDollar[1].str)) } - case 429: + case 431: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2607 +//line sql.y:2615 { yyVAL.strs = append(yyDollar[1].strs, encodeSQLString(yyDollar[3].str)) } - case 430: + case 432: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *int -//line sql.y:2612 +//line sql.y:2620 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 431: + case 433: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *int -//line sql.y:2616 +//line sql.y:2624 { yyLOCAL = ptr.Of(convertStringToInt(yyDollar[2].str)) } yyVAL.union = yyLOCAL - case 432: + case 434: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2621 +//line sql.y:2629 { yyVAL.LengthScaleOption = LengthScaleOption{} } - case 433: + case 435: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2625 +//line sql.y:2633 { yyVAL.LengthScaleOption = LengthScaleOption{ Length: ptr.Of(convertStringToInt(yyDollar[2].str)), Scale: ptr.Of(convertStringToInt(yyDollar[4].str)), } } - case 434: + case 436: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2634 +//line sql.y:2642 { yyVAL.LengthScaleOption = yyDollar[1].LengthScaleOption } - case 435: + case 437: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2638 +//line sql.y:2646 { yyVAL.LengthScaleOption = LengthScaleOption{ Length: ptr.Of(convertStringToInt(yyDollar[2].str)), } } - case 436: + case 438: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2645 +//line sql.y:2653 { yyVAL.LengthScaleOption = LengthScaleOption{} } - case 437: + case 439: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2649 +//line sql.y:2657 { yyVAL.LengthScaleOption = LengthScaleOption{ Length: ptr.Of(convertStringToInt(yyDollar[2].str)), } } - case 438: + case 440: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2655 +//line sql.y:2663 { yyVAL.LengthScaleOption = LengthScaleOption{ Length: ptr.Of(convertStringToInt(yyDollar[2].str)), Scale: ptr.Of(convertStringToInt(yyDollar[4].str)), } } - case 439: + case 441: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:2663 +//line sql.y:2671 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 440: + case 442: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:2667 +//line sql.y:2675 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 441: + case 443: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:2671 +//line sql.y:2679 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 442: + case 444: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:2676 +//line sql.y:2684 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 443: + case 445: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:2680 +//line sql.y:2688 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 444: + case 446: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2685 +//line sql.y:2693 { yyVAL.columnCharset = ColumnCharset{} } - case 445: + case 447: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2689 +//line sql.y:2697 { yyVAL.columnCharset = ColumnCharset{Name: string(yyDollar[2].identifierCI.String()), Binary: yyDollar[3].booleanUnion()} } - case 446: + case 448: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2693 +//line sql.y:2701 { yyVAL.columnCharset = ColumnCharset{Name: encodeSQLString(yyDollar[2].str), Binary: yyDollar[3].booleanUnion()} } - case 447: + case 449: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2697 +//line sql.y:2705 { yyVAL.columnCharset = ColumnCharset{Name: string(yyDollar[2].str)} } - case 448: + case 450: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2701 +//line sql.y:2709 { // ASCII: Shorthand for CHARACTER SET latin1. yyVAL.columnCharset = ColumnCharset{Name: "latin1", Binary: yyDollar[2].booleanUnion()} } - case 449: + case 451: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2706 +//line sql.y:2714 { // UNICODE: Shorthand for CHARACTER SET ucs2. yyVAL.columnCharset = ColumnCharset{Name: "ucs2", Binary: yyDollar[2].booleanUnion()} } - case 450: + case 452: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2711 +//line sql.y:2719 { // BINARY: Shorthand for default CHARACTER SET but with binary collation yyVAL.columnCharset = ColumnCharset{Name: "", Binary: true} } - case 451: + case 453: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2716 +//line sql.y:2724 { // BINARY ASCII: Shorthand for CHARACTER SET latin1 with binary collation yyVAL.columnCharset = ColumnCharset{Name: "latin1", Binary: true} } - case 452: + case 454: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2721 +//line sql.y:2729 { // BINARY UNICODE: Shorthand for CHARACTER SET ucs2 with binary collation yyVAL.columnCharset = ColumnCharset{Name: "ucs2", Binary: true} } - case 453: + case 455: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:2727 +//line sql.y:2735 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 454: + case 456: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:2731 +//line sql.y:2739 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 455: + case 457: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2736 +//line sql.y:2744 { yyVAL.str = "" } - case 456: + case 458: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2740 +//line sql.y:2748 { yyVAL.str = string(yyDollar[2].identifierCI.String()) } - case 457: + case 459: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2744 +//line sql.y:2752 { yyVAL.str = encodeSQLString(yyDollar[2].str) } - case 458: + case 460: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *IndexDefinition -//line sql.y:2750 +//line sql.y:2758 { yyLOCAL = &IndexDefinition{Info: yyDollar[1].indexInfoUnion(), Columns: yyDollar[3].indexColumnsUnion(), Options: yyDollar[5].indexOptionsUnion()} } yyVAL.union = yyLOCAL - case 459: + case 461: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:2755 +//line sql.y:2763 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 460: + case 462: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:2759 +//line sql.y:2767 { yyLOCAL = yyDollar[1].indexOptionsUnion() } yyVAL.union = yyLOCAL - case 461: + case 463: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:2765 +//line sql.y:2773 { yyLOCAL = []*IndexOption{yyDollar[1].indexOptionUnion()} } yyVAL.union = yyLOCAL - case 462: + case 464: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2769 +//line sql.y:2777 { yySLICE := (*[]*IndexOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].indexOptionUnion()) } - case 463: + case 465: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:2775 +//line sql.y:2783 { yyLOCAL = yyDollar[1].indexOptionUnion() } yyVAL.union = yyLOCAL - case 464: + case 466: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:2779 +//line sql.y:2787 { // should not be string yyLOCAL = &IndexOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 465: + case 467: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:2784 +//line sql.y:2792 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[2].str)} } yyVAL.union = yyLOCAL - case 466: + case 468: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:2788 +//line sql.y:2796 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 467: + case 469: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:2792 +//line sql.y:2800 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 468: + case 470: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:2796 +//line sql.y:2804 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str) + " " + string(yyDollar[2].str), String: yyDollar[3].identifierCI.String()} } yyVAL.union = yyLOCAL - case 469: + case 471: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:2800 +//line sql.y:2808 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 470: + case 472: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:2804 +//line sql.y:2812 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 471: + case 473: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2810 +//line sql.y:2818 { yyVAL.str = "" } - case 472: + case 474: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2814 +//line sql.y:2822 { yyVAL.str = string(yyDollar[1].str) } - case 473: + case 475: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *IndexInfo -//line sql.y:2820 +//line sql.y:2828 { yyLOCAL = &IndexInfo{Type: IndexTypePrimary, ConstraintName: NewIdentifierCI(yyDollar[1].str), Name: NewIdentifierCI("PRIMARY")} } yyVAL.union = yyLOCAL - case 474: + case 476: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *IndexInfo -//line sql.y:2824 +//line sql.y:2832 { yyLOCAL = &IndexInfo{Type: IndexTypeSpatial, Name: NewIdentifierCI(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 475: + case 477: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *IndexInfo -//line sql.y:2828 +//line sql.y:2836 { yyLOCAL = &IndexInfo{Type: IndexTypeFullText, Name: NewIdentifierCI(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 476: + case 478: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *IndexInfo -//line sql.y:2832 +//line sql.y:2840 { yyLOCAL = &IndexInfo{Type: IndexTypeUnique, ConstraintName: NewIdentifierCI(yyDollar[1].str), Name: NewIdentifierCI(yyDollar[4].str)} } yyVAL.union = yyLOCAL - case 477: + case 479: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *IndexInfo -//line sql.y:2836 +//line sql.y:2844 { yyLOCAL = &IndexInfo{Type: IndexTypeDefault, Name: NewIdentifierCI(yyDollar[2].str)} } yyVAL.union = yyLOCAL - case 478: + case 480: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2841 +//line sql.y:2849 { yyVAL.str = "" } - case 479: + case 481: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2845 +//line sql.y:2853 { yyVAL.str = yyDollar[2].str } - case 480: + case 482: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2851 +//line sql.y:2859 { yyVAL.str = string(yyDollar[1].str) } - case 481: + case 483: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2855 +//line sql.y:2863 { yyVAL.str = string(yyDollar[1].str) } - case 482: + case 484: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2859 +//line sql.y:2867 { yyVAL.str = string(yyDollar[1].str) } - case 483: + case 485: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2865 +//line sql.y:2873 { yyVAL.str = string(yyDollar[1].str) } - case 484: + case 486: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2869 +//line sql.y:2877 { yyVAL.str = string(yyDollar[1].str) } - case 485: + case 487: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2874 +//line sql.y:2882 { yyVAL.str = "" } - case 486: + case 488: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2878 +//line sql.y:2886 { yyVAL.str = yyDollar[1].str } - case 487: + case 489: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2884 +//line sql.y:2892 { yyVAL.str = string(yyDollar[1].str) } - case 488: + case 490: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2888 +//line sql.y:2896 { yyVAL.str = string(yyDollar[1].str) } - case 489: + case 491: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2893 +//line sql.y:2901 { yyVAL.str = "" } - case 490: + case 492: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2897 +//line sql.y:2905 { yyVAL.str = string(yyDollar[1].identifierCI.String()) } - case 491: + case 493: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*IndexColumn -//line sql.y:2903 +//line sql.y:2911 { yyLOCAL = []*IndexColumn{yyDollar[1].indexColumnUnion()} } yyVAL.union = yyLOCAL - case 492: + case 494: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2907 +//line sql.y:2915 { yySLICE := (*[]*IndexColumn)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].indexColumnUnion()) } - case 493: + case 495: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *IndexColumn -//line sql.y:2913 +//line sql.y:2921 { yyLOCAL = &IndexColumn{Column: yyDollar[1].identifierCI, Length: yyDollar[2].intPtrUnion(), Direction: yyDollar[3].orderDirectionUnion()} } yyVAL.union = yyLOCAL - case 494: + case 496: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *IndexColumn -//line sql.y:2917 +//line sql.y:2925 { yyLOCAL = &IndexColumn{Expression: yyDollar[2].exprUnion(), Direction: yyDollar[4].orderDirectionUnion()} } yyVAL.union = yyLOCAL - case 495: + case 497: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ConstraintDefinition -//line sql.y:2923 +//line sql.y:2931 { yyLOCAL = &ConstraintDefinition{Name: yyDollar[2].identifierCI, Details: yyDollar[3].constraintInfoUnion()} } yyVAL.union = yyLOCAL - case 496: + case 498: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConstraintDefinition -//line sql.y:2927 +//line sql.y:2935 { yyLOCAL = &ConstraintDefinition{Details: yyDollar[1].constraintInfoUnion()} } yyVAL.union = yyLOCAL - case 497: + case 499: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ConstraintDefinition -//line sql.y:2933 +//line sql.y:2941 { yyLOCAL = &ConstraintDefinition{Name: yyDollar[2].identifierCI, Details: yyDollar[3].constraintInfoUnion()} } yyVAL.union = yyLOCAL - case 498: + case 500: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConstraintDefinition -//line sql.y:2937 +//line sql.y:2945 { yyLOCAL = &ConstraintDefinition{Details: yyDollar[1].constraintInfoUnion()} } yyVAL.union = yyLOCAL - case 499: + case 501: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL ConstraintInfo -//line sql.y:2943 +//line sql.y:2951 { yyLOCAL = &ForeignKeyDefinition{IndexName: NewIdentifierCI(yyDollar[3].str), Source: yyDollar[5].columnsUnion(), ReferenceDefinition: yyDollar[7].referenceDefinitionUnion()} } yyVAL.union = yyLOCAL - case 500: + case 502: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *ReferenceDefinition -//line sql.y:2949 +//line sql.y:2957 { yyLOCAL = &ReferenceDefinition{ReferencedTable: yyDollar[2].tableName, ReferencedColumns: yyDollar[4].columnsUnion(), Match: yyDollar[6].matchActionUnion()} } yyVAL.union = yyLOCAL - case 501: + case 503: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *ReferenceDefinition -//line sql.y:2953 +//line sql.y:2961 { yyLOCAL = &ReferenceDefinition{ReferencedTable: yyDollar[2].tableName, ReferencedColumns: yyDollar[4].columnsUnion(), Match: yyDollar[6].matchActionUnion(), OnDelete: yyDollar[7].referenceActionUnion()} } yyVAL.union = yyLOCAL - case 502: + case 504: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *ReferenceDefinition -//line sql.y:2957 +//line sql.y:2965 { yyLOCAL = &ReferenceDefinition{ReferencedTable: yyDollar[2].tableName, ReferencedColumns: yyDollar[4].columnsUnion(), Match: yyDollar[6].matchActionUnion(), OnUpdate: yyDollar[7].referenceActionUnion()} } yyVAL.union = yyLOCAL - case 503: + case 505: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *ReferenceDefinition -//line sql.y:2961 +//line sql.y:2969 { yyLOCAL = &ReferenceDefinition{ReferencedTable: yyDollar[2].tableName, ReferencedColumns: yyDollar[4].columnsUnion(), Match: yyDollar[6].matchActionUnion(), OnDelete: yyDollar[7].referenceActionUnion(), OnUpdate: yyDollar[8].referenceActionUnion()} } yyVAL.union = yyLOCAL - case 504: + case 506: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *ReferenceDefinition -//line sql.y:2965 +//line sql.y:2973 { yyLOCAL = &ReferenceDefinition{ReferencedTable: yyDollar[2].tableName, ReferencedColumns: yyDollar[4].columnsUnion(), Match: yyDollar[6].matchActionUnion(), OnUpdate: yyDollar[7].referenceActionUnion(), OnDelete: yyDollar[8].referenceActionUnion()} } yyVAL.union = yyLOCAL - case 505: + case 507: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ReferenceDefinition -//line sql.y:2970 +//line sql.y:2978 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 506: + case 508: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ReferenceDefinition -//line sql.y:2974 +//line sql.y:2982 { yyLOCAL = yyDollar[1].referenceDefinitionUnion() } yyVAL.union = yyLOCAL - case 507: + case 509: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL ConstraintInfo -//line sql.y:2980 +//line sql.y:2988 { yyLOCAL = &CheckConstraintDefinition{Expr: yyDollar[3].exprUnion(), Enforced: yyDollar[5].booleanUnion()} } yyVAL.union = yyLOCAL - case 508: + case 510: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL MatchAction -//line sql.y:2986 +//line sql.y:2994 { yyLOCAL = yyDollar[2].matchActionUnion() } yyVAL.union = yyLOCAL - case 509: + case 511: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL MatchAction -//line sql.y:2992 +//line sql.y:3000 { yyLOCAL = Full } yyVAL.union = yyLOCAL - case 510: + case 512: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL MatchAction -//line sql.y:2996 +//line sql.y:3004 { yyLOCAL = Partial } yyVAL.union = yyLOCAL - case 511: + case 513: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL MatchAction -//line sql.y:3000 +//line sql.y:3008 { yyLOCAL = Simple } yyVAL.union = yyLOCAL - case 512: + case 514: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL MatchAction -//line sql.y:3005 +//line sql.y:3013 { yyLOCAL = DefaultMatch } yyVAL.union = yyLOCAL - case 513: + case 515: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL MatchAction -//line sql.y:3009 +//line sql.y:3017 { yyLOCAL = yyDollar[1].matchActionUnion() } yyVAL.union = yyLOCAL - case 514: + case 516: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ReferenceAction -//line sql.y:3015 +//line sql.y:3023 { yyLOCAL = yyDollar[3].referenceActionUnion() } yyVAL.union = yyLOCAL - case 515: + case 517: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ReferenceAction -//line sql.y:3021 +//line sql.y:3029 { yyLOCAL = yyDollar[3].referenceActionUnion() } yyVAL.union = yyLOCAL - case 516: + case 518: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ReferenceAction -//line sql.y:3027 +//line sql.y:3035 { yyLOCAL = Restrict } yyVAL.union = yyLOCAL - case 517: + case 519: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ReferenceAction -//line sql.y:3031 +//line sql.y:3039 { yyLOCAL = Cascade } yyVAL.union = yyLOCAL - case 518: + case 520: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL ReferenceAction -//line sql.y:3035 +//line sql.y:3043 { yyLOCAL = NoAction } yyVAL.union = yyLOCAL - case 519: + case 521: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL ReferenceAction -//line sql.y:3039 +//line sql.y:3047 { yyLOCAL = SetDefault } yyVAL.union = yyLOCAL - case 520: + case 522: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL ReferenceAction -//line sql.y:3043 +//line sql.y:3051 { yyLOCAL = SetNull } yyVAL.union = yyLOCAL - case 521: + case 523: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3048 +//line sql.y:3056 { yyVAL.str = "" } - case 522: + case 524: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3052 +//line sql.y:3060 { yyVAL.str = string(yyDollar[1].str) } - case 523: + case 525: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3056 +//line sql.y:3064 { yyVAL.str = string(yyDollar[1].str) } - case 524: + case 526: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:3062 +//line sql.y:3070 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 525: + case 527: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:3066 +//line sql.y:3074 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 526: + case 528: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:3071 +//line sql.y:3079 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 527: + case 529: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:3075 +//line sql.y:3083 { yyLOCAL = yyDollar[1].booleanUnion() } yyVAL.union = yyLOCAL - case 528: + case 530: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL TableOptions -//line sql.y:3080 +//line sql.y:3088 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 529: + case 531: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableOptions -//line sql.y:3084 +//line sql.y:3092 { yyLOCAL = yyDollar[1].tableOptionsUnion() } yyVAL.union = yyLOCAL - case 530: + case 532: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableOptions -//line sql.y:3090 +//line sql.y:3098 { yyLOCAL = TableOptions{yyDollar[1].tableOptionUnion()} } yyVAL.union = yyLOCAL - case 531: + case 533: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3094 +//line sql.y:3102 { yySLICE := (*TableOptions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableOptionUnion()) } - case 532: + case 534: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3098 +//line sql.y:3106 { yySLICE := (*TableOptions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].tableOptionUnion()) } - case 533: + case 535: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableOptions -//line sql.y:3104 +//line sql.y:3112 { yyLOCAL = TableOptions{yyDollar[1].tableOptionUnion()} } yyVAL.union = yyLOCAL - case 534: + case 536: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3108 +//line sql.y:3116 { yySLICE := (*TableOptions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].tableOptionUnion()) } - case 535: - yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL *TableOption -//line sql.y:3114 - { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} - } - yyVAL.union = yyLOCAL - case 536: - yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL *TableOption -//line sql.y:3118 - { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} - } - yyVAL.union = yyLOCAL case 537: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption @@ -14882,35 +15014,35 @@ yydefault: } yyVAL.union = yyLOCAL case 538: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption //line sql.y:3126 { - yyLOCAL = &TableOption{Name: (string(yyDollar[2].str)), String: yyDollar[4].str, CaseSensitive: true} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 539: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption //line sql.y:3130 { - yyLOCAL = &TableOption{Name: string(yyDollar[2].str), String: yyDollar[4].str, CaseSensitive: true} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 540: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *TableOption //line sql.y:3134 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} + yyLOCAL = &TableOption{Name: (string(yyDollar[2].str)), String: yyDollar[4].str, CaseSensitive: true} } yyVAL.union = yyLOCAL case 541: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *TableOption //line sql.y:3138 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} + yyLOCAL = &TableOption{Name: string(yyDollar[2].str), String: yyDollar[4].str, CaseSensitive: true} } yyVAL.union = yyLOCAL case 542: @@ -14918,7 +15050,7 @@ yydefault: var yyLOCAL *TableOption //line sql.y:3142 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 543: @@ -14930,35 +15062,35 @@ yydefault: } yyVAL.union = yyLOCAL case 544: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption //line sql.y:3150 { - yyLOCAL = &TableOption{Name: (string(yyDollar[1].str) + " " + string(yyDollar[2].str)), Value: NewStrLiteral(yyDollar[4].str)} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 545: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption //line sql.y:3154 { - yyLOCAL = &TableOption{Name: (string(yyDollar[1].str) + " " + string(yyDollar[2].str)), Value: NewStrLiteral(yyDollar[4].str)} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 546: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *TableOption //line sql.y:3158 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} + yyLOCAL = &TableOption{Name: (string(yyDollar[1].str) + " " + string(yyDollar[2].str)), Value: NewStrLiteral(yyDollar[4].str)} } yyVAL.union = yyLOCAL case 547: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *TableOption //line sql.y:3162 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} + yyLOCAL = &TableOption{Name: (string(yyDollar[1].str) + " " + string(yyDollar[2].str)), Value: NewStrLiteral(yyDollar[4].str)} } yyVAL.union = yyLOCAL case 548: @@ -14966,7 +15098,7 @@ yydefault: var yyLOCAL *TableOption //line sql.y:3166 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: yyDollar[3].identifierCS.String(), CaseSensitive: true} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 549: @@ -14982,7 +15114,7 @@ yydefault: var yyLOCAL *TableOption //line sql.y:3174 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: yyDollar[3].identifierCS.String(), CaseSensitive: true} } yyVAL.union = yyLOCAL case 551: @@ -14990,7 +15122,7 @@ yydefault: var yyLOCAL *TableOption //line sql.y:3178 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 552: @@ -14998,7 +15130,7 @@ yydefault: var yyLOCAL *TableOption //line sql.y:3182 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 553: @@ -15022,7 +15154,7 @@ yydefault: var yyLOCAL *TableOption //line sql.y:3194 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 556: @@ -15030,7 +15162,7 @@ yydefault: var yyLOCAL *TableOption //line sql.y:3198 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 557: @@ -15054,7 +15186,7 @@ yydefault: var yyLOCAL *TableOption //line sql.y:3210 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 560: @@ -15062,7 +15194,7 @@ yydefault: var yyLOCAL *TableOption //line sql.y:3214 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 561: @@ -15090,227 +15222,227 @@ yydefault: } yyVAL.union = yyLOCAL case 564: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption //line sql.y:3230 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: (yyDollar[3].identifierCI.String() + yyDollar[4].str), CaseSensitive: true} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 565: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *TableOption //line sql.y:3234 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Tables: yyDollar[4].tableNamesUnion()} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 566: + yyDollar = yyS[yypt-4 : yypt+1] + var yyLOCAL *TableOption +//line sql.y:3238 + { + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: (yyDollar[3].identifierCI.String() + yyDollar[4].str), CaseSensitive: true} + } + yyVAL.union = yyLOCAL + case 567: + yyDollar = yyS[yypt-5 : yypt+1] + var yyLOCAL *TableOption +//line sql.y:3242 + { + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Tables: yyDollar[4].tableNamesUnion()} + } + yyVAL.union = yyLOCAL + case 568: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3239 +//line sql.y:3247 { yyVAL.str = "" } - case 567: + case 569: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3243 +//line sql.y:3251 { yyVAL.str = " " + string(yyDollar[1].str) + " " + string(yyDollar[2].str) } - case 568: + case 570: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3247 +//line sql.y:3255 { yyVAL.str = " " + string(yyDollar[1].str) + " " + string(yyDollar[2].str) } - case 578: + case 580: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3266 +//line sql.y:3274 { yyVAL.str = String(TableName{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCS}) } - case 579: + case 581: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3270 +//line sql.y:3278 { yyVAL.str = yyDollar[1].identifierCI.String() } - case 580: + case 582: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3274 +//line sql.y:3282 { yyVAL.str = encodeSQLString(yyDollar[1].str) } - case 581: + case 583: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3278 +//line sql.y:3286 { yyVAL.str = string(yyDollar[1].str) } - case 582: + case 584: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3283 +//line sql.y:3291 { yyVAL.str = "" } - case 584: + case 586: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:3289 +//line sql.y:3297 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 585: + case 587: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:3293 +//line sql.y:3301 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 586: + case 588: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ColName -//line sql.y:3298 +//line sql.y:3306 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 587: + case 589: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColName -//line sql.y:3302 +//line sql.y:3310 { yyLOCAL = yyDollar[2].colNameUnion() } yyVAL.union = yyLOCAL - case 588: + case 590: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3307 +//line sql.y:3315 { yyVAL.str = "" } - case 589: + case 591: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3311 +//line sql.y:3319 { yyVAL.str = string(yyDollar[2].str) } - case 590: + case 592: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *Literal -//line sql.y:3316 +//line sql.y:3324 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 591: + case 593: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Literal -//line sql.y:3320 +//line sql.y:3328 { yyLOCAL = NewIntLiteral(yyDollar[2].str) } yyVAL.union = yyLOCAL - case 592: + case 594: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Literal -//line sql.y:3324 +//line sql.y:3332 { yyLOCAL = NewDecimalLiteral(yyDollar[2].str) } yyVAL.union = yyLOCAL - case 593: + case 595: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:3329 +//line sql.y:3337 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 594: + case 596: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:3333 +//line sql.y:3341 { yyLOCAL = yyDollar[1].alterOptionsUnion() } yyVAL.union = yyLOCAL - case 595: + case 597: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:3337 +//line sql.y:3345 { yySLICE := (*[]AlterOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, &OrderByOption{Cols: yyDollar[5].columnsUnion()}) } - case 596: + case 598: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:3341 +//line sql.y:3349 { yyLOCAL = yyDollar[1].alterOptionsUnion() } yyVAL.union = yyLOCAL - case 597: + case 599: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3345 +//line sql.y:3353 { yySLICE := (*[]AlterOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].alterOptionsUnion()...) } - case 598: + case 600: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:3349 +//line sql.y:3357 { yyLOCAL = append(append(yyDollar[1].alterOptionsUnion(), yyDollar[3].alterOptionsUnion()...), &OrderByOption{Cols: yyDollar[7].columnsUnion()}) } yyVAL.union = yyLOCAL - case 599: + case 601: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:3355 +//line sql.y:3363 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 600: - yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3359 - { - yySLICE := (*[]AlterOption)(yyIaddr(yyVAL.union)) - *yySLICE = append(*yySLICE, yyDollar[3].alterOptionUnion()) - } - case 601: + case 602: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3363 +//line sql.y:3367 { yySLICE := (*[]AlterOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].alterOptionUnion()) } - case 602: - yyDollar = yyS[yypt-1 : yypt+1] - var yyLOCAL AlterOption -//line sql.y:3369 - { - yyLOCAL = yyDollar[1].tableOptionsUnion() - } - yyVAL.union = yyLOCAL - case 603: - yyDollar = yyS[yypt-2 : yypt+1] - var yyLOCAL AlterOption -//line sql.y:3373 + case 603: + yyDollar = yyS[yypt-3 : yypt+1] +//line sql.y:3371 { - yyLOCAL = &AddConstraintDefinition{ConstraintDefinition: yyDollar[2].constraintDefinitionUnion()} + yySLICE := (*[]AlterOption)(yyIaddr(yyVAL.union)) + *yySLICE = append(*yySLICE, yyDollar[3].alterOptionUnion()) } - yyVAL.union = yyLOCAL case 604: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL AlterOption //line sql.y:3377 { - yyLOCAL = &AddConstraintDefinition{ConstraintDefinition: yyDollar[2].constraintDefinitionUnion()} + yyLOCAL = yyDollar[1].tableOptionsUnion() } yyVAL.union = yyLOCAL case 605: @@ -15318,23 +15450,23 @@ yydefault: var yyLOCAL AlterOption //line sql.y:3381 { - yyLOCAL = &AddIndexDefinition{IndexDefinition: yyDollar[2].indexDefinitionUnion()} + yyLOCAL = &AddConstraintDefinition{ConstraintDefinition: yyDollar[2].constraintDefinitionUnion()} } yyVAL.union = yyLOCAL case 606: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption //line sql.y:3385 { - yyLOCAL = &AddColumns{Columns: yyDollar[4].columnDefinitionsUnion()} + yyLOCAL = &AddConstraintDefinition{ConstraintDefinition: yyDollar[2].constraintDefinitionUnion()} } yyVAL.union = yyLOCAL case 607: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption //line sql.y:3389 { - yyLOCAL = &AddColumns{Columns: []*ColumnDefinition{yyDollar[3].columnDefinitionUnion()}, First: yyDollar[4].booleanUnion(), After: yyDollar[5].colNameUnion()} + yyLOCAL = &AddIndexDefinition{IndexDefinition: yyDollar[2].indexDefinitionUnion()} } yyVAL.union = yyLOCAL case 608: @@ -15342,55 +15474,55 @@ yydefault: var yyLOCAL AlterOption //line sql.y:3393 { - yyLOCAL = &AlterColumn{Column: yyDollar[3].colNameUnion(), DropDefault: true} + yyLOCAL = &AddColumns{Columns: yyDollar[4].columnDefinitionsUnion()} } yyVAL.union = yyLOCAL case 609: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption //line sql.y:3397 { - yyLOCAL = &AlterColumn{Column: yyDollar[3].colNameUnion(), DropDefault: false, DefaultVal: yyDollar[6].exprUnion(), DefaultLiteral: true} + yyLOCAL = &AddColumns{Columns: []*ColumnDefinition{yyDollar[3].columnDefinitionUnion()}, First: yyDollar[4].booleanUnion(), After: yyDollar[5].colNameUnion()} } yyVAL.union = yyLOCAL case 610: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption //line sql.y:3401 { - yyLOCAL = &AlterColumn{Column: yyDollar[3].colNameUnion(), DropDefault: false, DefaultVal: yyDollar[7].exprUnion()} + yyLOCAL = &AlterColumn{Column: yyDollar[3].colNameUnion(), DropDefault: true} } yyVAL.union = yyLOCAL case 611: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL AlterOption //line sql.y:3405 { - yyLOCAL = &AlterColumn{Column: yyDollar[3].colNameUnion(), Invisible: ptr.Of(false)} + yyLOCAL = &AlterColumn{Column: yyDollar[3].colNameUnion(), DropDefault: false, DefaultVal: yyDollar[6].exprUnion(), DefaultLiteral: true} } yyVAL.union = yyLOCAL case 612: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL AlterOption //line sql.y:3409 { - yyLOCAL = &AlterColumn{Column: yyDollar[3].colNameUnion(), Invisible: ptr.Of(true)} + yyLOCAL = &AlterColumn{Column: yyDollar[3].colNameUnion(), DropDefault: false, DefaultVal: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 613: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption //line sql.y:3413 { - yyLOCAL = &AlterCheck{Name: yyDollar[3].identifierCI, Enforced: yyDollar[4].booleanUnion()} + yyLOCAL = &AlterColumn{Column: yyDollar[3].colNameUnion(), Invisible: ptr.Of(false)} } yyVAL.union = yyLOCAL case 614: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption //line sql.y:3417 { - yyLOCAL = &AlterIndex{Name: yyDollar[3].identifierCI, Invisible: false} + yyLOCAL = &AlterColumn{Column: yyDollar[3].colNameUnion(), Invisible: ptr.Of(true)} } yyVAL.union = yyLOCAL case 615: @@ -15398,31 +15530,31 @@ yydefault: var yyLOCAL AlterOption //line sql.y:3421 { - yyLOCAL = &AlterIndex{Name: yyDollar[3].identifierCI, Invisible: true} + yyLOCAL = &AlterCheck{Name: yyDollar[3].identifierCI, Enforced: yyDollar[4].booleanUnion()} } yyVAL.union = yyLOCAL case 616: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL AlterOption //line sql.y:3425 { - yyLOCAL = &ChangeColumn{OldColumn: yyDollar[3].colNameUnion(), NewColDefinition: yyDollar[4].columnDefinitionUnion(), First: yyDollar[5].booleanUnion(), After: yyDollar[6].colNameUnion()} + yyLOCAL = &AlterIndex{Name: yyDollar[3].identifierCI, Invisible: false} } yyVAL.union = yyLOCAL case 617: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL AlterOption //line sql.y:3429 { - yyLOCAL = &ModifyColumn{NewColDefinition: yyDollar[3].columnDefinitionUnion(), First: yyDollar[4].booleanUnion(), After: yyDollar[5].colNameUnion()} + yyLOCAL = &AlterIndex{Name: yyDollar[3].identifierCI, Invisible: true} } yyVAL.union = yyLOCAL case 618: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL AlterOption //line sql.y:3433 { - yyLOCAL = &RenameColumn{OldName: yyDollar[3].colNameUnion(), NewName: yyDollar[5].colNameUnion()} + yyLOCAL = &ChangeColumn{OldColumn: yyDollar[3].colNameUnion(), NewColDefinition: yyDollar[4].columnDefinitionUnion(), First: yyDollar[5].booleanUnion(), After: yyDollar[6].colNameUnion()} } yyVAL.union = yyLOCAL case 619: @@ -15430,23 +15562,23 @@ yydefault: var yyLOCAL AlterOption //line sql.y:3437 { - yyLOCAL = &AlterCharset{CharacterSet: yyDollar[4].str, Collate: yyDollar[5].str} + yyLOCAL = &ModifyColumn{NewColDefinition: yyDollar[3].columnDefinitionUnion(), First: yyDollar[4].booleanUnion(), After: yyDollar[5].colNameUnion()} } yyVAL.union = yyLOCAL case 620: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption //line sql.y:3441 { - yyLOCAL = &KeyState{Enable: false} + yyLOCAL = &RenameColumn{OldName: yyDollar[3].colNameUnion(), NewName: yyDollar[5].colNameUnion()} } yyVAL.union = yyLOCAL case 621: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption //line sql.y:3445 { - yyLOCAL = &KeyState{Enable: true} + yyLOCAL = &AlterCharset{CharacterSet: yyDollar[4].str, Collate: yyDollar[5].str} } yyVAL.union = yyLOCAL case 622: @@ -15454,7 +15586,7 @@ yydefault: var yyLOCAL AlterOption //line sql.y:3449 { - yyLOCAL = &TablespaceOperation{Import: false} + yyLOCAL = &KeyState{Enable: false} } yyVAL.union = yyLOCAL case 623: @@ -15462,23 +15594,23 @@ yydefault: var yyLOCAL AlterOption //line sql.y:3453 { - yyLOCAL = &TablespaceOperation{Import: true} + yyLOCAL = &KeyState{Enable: true} } yyVAL.union = yyLOCAL case 624: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption //line sql.y:3457 { - yyLOCAL = &DropColumn{Name: yyDollar[3].colNameUnion()} + yyLOCAL = &TablespaceOperation{Import: false} } yyVAL.union = yyLOCAL case 625: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption //line sql.y:3461 { - yyLOCAL = &DropKey{Type: NormalKeyType, Name: yyDollar[3].identifierCI} + yyLOCAL = &TablespaceOperation{Import: true} } yyVAL.union = yyLOCAL case 626: @@ -15486,15 +15618,15 @@ yydefault: var yyLOCAL AlterOption //line sql.y:3465 { - yyLOCAL = &DropKey{Type: PrimaryKeyType} + yyLOCAL = &DropColumn{Name: yyDollar[3].colNameUnion()} } yyVAL.union = yyLOCAL case 627: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption //line sql.y:3469 { - yyLOCAL = &DropKey{Type: ForeignKeyType, Name: yyDollar[4].identifierCI} + yyLOCAL = &DropKey{Type: NormalKeyType, Name: yyDollar[3].identifierCI} } yyVAL.union = yyLOCAL case 628: @@ -15502,23 +15634,23 @@ yydefault: var yyLOCAL AlterOption //line sql.y:3473 { - yyLOCAL = &DropKey{Type: CheckKeyType, Name: yyDollar[3].identifierCI} + yyLOCAL = &DropKey{Type: PrimaryKeyType} } yyVAL.union = yyLOCAL case 629: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL AlterOption //line sql.y:3477 { - yyLOCAL = &DropKey{Type: ConstraintType, Name: yyDollar[3].identifierCI} + yyLOCAL = &DropKey{Type: ForeignKeyType, Name: yyDollar[4].identifierCI} } yyVAL.union = yyLOCAL case 630: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption //line sql.y:3481 { - yyLOCAL = &Force{} + yyLOCAL = &DropKey{Type: CheckKeyType, Name: yyDollar[3].identifierCI} } yyVAL.union = yyLOCAL case 631: @@ -15526,48 +15658,48 @@ yydefault: var yyLOCAL AlterOption //line sql.y:3485 { - yyLOCAL = &RenameTableName{Table: yyDollar[3].tableName} + yyLOCAL = &DropKey{Type: ConstraintType, Name: yyDollar[3].identifierCI} } yyVAL.union = yyLOCAL case 632: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL AlterOption //line sql.y:3489 { - yyLOCAL = &RenameIndex{OldName: yyDollar[3].identifierCI, NewName: yyDollar[5].identifierCI} + yyLOCAL = &Force{} } yyVAL.union = yyLOCAL case 633: - yyDollar = yyS[yypt-1 : yypt+1] - var yyLOCAL []AlterOption -//line sql.y:3495 + yyDollar = yyS[yypt-3 : yypt+1] + var yyLOCAL AlterOption +//line sql.y:3493 { - yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} + yyLOCAL = &RenameTableName{Table: yyDollar[3].tableName} } yyVAL.union = yyLOCAL case 634: - yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3499 + yyDollar = yyS[yypt-5 : yypt+1] + var yyLOCAL AlterOption +//line sql.y:3497 { - yySLICE := (*[]AlterOption)(yyIaddr(yyVAL.union)) - *yySLICE = append(*yySLICE, yyDollar[3].alterOptionUnion()) + yyLOCAL = &RenameIndex{OldName: yyDollar[3].identifierCI, NewName: yyDollar[5].identifierCI} } + yyVAL.union = yyLOCAL case 635: - yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL AlterOption -//line sql.y:3505 + yyDollar = yyS[yypt-1 : yypt+1] + var yyLOCAL []AlterOption +//line sql.y:3503 { - yyLOCAL = AlgorithmValue(string(yyDollar[3].str)) + yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} } yyVAL.union = yyLOCAL case 636: yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL AlterOption -//line sql.y:3509 +//line sql.y:3507 { - yyLOCAL = AlgorithmValue(string(yyDollar[3].str)) + yySLICE := (*[]AlterOption)(yyIaddr(yyVAL.union)) + *yySLICE = append(*yySLICE, yyDollar[3].alterOptionUnion()) } - yyVAL.union = yyLOCAL case 637: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption @@ -15589,7 +15721,7 @@ yydefault: var yyLOCAL AlterOption //line sql.y:3521 { - yyLOCAL = &LockOption{Type: DefaultType} + yyLOCAL = AlgorithmValue(string(yyDollar[3].str)) } yyVAL.union = yyLOCAL case 640: @@ -15597,7 +15729,7 @@ yydefault: var yyLOCAL AlterOption //line sql.y:3525 { - yyLOCAL = &LockOption{Type: NoneType} + yyLOCAL = AlgorithmValue(string(yyDollar[3].str)) } yyVAL.union = yyLOCAL case 641: @@ -15605,7 +15737,7 @@ yydefault: var yyLOCAL AlterOption //line sql.y:3529 { - yyLOCAL = &LockOption{Type: SharedType} + yyLOCAL = &LockOption{Type: DefaultType} } yyVAL.union = yyLOCAL case 642: @@ -15613,29 +15745,45 @@ yydefault: var yyLOCAL AlterOption //line sql.y:3533 { - yyLOCAL = &LockOption{Type: ExclusiveType} + yyLOCAL = &LockOption{Type: NoneType} } yyVAL.union = yyLOCAL case 643: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption //line sql.y:3537 { - yyLOCAL = &Validation{With: true} + yyLOCAL = &LockOption{Type: SharedType} } yyVAL.union = yyLOCAL case 644: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption //line sql.y:3541 { - yyLOCAL = &Validation{With: false} + yyLOCAL = &LockOption{Type: ExclusiveType} } yyVAL.union = yyLOCAL case 645: + yyDollar = yyS[yypt-2 : yypt+1] + var yyLOCAL AlterOption +//line sql.y:3545 + { + yyLOCAL = &Validation{With: true} + } + yyVAL.union = yyLOCAL + case 646: + yyDollar = yyS[yypt-2 : yypt+1] + var yyLOCAL AlterOption +//line sql.y:3549 + { + yyLOCAL = &Validation{With: false} + } + yyVAL.union = yyLOCAL + case 647: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:3547 +//line sql.y:3555 { yyDollar[1].alterTableUnion().FullyParsed = true yyDollar[1].alterTableUnion().AlterOptions = yyDollar[2].alterOptionsUnion() @@ -15643,10 +15791,10 @@ yydefault: yyLOCAL = yyDollar[1].alterTableUnion() } yyVAL.union = yyLOCAL - case 646: + case 648: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:3554 +//line sql.y:3562 { yyDollar[1].alterTableUnion().FullyParsed = true yyDollar[1].alterTableUnion().AlterOptions = yyDollar[2].alterOptionsUnion() @@ -15654,10 +15802,10 @@ yydefault: yyLOCAL = yyDollar[1].alterTableUnion() } yyVAL.union = yyLOCAL - case 647: + case 649: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:3561 +//line sql.y:3569 { yyDollar[1].alterTableUnion().FullyParsed = true yyDollar[1].alterTableUnion().AlterOptions = yyDollar[2].alterOptionsUnion() @@ -15665,28 +15813,28 @@ yydefault: yyLOCAL = yyDollar[1].alterTableUnion() } yyVAL.union = yyLOCAL - case 648: + case 650: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:3568 +//line sql.y:3576 { yyDollar[1].alterTableUnion().FullyParsed = true yyDollar[1].alterTableUnion().PartitionSpec = yyDollar[2].partSpecUnion() yyLOCAL = yyDollar[1].alterTableUnion() } yyVAL.union = yyLOCAL - case 649: + case 651: yyDollar = yyS[yypt-11 : yypt+1] var yyLOCAL Statement -//line sql.y:3574 +//line sql.y:3582 { yyLOCAL = &AlterView{ViewName: yyDollar[7].tableName, Comments: Comments(yyDollar[2].strs).Parsed(), Algorithm: yyDollar[3].str, Definer: yyDollar[4].definerUnion(), Security: yyDollar[5].str, Columns: yyDollar[8].columnsUnion(), Select: yyDollar[10].tableStmtUnion(), CheckOption: yyDollar[11].str} } yyVAL.union = yyLOCAL - case 650: + case 652: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:3584 +//line sql.y:3592 { yyDollar[1].alterDatabaseUnion().FullyParsed = true yyDollar[1].alterDatabaseUnion().DBName = yyDollar[2].identifierCS @@ -15694,10 +15842,10 @@ yydefault: yyLOCAL = yyDollar[1].alterDatabaseUnion() } yyVAL.union = yyLOCAL - case 651: + case 653: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:3591 +//line sql.y:3599 { yyDollar[1].alterDatabaseUnion().FullyParsed = true yyDollar[1].alterDatabaseUnion().DBName = yyDollar[2].identifierCS @@ -15705,10 +15853,10 @@ yydefault: yyLOCAL = yyDollar[1].alterDatabaseUnion() } yyVAL.union = yyLOCAL - case 652: + case 654: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Statement -//line sql.y:3598 +//line sql.y:3606 { yyLOCAL = &AlterVschema{ Action: CreateVindexDDLAction, @@ -15721,10 +15869,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 653: + case 655: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:3610 +//line sql.y:3618 { yyLOCAL = &AlterVschema{ Action: DropVindexDDLAction, @@ -15735,26 +15883,26 @@ yydefault: } } yyVAL.union = yyLOCAL - case 654: + case 656: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:3620 +//line sql.y:3628 { yyLOCAL = &AlterVschema{Action: AddVschemaTableDDLAction, Table: yyDollar[6].tableName} } yyVAL.union = yyLOCAL - case 655: + case 657: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:3624 +//line sql.y:3632 { yyLOCAL = &AlterVschema{Action: DropVschemaTableDDLAction, Table: yyDollar[6].tableName} } yyVAL.union = yyLOCAL - case 656: + case 658: yyDollar = yyS[yypt-13 : yypt+1] var yyLOCAL Statement -//line sql.y:3628 +//line sql.y:3636 { yyLOCAL = &AlterVschema{ Action: AddColVindexDDLAction, @@ -15768,10 +15916,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 657: + case 659: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Statement -//line sql.y:3641 +//line sql.y:3649 { yyLOCAL = &AlterVschema{ Action: DropColVindexDDLAction, @@ -15782,26 +15930,26 @@ yydefault: } } yyVAL.union = yyLOCAL - case 658: + case 660: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:3651 +//line sql.y:3659 { yyLOCAL = &AlterVschema{Action: AddSequenceDDLAction, Table: yyDollar[6].tableName} } yyVAL.union = yyLOCAL - case 659: + case 661: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:3655 +//line sql.y:3663 { yyLOCAL = &AlterVschema{Action: DropSequenceDDLAction, Table: yyDollar[6].tableName} } yyVAL.union = yyLOCAL - case 660: + case 662: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Statement -//line sql.y:3659 +//line sql.y:3667 { yyLOCAL = &AlterVschema{ Action: AddAutoIncDDLAction, @@ -15813,10 +15961,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 661: + case 663: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:3670 +//line sql.y:3678 { yyLOCAL = &AlterVschema{ Action: DropAutoIncDDLAction, @@ -15824,10 +15972,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 662: + case 664: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3677 +//line sql.y:3685 { yyLOCAL = &AlterMigration{ Type: RetryMigrationType, @@ -15835,10 +15983,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 663: + case 665: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3684 +//line sql.y:3692 { yyLOCAL = &AlterMigration{ Type: CleanupMigrationType, @@ -15846,20 +15994,20 @@ yydefault: } } yyVAL.union = yyLOCAL - case 664: + case 666: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3691 +//line sql.y:3699 { yyLOCAL = &AlterMigration{ Type: CleanupAllMigrationType, } } yyVAL.union = yyLOCAL - case 665: + case 667: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3697 +//line sql.y:3705 { yyLOCAL = &AlterMigration{ Type: LaunchMigrationType, @@ -15867,10 +16015,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 666: + case 668: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:3704 +//line sql.y:3712 { yyLOCAL = &AlterMigration{ Type: LaunchMigrationType, @@ -15879,20 +16027,20 @@ yydefault: } } yyVAL.union = yyLOCAL - case 667: + case 669: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3712 +//line sql.y:3720 { yyLOCAL = &AlterMigration{ Type: LaunchAllMigrationType, } } yyVAL.union = yyLOCAL - case 668: + case 670: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3718 +//line sql.y:3726 { yyLOCAL = &AlterMigration{ Type: CompleteMigrationType, @@ -15900,20 +16048,20 @@ yydefault: } } yyVAL.union = yyLOCAL - case 669: + case 671: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3725 +//line sql.y:3733 { yyLOCAL = &AlterMigration{ Type: CompleteAllMigrationType, } } yyVAL.union = yyLOCAL - case 670: + case 672: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3731 +//line sql.y:3739 { yyLOCAL = &AlterMigration{ Type: CancelMigrationType, @@ -15921,20 +16069,20 @@ yydefault: } } yyVAL.union = yyLOCAL - case 671: + case 673: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3738 +//line sql.y:3746 { yyLOCAL = &AlterMigration{ Type: CancelAllMigrationType, } } yyVAL.union = yyLOCAL - case 672: + case 674: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:3744 +//line sql.y:3752 { yyLOCAL = &AlterMigration{ Type: ThrottleMigrationType, @@ -15944,10 +16092,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 673: + case 675: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:3753 +//line sql.y:3761 { yyLOCAL = &AlterMigration{ Type: ThrottleAllMigrationType, @@ -15956,10 +16104,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 674: + case 676: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3761 +//line sql.y:3769 { yyLOCAL = &AlterMigration{ Type: UnthrottleMigrationType, @@ -15967,20 +16115,20 @@ yydefault: } } yyVAL.union = yyLOCAL - case 675: + case 677: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3768 +//line sql.y:3776 { yyLOCAL = &AlterMigration{ Type: UnthrottleAllMigrationType, } } yyVAL.union = yyLOCAL - case 676: + case 678: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3774 +//line sql.y:3782 { yyLOCAL = &AlterMigration{ Type: ForceCutOverMigrationType, @@ -15988,20 +16136,20 @@ yydefault: } } yyVAL.union = yyLOCAL - case 677: + case 679: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:3781 +//line sql.y:3789 { yyLOCAL = &AlterMigration{ Type: ForceCutOverAllMigrationType, } } yyVAL.union = yyLOCAL - case 678: + case 680: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:3787 +//line sql.y:3795 { yyLOCAL = &AlterMigration{ Type: SetCutOverThresholdMigrationType, @@ -16010,18 +16158,18 @@ yydefault: } } yyVAL.union = yyLOCAL - case 679: + case 681: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *PartitionOption -//line sql.y:3796 +//line sql.y:3804 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 680: + case 682: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *PartitionOption -//line sql.y:3800 +//line sql.y:3808 { yyDollar[3].partitionOptionUnion().Partitions = yyDollar[4].integerUnion() yyDollar[3].partitionOptionUnion().SubPartition = yyDollar[5].subPartitionUnion() @@ -16029,10 +16177,10 @@ yydefault: yyLOCAL = yyDollar[3].partitionOptionUnion() } yyVAL.union = yyLOCAL - case 681: + case 683: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *PartitionOption -//line sql.y:3809 +//line sql.y:3817 { yyLOCAL = &PartitionOption{ IsLinear: yyDollar[1].booleanUnion(), @@ -16041,10 +16189,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 682: + case 684: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *PartitionOption -//line sql.y:3817 +//line sql.y:3825 { yyLOCAL = &PartitionOption{ IsLinear: yyDollar[1].booleanUnion(), @@ -16054,10 +16202,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 683: + case 685: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionOption -//line sql.y:3826 +//line sql.y:3834 { yyLOCAL = &PartitionOption{ Type: yyDollar[1].partitionByTypeUnion(), @@ -16065,10 +16213,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 684: + case 686: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *PartitionOption -//line sql.y:3833 +//line sql.y:3841 { yyLOCAL = &PartitionOption{ Type: yyDollar[1].partitionByTypeUnion(), @@ -16076,18 +16224,18 @@ yydefault: } } yyVAL.union = yyLOCAL - case 685: + case 687: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *SubPartition -//line sql.y:3841 +//line sql.y:3849 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 686: + case 688: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *SubPartition -//line sql.y:3845 +//line sql.y:3853 { yyLOCAL = &SubPartition{ IsLinear: yyDollar[3].booleanUnion(), @@ -16097,10 +16245,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 687: + case 689: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL *SubPartition -//line sql.y:3854 +//line sql.y:3862 { yyLOCAL = &SubPartition{ IsLinear: yyDollar[3].booleanUnion(), @@ -16111,300 +16259,284 @@ yydefault: } } yyVAL.union = yyLOCAL - case 688: + case 690: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*PartitionDefinition -//line sql.y:3865 +//line sql.y:3873 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 689: + case 691: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*PartitionDefinition -//line sql.y:3869 +//line sql.y:3877 { yyLOCAL = yyDollar[2].partDefsUnion() } yyVAL.union = yyLOCAL - case 690: + case 692: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:3874 +//line sql.y:3882 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 691: + case 693: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:3878 +//line sql.y:3886 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 692: + case 694: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int -//line sql.y:3883 +//line sql.y:3891 { yyLOCAL = 0 } yyVAL.union = yyLOCAL - case 693: + case 695: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int -//line sql.y:3887 +//line sql.y:3895 { yyLOCAL = convertStringToInt(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 694: + case 696: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL TableExpr -//line sql.y:3893 +//line sql.y:3901 { yyLOCAL = &JSONTableExpr{Expr: yyDollar[3].exprUnion(), Filter: yyDollar[5].exprUnion(), Columns: yyDollar[6].jtColumnListUnion(), Alias: yyDollar[8].identifierCS} } yyVAL.union = yyLOCAL - case 695: + case 697: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL []*JtColumnDefinition -//line sql.y:3899 +//line sql.y:3907 { yyLOCAL = yyDollar[3].jtColumnListUnion() } yyVAL.union = yyLOCAL - case 696: + case 698: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*JtColumnDefinition -//line sql.y:3905 +//line sql.y:3913 { yyLOCAL = []*JtColumnDefinition{yyDollar[1].jtColumnDefinitionUnion()} } yyVAL.union = yyLOCAL - case 697: + case 699: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3909 +//line sql.y:3917 { yySLICE := (*[]*JtColumnDefinition)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].jtColumnDefinitionUnion()) } - case 698: + case 700: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *JtColumnDefinition -//line sql.y:3915 +//line sql.y:3923 { yyLOCAL = &JtColumnDefinition{JtOrdinal: &JtOrdinalColDef{Name: yyDollar[1].identifierCI}} } yyVAL.union = yyLOCAL - case 699: + case 701: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *JtColumnDefinition -//line sql.y:3919 +//line sql.y:3927 { yyDollar[2].columnType.Options = &ColumnTypeOptions{Collate: yyDollar[3].str} jtPath := &JtPathColDef{Name: yyDollar[1].identifierCI, Type: yyDollar[2].columnType, JtColExists: yyDollar[4].booleanUnion(), Path: yyDollar[6].exprUnion()} yyLOCAL = &JtColumnDefinition{JtPath: jtPath} } yyVAL.union = yyLOCAL - case 700: + case 702: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *JtColumnDefinition -//line sql.y:3925 +//line sql.y:3933 { yyDollar[2].columnType.Options = &ColumnTypeOptions{Collate: yyDollar[3].str} jtPath := &JtPathColDef{Name: yyDollar[1].identifierCI, Type: yyDollar[2].columnType, JtColExists: yyDollar[4].booleanUnion(), Path: yyDollar[6].exprUnion(), EmptyOnResponse: yyDollar[7].jtOnResponseUnion()} yyLOCAL = &JtColumnDefinition{JtPath: jtPath} } yyVAL.union = yyLOCAL - case 701: + case 703: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *JtColumnDefinition -//line sql.y:3931 +//line sql.y:3939 { yyDollar[2].columnType.Options = &ColumnTypeOptions{Collate: yyDollar[3].str} jtPath := &JtPathColDef{Name: yyDollar[1].identifierCI, Type: yyDollar[2].columnType, JtColExists: yyDollar[4].booleanUnion(), Path: yyDollar[6].exprUnion(), ErrorOnResponse: yyDollar[7].jtOnResponseUnion()} yyLOCAL = &JtColumnDefinition{JtPath: jtPath} } yyVAL.union = yyLOCAL - case 702: + case 704: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *JtColumnDefinition -//line sql.y:3937 +//line sql.y:3945 { yyDollar[2].columnType.Options = &ColumnTypeOptions{Collate: yyDollar[3].str} jtPath := &JtPathColDef{Name: yyDollar[1].identifierCI, Type: yyDollar[2].columnType, JtColExists: yyDollar[4].booleanUnion(), Path: yyDollar[6].exprUnion(), EmptyOnResponse: yyDollar[7].jtOnResponseUnion(), ErrorOnResponse: yyDollar[8].jtOnResponseUnion()} yyLOCAL = &JtColumnDefinition{JtPath: jtPath} } yyVAL.union = yyLOCAL - case 703: + case 705: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *JtColumnDefinition -//line sql.y:3943 +//line sql.y:3951 { jtNestedPath := &JtNestedPathColDef{Path: yyDollar[3].exprUnion(), Columns: yyDollar[4].jtColumnListUnion()} yyLOCAL = &JtColumnDefinition{JtNestedPath: jtNestedPath} } yyVAL.union = yyLOCAL - case 704: + case 706: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:3949 +//line sql.y:3957 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 705: + case 707: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:3953 +//line sql.y:3961 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 706: + case 708: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:3957 +//line sql.y:3965 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 707: + case 709: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:3961 +//line sql.y:3969 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 708: + case 710: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *JtOnResponse -//line sql.y:3967 +//line sql.y:3975 { yyLOCAL = yyDollar[1].jtOnResponseUnion() } yyVAL.union = yyLOCAL - case 709: + case 711: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *JtOnResponse -//line sql.y:3973 +//line sql.y:3981 { yyLOCAL = yyDollar[1].jtOnResponseUnion() } yyVAL.union = yyLOCAL - case 710: + case 712: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *JtOnResponse -//line sql.y:3979 +//line sql.y:3987 { yyLOCAL = &JtOnResponse{ResponseType: ErrorJSONType} } yyVAL.union = yyLOCAL - case 711: + case 713: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *JtOnResponse -//line sql.y:3983 +//line sql.y:3991 { yyLOCAL = &JtOnResponse{ResponseType: NullJSONType} } yyVAL.union = yyLOCAL - case 712: + case 714: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *JtOnResponse -//line sql.y:3987 +//line sql.y:3995 { yyLOCAL = &JtOnResponse{ResponseType: DefaultJSONType, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 713: + case 715: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL PartitionByType -//line sql.y:3993 +//line sql.y:4001 { yyLOCAL = RangeType } yyVAL.union = yyLOCAL - case 714: + case 716: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL PartitionByType -//line sql.y:3997 +//line sql.y:4005 { yyLOCAL = ListType } yyVAL.union = yyLOCAL - case 715: + case 717: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int -//line sql.y:4002 +//line sql.y:4010 { yyLOCAL = -1 } yyVAL.union = yyLOCAL - case 716: + case 718: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL int -//line sql.y:4006 +//line sql.y:4014 { yyLOCAL = convertStringToInt(yyDollar[2].str) } yyVAL.union = yyLOCAL - case 717: + case 719: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int -//line sql.y:4011 +//line sql.y:4019 { yyLOCAL = -1 } yyVAL.union = yyLOCAL - case 718: + case 720: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL int -//line sql.y:4015 +//line sql.y:4023 { yyLOCAL = convertStringToInt(yyDollar[2].str) } yyVAL.union = yyLOCAL - case 719: - yyDollar = yyS[yypt-5 : yypt+1] - var yyLOCAL *PartitionSpec -//line sql.y:4021 - { - yyLOCAL = &PartitionSpec{Action: AddAction, Definitions: []*PartitionDefinition{yyDollar[4].partDefUnion()}} - } - yyVAL.union = yyLOCAL - case 720: - yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL *PartitionSpec -//line sql.y:4025 - { - yyLOCAL = &PartitionSpec{Action: DropAction, Names: yyDollar[3].partitionsUnion()} - } - yyVAL.union = yyLOCAL case 721: - yyDollar = yyS[yypt-7 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *PartitionSpec //line sql.y:4029 { - yyLOCAL = &PartitionSpec{Action: ReorganizeAction, Names: yyDollar[3].partitionsUnion(), Definitions: yyDollar[6].partDefsUnion()} + yyLOCAL = &PartitionSpec{Action: AddAction, Definitions: []*PartitionDefinition{yyDollar[4].partDefUnion()}} } yyVAL.union = yyLOCAL case 722: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec //line sql.y:4033 { - yyLOCAL = &PartitionSpec{Action: DiscardAction, Names: yyDollar[3].partitionsUnion()} + yyLOCAL = &PartitionSpec{Action: DropAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL case 723: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *PartitionSpec //line sql.y:4037 { - yyLOCAL = &PartitionSpec{Action: DiscardAction, IsAll: true} + yyLOCAL = &PartitionSpec{Action: ReorganizeAction, Names: yyDollar[3].partitionsUnion(), Definitions: yyDollar[6].partDefsUnion()} } yyVAL.union = yyLOCAL case 724: @@ -16412,7 +16544,7 @@ yydefault: var yyLOCAL *PartitionSpec //line sql.y:4041 { - yyLOCAL = &PartitionSpec{Action: ImportAction, Names: yyDollar[3].partitionsUnion()} + yyLOCAL = &PartitionSpec{Action: DiscardAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL case 725: @@ -16420,23 +16552,23 @@ yydefault: var yyLOCAL *PartitionSpec //line sql.y:4045 { - yyLOCAL = &PartitionSpec{Action: ImportAction, IsAll: true} + yyLOCAL = &PartitionSpec{Action: DiscardAction, IsAll: true} } yyVAL.union = yyLOCAL case 726: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionSpec //line sql.y:4049 { - yyLOCAL = &PartitionSpec{Action: TruncateAction, Names: yyDollar[3].partitionsUnion()} + yyLOCAL = &PartitionSpec{Action: ImportAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL case 727: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionSpec //line sql.y:4053 { - yyLOCAL = &PartitionSpec{Action: TruncateAction, IsAll: true} + yyLOCAL = &PartitionSpec{Action: ImportAction, IsAll: true} } yyVAL.union = yyLOCAL case 728: @@ -16444,15 +16576,15 @@ yydefault: var yyLOCAL *PartitionSpec //line sql.y:4057 { - yyLOCAL = &PartitionSpec{Action: CoalesceAction, Number: NewIntLiteral(yyDollar[3].str)} + yyLOCAL = &PartitionSpec{Action: TruncateAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL case 729: - yyDollar = yyS[yypt-7 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec //line sql.y:4061 { - yyLOCAL = &PartitionSpec{Action: ExchangeAction, Names: Partitions{yyDollar[3].identifierCI}, TableName: yyDollar[6].tableName, WithoutValidation: yyDollar[7].booleanUnion()} + yyLOCAL = &PartitionSpec{Action: TruncateAction, IsAll: true} } yyVAL.union = yyLOCAL case 730: @@ -16460,15 +16592,15 @@ yydefault: var yyLOCAL *PartitionSpec //line sql.y:4065 { - yyLOCAL = &PartitionSpec{Action: AnalyzeAction, Names: yyDollar[3].partitionsUnion()} + yyLOCAL = &PartitionSpec{Action: CoalesceAction, Number: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 731: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *PartitionSpec //line sql.y:4069 { - yyLOCAL = &PartitionSpec{Action: AnalyzeAction, IsAll: true} + yyLOCAL = &PartitionSpec{Action: ExchangeAction, Names: Partitions{yyDollar[3].identifierCI}, TableName: yyDollar[6].tableName, WithoutValidation: yyDollar[7].booleanUnion()} } yyVAL.union = yyLOCAL case 732: @@ -16476,7 +16608,7 @@ yydefault: var yyLOCAL *PartitionSpec //line sql.y:4073 { - yyLOCAL = &PartitionSpec{Action: CheckAction, Names: yyDollar[3].partitionsUnion()} + yyLOCAL = &PartitionSpec{Action: AnalyzeAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL case 733: @@ -16484,7 +16616,7 @@ yydefault: var yyLOCAL *PartitionSpec //line sql.y:4077 { - yyLOCAL = &PartitionSpec{Action: CheckAction, IsAll: true} + yyLOCAL = &PartitionSpec{Action: AnalyzeAction, IsAll: true} } yyVAL.union = yyLOCAL case 734: @@ -16492,7 +16624,7 @@ yydefault: var yyLOCAL *PartitionSpec //line sql.y:4081 { - yyLOCAL = &PartitionSpec{Action: OptimizeAction, Names: yyDollar[3].partitionsUnion()} + yyLOCAL = &PartitionSpec{Action: CheckAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL case 735: @@ -16500,7 +16632,7 @@ yydefault: var yyLOCAL *PartitionSpec //line sql.y:4085 { - yyLOCAL = &PartitionSpec{Action: OptimizeAction, IsAll: true} + yyLOCAL = &PartitionSpec{Action: CheckAction, IsAll: true} } yyVAL.union = yyLOCAL case 736: @@ -16508,7 +16640,7 @@ yydefault: var yyLOCAL *PartitionSpec //line sql.y:4089 { - yyLOCAL = &PartitionSpec{Action: RebuildAction, Names: yyDollar[3].partitionsUnion()} + yyLOCAL = &PartitionSpec{Action: OptimizeAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL case 737: @@ -16516,7 +16648,7 @@ yydefault: var yyLOCAL *PartitionSpec //line sql.y:4093 { - yyLOCAL = &PartitionSpec{Action: RebuildAction, IsAll: true} + yyLOCAL = &PartitionSpec{Action: OptimizeAction, IsAll: true} } yyVAL.union = yyLOCAL case 738: @@ -16524,7 +16656,7 @@ yydefault: var yyLOCAL *PartitionSpec //line sql.y:4097 { - yyLOCAL = &PartitionSpec{Action: RepairAction, Names: yyDollar[3].partitionsUnion()} + yyLOCAL = &PartitionSpec{Action: RebuildAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL case 739: @@ -16532,257 +16664,273 @@ yydefault: var yyLOCAL *PartitionSpec //line sql.y:4101 { - yyLOCAL = &PartitionSpec{Action: RepairAction, IsAll: true} + yyLOCAL = &PartitionSpec{Action: RebuildAction, IsAll: true} } yyVAL.union = yyLOCAL case 740: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec //line sql.y:4105 { - yyLOCAL = &PartitionSpec{Action: UpgradeAction} + yyLOCAL = &PartitionSpec{Action: RepairAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL case 741: + yyDollar = yyS[yypt-3 : yypt+1] + var yyLOCAL *PartitionSpec +//line sql.y:4109 + { + yyLOCAL = &PartitionSpec{Action: RepairAction, IsAll: true} + } + yyVAL.union = yyLOCAL + case 742: + yyDollar = yyS[yypt-2 : yypt+1] + var yyLOCAL *PartitionSpec +//line sql.y:4113 + { + yyLOCAL = &PartitionSpec{Action: UpgradeAction} + } + yyVAL.union = yyLOCAL + case 743: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:4110 +//line sql.y:4118 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 742: + case 744: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:4114 +//line sql.y:4122 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 743: + case 745: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:4118 +//line sql.y:4126 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 744: + case 746: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*PartitionDefinition -//line sql.y:4124 +//line sql.y:4132 { yyLOCAL = []*PartitionDefinition{yyDollar[1].partDefUnion()} } yyVAL.union = yyLOCAL - case 745: + case 747: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4128 +//line sql.y:4136 { yySLICE := (*[]*PartitionDefinition)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].partDefUnion()) } - case 746: + case 748: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4134 +//line sql.y:4142 { yyVAL.partDefUnion().Options = yyDollar[2].partitionDefinitionOptionsUnion() } - case 747: + case 749: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:4139 +//line sql.y:4147 { yyLOCAL = &PartitionDefinitionOptions{} } yyVAL.union = yyLOCAL - case 748: + case 750: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:4143 +//line sql.y:4151 { yyDollar[1].partitionDefinitionOptionsUnion().ValueRange = yyDollar[2].partitionValueRangeUnion() yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 749: + case 751: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:4148 +//line sql.y:4156 { yyDollar[1].partitionDefinitionOptionsUnion().Comment = yyDollar[2].literalUnion() yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 750: + case 752: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:4153 +//line sql.y:4161 { yyDollar[1].partitionDefinitionOptionsUnion().Engine = yyDollar[2].partitionEngineUnion() yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 751: + case 753: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:4158 +//line sql.y:4166 { yyDollar[1].partitionDefinitionOptionsUnion().DataDirectory = yyDollar[2].literalUnion() yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 752: + case 754: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:4163 +//line sql.y:4171 { yyDollar[1].partitionDefinitionOptionsUnion().IndexDirectory = yyDollar[2].literalUnion() yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 753: + case 755: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:4168 +//line sql.y:4176 { yyDollar[1].partitionDefinitionOptionsUnion().MaxRows = ptr.Of(yyDollar[2].integerUnion()) yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 754: + case 756: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:4173 +//line sql.y:4181 { yyDollar[1].partitionDefinitionOptionsUnion().MinRows = ptr.Of(yyDollar[2].integerUnion()) yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 755: + case 757: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:4178 +//line sql.y:4186 { yyDollar[1].partitionDefinitionOptionsUnion().TableSpace = yyDollar[2].str yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 756: + case 758: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinitionOptions -//line sql.y:4183 +//line sql.y:4191 { yyDollar[1].partitionDefinitionOptionsUnion().SubPartitionDefinitions = yyDollar[2].subPartitionDefinitionsUnion() yyLOCAL = yyDollar[1].partitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 757: + case 759: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL SubPartitionDefinitions -//line sql.y:4189 +//line sql.y:4197 { yyLOCAL = yyDollar[2].subPartitionDefinitionsUnion() } yyVAL.union = yyLOCAL - case 758: + case 760: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SubPartitionDefinitions -//line sql.y:4195 +//line sql.y:4203 { yyLOCAL = SubPartitionDefinitions{yyDollar[1].subPartitionDefinitionUnion()} } yyVAL.union = yyLOCAL - case 759: + case 761: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4199 +//line sql.y:4207 { yySLICE := (*SubPartitionDefinitions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].subPartitionDefinitionUnion()) } - case 760: + case 762: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SubPartitionDefinition -//line sql.y:4205 +//line sql.y:4213 { yyLOCAL = &SubPartitionDefinition{Name: yyDollar[2].identifierCI, Options: yyDollar[3].subPartitionDefinitionOptionsUnion()} } yyVAL.union = yyLOCAL - case 761: + case 763: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:4210 +//line sql.y:4218 { yyLOCAL = &SubPartitionDefinitionOptions{} } yyVAL.union = yyLOCAL - case 762: + case 764: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:4214 +//line sql.y:4222 { yyDollar[1].subPartitionDefinitionOptionsUnion().Comment = yyDollar[2].literalUnion() yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 763: + case 765: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:4219 +//line sql.y:4227 { yyDollar[1].subPartitionDefinitionOptionsUnion().Engine = yyDollar[2].partitionEngineUnion() yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 764: + case 766: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:4224 +//line sql.y:4232 { yyDollar[1].subPartitionDefinitionOptionsUnion().DataDirectory = yyDollar[2].literalUnion() yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 765: + case 767: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:4229 +//line sql.y:4237 { yyDollar[1].subPartitionDefinitionOptionsUnion().IndexDirectory = yyDollar[2].literalUnion() yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 766: + case 768: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:4234 +//line sql.y:4242 { yyDollar[1].subPartitionDefinitionOptionsUnion().MaxRows = ptr.Of(yyDollar[2].integerUnion()) yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 767: + case 769: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:4239 +//line sql.y:4247 { yyDollar[1].subPartitionDefinitionOptionsUnion().MinRows = ptr.Of(yyDollar[2].integerUnion()) yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 768: + case 770: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SubPartitionDefinitionOptions -//line sql.y:4244 +//line sql.y:4252 { yyDollar[1].subPartitionDefinitionOptionsUnion().TableSpace = yyDollar[2].str yyLOCAL = yyDollar[1].subPartitionDefinitionOptionsUnion() } yyVAL.union = yyLOCAL - case 769: + case 771: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionValueRange -//line sql.y:4251 +//line sql.y:4259 { yyLOCAL = &PartitionValueRange{ Type: LessThanType, @@ -16790,10 +16938,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 770: + case 772: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionValueRange -//line sql.y:4258 +//line sql.y:4266 { yyLOCAL = &PartitionValueRange{ Type: LessThanType, @@ -16801,10 +16949,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 771: + case 773: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionValueRange -//line sql.y:4265 +//line sql.y:4273 { yyLOCAL = &PartitionValueRange{ Type: InType, @@ -16812,131 +16960,131 @@ yydefault: } } yyVAL.union = yyLOCAL - case 772: + case 774: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:4273 +//line sql.y:4281 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 773: + case 775: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4277 +//line sql.y:4285 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 774: + case 776: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionEngine -//line sql.y:4283 +//line sql.y:4291 { yyLOCAL = &PartitionEngine{Storage: yyDollar[1].booleanUnion(), Name: yyDollar[4].identifierCS.String()} } yyVAL.union = yyLOCAL - case 775: + case 777: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *Literal -//line sql.y:4289 +//line sql.y:4297 { yyLOCAL = NewStrLiteral(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 776: + case 778: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Literal -//line sql.y:4295 +//line sql.y:4303 { yyLOCAL = NewStrLiteral(yyDollar[4].str) } yyVAL.union = yyLOCAL - case 777: + case 779: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Literal -//line sql.y:4301 +//line sql.y:4309 { yyLOCAL = NewStrLiteral(yyDollar[4].str) } yyVAL.union = yyLOCAL - case 778: + case 780: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int -//line sql.y:4307 +//line sql.y:4315 { yyLOCAL = convertStringToInt(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 779: + case 781: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int -//line sql.y:4313 +//line sql.y:4321 { yyLOCAL = convertStringToInt(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 780: + case 782: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4319 +//line sql.y:4327 { yyVAL.str = yyDollar[3].identifierCS.String() } - case 781: + case 783: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionDefinition -//line sql.y:4325 +//line sql.y:4333 { yyLOCAL = &PartitionDefinition{Name: yyDollar[2].identifierCI} } yyVAL.union = yyLOCAL - case 782: + case 784: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4331 +//line sql.y:4339 { yyVAL.str = "" } - case 783: + case 785: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4335 +//line sql.y:4343 { yyVAL.str = "" } - case 784: + case 786: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4341 +//line sql.y:4349 { yyLOCAL = &RenameTable{TablePairs: yyDollar[3].renameTablePairsUnion()} } yyVAL.union = yyLOCAL - case 785: + case 787: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*RenameTablePair -//line sql.y:4347 +//line sql.y:4355 { yyLOCAL = []*RenameTablePair{{FromTable: yyDollar[1].tableName, ToTable: yyDollar[3].tableName}} } yyVAL.union = yyLOCAL - case 786: + case 788: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:4351 +//line sql.y:4359 { yySLICE := (*[]*RenameTablePair)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, &RenameTablePair{FromTable: yyDollar[3].tableName, ToTable: yyDollar[5].tableName}) } - case 787: + case 789: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:4357 +//line sql.y:4365 { yyLOCAL = &DropTable{FromTables: yyDollar[6].tableNamesUnion(), IfExists: yyDollar[5].booleanUnion(), Comments: Comments(yyDollar[2].strs).Parsed(), Temp: yyDollar[3].booleanUnion()} } yyVAL.union = yyLOCAL - case 788: + case 790: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:4361 +//line sql.y:4369 { // Change this to an alter statement if yyDollar[4].identifierCI.Lowered() == "primary" { @@ -16946,92 +17094,76 @@ yydefault: } } yyVAL.union = yyLOCAL - case 789: + case 791: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:4370 +//line sql.y:4378 { yyLOCAL = &DropView{FromTables: yyDollar[5].tableNamesUnion(), Comments: Comments(yyDollar[2].strs).Parsed(), IfExists: yyDollar[4].booleanUnion()} } yyVAL.union = yyLOCAL - case 790: + case 792: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4374 +//line sql.y:4382 { yyLOCAL = &DropDatabase{Comments: Comments(yyDollar[2].strs).Parsed(), DBName: yyDollar[5].identifierCS, IfExists: yyDollar[4].booleanUnion()} } yyVAL.union = yyLOCAL - case 791: + case 793: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4378 +//line sql.y:4386 { yyLOCAL = &DropProcedure{Comments: Comments(yyDollar[2].strs).Parsed(), Name: yyDollar[5].tableName, IfExists: yyDollar[4].booleanUnion()} } yyVAL.union = yyLOCAL - case 792: + case 794: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4384 +//line sql.y:4392 { yyLOCAL = &TruncateTable{Table: yyDollar[3].tableName} } yyVAL.union = yyLOCAL - case 793: + case 795: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4388 +//line sql.y:4396 { yyLOCAL = &TruncateTable{Table: yyDollar[2].tableName} } yyVAL.union = yyLOCAL - case 794: + case 796: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4394 +//line sql.y:4402 { yyLOCAL = &Analyze{IsLocal: yyDollar[2].booleanUnion(), Table: yyDollar[4].tableName} } yyVAL.union = yyLOCAL - case 795: + case 797: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4400 +//line sql.y:4408 { yyLOCAL = &PurgeBinaryLogs{To: string(yyDollar[5].str)} } yyVAL.union = yyLOCAL - case 796: + case 798: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4404 +//line sql.y:4412 { yyLOCAL = &PurgeBinaryLogs{Before: string(yyDollar[5].str)} } yyVAL.union = yyLOCAL - case 797: - yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL Statement -//line sql.y:4410 - { - yyLOCAL = &Show{&ShowBasic{Command: Charset, Filter: yyDollar[3].showFilterUnion()}} - } - yyVAL.union = yyLOCAL - case 798: - yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL Statement -//line sql.y:4414 - { - yyLOCAL = &Show{&ShowBasic{Command: Collation, Filter: yyDollar[3].showFilterUnion()}} - } - yyVAL.union = yyLOCAL case 799: - yyDollar = yyS[yypt-7 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement //line sql.y:4418 { - yyLOCAL = &Show{&ShowBasic{Full: yyDollar[2].booleanUnion(), Command: Column, Tbl: yyDollar[5].tableName, DbName: yyDollar[6].identifierCS, Filter: yyDollar[7].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: Charset, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL case 800: @@ -17039,15 +17171,15 @@ yydefault: var yyLOCAL Statement //line sql.y:4422 { - yyLOCAL = &Show{&ShowBasic{Command: Database, Filter: yyDollar[3].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: Collation, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL case 801: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement //line sql.y:4426 { - yyLOCAL = &Show{&ShowBasic{Command: Database, Filter: yyDollar[3].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Full: yyDollar[2].booleanUnion(), Command: Column, Tbl: yyDollar[5].tableName, DbName: yyDollar[6].identifierCS, Filter: yyDollar[7].showFilterUnion()}} } yyVAL.union = yyLOCAL case 802: @@ -17055,7 +17187,7 @@ yydefault: var yyLOCAL Statement //line sql.y:4430 { - yyLOCAL = &Show{&ShowBasic{Command: Keyspace, Filter: yyDollar[3].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: Database, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL case 803: @@ -17063,55 +17195,55 @@ yydefault: var yyLOCAL Statement //line sql.y:4434 { - yyLOCAL = &Show{&ShowBasic{Command: Keyspace, Filter: yyDollar[3].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: Database, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL case 804: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement //line sql.y:4438 { - yyLOCAL = &Show{&ShowBasic{Command: Function, Filter: yyDollar[4].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: Keyspace, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL case 805: - yyDollar = yyS[yypt-7 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement //line sql.y:4442 { - yyLOCAL = &Show{&ShowBasic{Command: Index, Tbl: yyDollar[5].tableName, DbName: yyDollar[6].identifierCS, Filter: yyDollar[7].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: Keyspace, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL case 806: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement //line sql.y:4446 { - yyLOCAL = &Show{&ShowBasic{Command: OpenTable, DbName: yyDollar[4].identifierCS, Filter: yyDollar[5].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: Function, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL case 807: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement //line sql.y:4450 { - yyLOCAL = &Show{&ShowBasic{Command: Privilege}} + yyLOCAL = &Show{&ShowBasic{Command: Index, Tbl: yyDollar[5].tableName, DbName: yyDollar[6].identifierCS, Filter: yyDollar[7].showFilterUnion()}} } yyVAL.union = yyLOCAL case 808: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement //line sql.y:4454 { - yyLOCAL = &Show{&ShowBasic{Command: Procedure, Filter: yyDollar[4].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: OpenTable, DbName: yyDollar[4].identifierCS, Filter: yyDollar[5].showFilterUnion()}} } yyVAL.union = yyLOCAL case 809: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement //line sql.y:4458 { - yyLOCAL = &Show{&ShowBasic{Command: StatusSession, Filter: yyDollar[4].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: Privilege}} } yyVAL.union = yyLOCAL case 810: @@ -17119,7 +17251,7 @@ yydefault: var yyLOCAL Statement //line sql.y:4462 { - yyLOCAL = &Show{&ShowBasic{Command: StatusGlobal, Filter: yyDollar[4].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: Procedure, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL case 811: @@ -17127,7 +17259,7 @@ yydefault: var yyLOCAL Statement //line sql.y:4466 { - yyLOCAL = &Show{&ShowBasic{Command: VariableSession, Filter: yyDollar[4].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: StatusSession, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL case 812: @@ -17135,39 +17267,39 @@ yydefault: var yyLOCAL Statement //line sql.y:4470 { - yyLOCAL = &Show{&ShowBasic{Command: VariableGlobal, Filter: yyDollar[4].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: StatusGlobal, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL case 813: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement //line sql.y:4474 { - yyLOCAL = &Show{&ShowBasic{Command: TableStatus, DbName: yyDollar[4].identifierCS, Filter: yyDollar[5].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: VariableSession, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL case 814: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement //line sql.y:4478 { - yyLOCAL = &Show{&ShowBasic{Command: Table, Full: yyDollar[2].booleanUnion(), DbName: yyDollar[4].identifierCS, Filter: yyDollar[5].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: VariableGlobal, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL case 815: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement //line sql.y:4482 { - yyLOCAL = &Show{&ShowBasic{Command: Trigger, DbName: yyDollar[3].identifierCS, Filter: yyDollar[4].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: TableStatus, DbName: yyDollar[4].identifierCS, Filter: yyDollar[5].showFilterUnion()}} } yyVAL.union = yyLOCAL case 816: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement //line sql.y:4486 { - yyLOCAL = &Show{&ShowCreate{Command: CreateDb, Op: yyDollar[4].tableName}} + yyLOCAL = &Show{&ShowBasic{Command: Table, Full: yyDollar[2].booleanUnion(), DbName: yyDollar[4].identifierCS, Filter: yyDollar[5].showFilterUnion()}} } yyVAL.union = yyLOCAL case 817: @@ -17175,7 +17307,7 @@ yydefault: var yyLOCAL Statement //line sql.y:4490 { - yyLOCAL = &Show{&ShowCreate{Command: CreateE, Op: yyDollar[4].tableName}} + yyLOCAL = &Show{&ShowBasic{Command: Trigger, DbName: yyDollar[3].identifierCS, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL case 818: @@ -17183,7 +17315,7 @@ yydefault: var yyLOCAL Statement //line sql.y:4494 { - yyLOCAL = &Show{&ShowCreate{Command: CreateF, Op: yyDollar[4].tableName}} + yyLOCAL = &Show{&ShowCreate{Command: CreateDb, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL case 819: @@ -17191,7 +17323,7 @@ yydefault: var yyLOCAL Statement //line sql.y:4498 { - yyLOCAL = &Show{&ShowCreate{Command: CreateProc, Op: yyDollar[4].tableName}} + yyLOCAL = &Show{&ShowCreate{Command: CreateE, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL case 820: @@ -17199,7 +17331,7 @@ yydefault: var yyLOCAL Statement //line sql.y:4502 { - yyLOCAL = &Show{&ShowCreate{Command: CreateTbl, Op: yyDollar[4].tableName}} + yyLOCAL = &Show{&ShowCreate{Command: CreateF, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL case 821: @@ -17207,7 +17339,7 @@ yydefault: var yyLOCAL Statement //line sql.y:4506 { - yyLOCAL = &Show{&ShowCreate{Command: CreateTr, Op: yyDollar[4].tableName}} + yyLOCAL = &Show{&ShowCreate{Command: CreateProc, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL case 822: @@ -17215,39 +17347,39 @@ yydefault: var yyLOCAL Statement //line sql.y:4510 { - yyLOCAL = &Show{&ShowCreate{Command: CreateV, Op: yyDollar[4].tableName}} + yyLOCAL = &Show{&ShowCreate{Command: CreateTbl, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL case 823: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement //line sql.y:4514 { - yyLOCAL = &Show{&ShowBasic{Command: Engines}} + yyLOCAL = &Show{&ShowCreate{Command: CreateTr, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL case 824: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement //line sql.y:4518 { - yyLOCAL = &Show{&ShowBasic{Command: Plugins}} + yyLOCAL = &Show{&ShowCreate{Command: CreateV, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL case 825: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement //line sql.y:4522 { - yyLOCAL = &Show{&ShowBasic{Command: GtidExecGlobal, DbName: yyDollar[4].identifierCS}} + yyLOCAL = &Show{&ShowBasic{Command: Engines}} } yyVAL.union = yyLOCAL case 826: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement //line sql.y:4526 { - yyLOCAL = &Show{&ShowBasic{Command: VGtidExecGlobal, DbName: yyDollar[4].identifierCS}} + yyLOCAL = &Show{&ShowBasic{Command: Plugins}} } yyVAL.union = yyLOCAL case 827: @@ -17255,7 +17387,7 @@ yydefault: var yyLOCAL Statement //line sql.y:4530 { - yyLOCAL = &Show{&ShowBasic{Command: VitessVariables, Filter: yyDollar[4].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: GtidExecGlobal, DbName: yyDollar[4].identifierCS}} } yyVAL.union = yyLOCAL case 828: @@ -17263,7 +17395,7 @@ yydefault: var yyLOCAL Statement //line sql.y:4534 { - yyLOCAL = &Show{&ShowBasic{Command: VitessMigrations, Filter: yyDollar[4].showFilterUnion(), DbName: yyDollar[3].identifierCS}} + yyLOCAL = &Show{&ShowBasic{Command: VGtidExecGlobal, DbName: yyDollar[4].identifierCS}} } yyVAL.union = yyLOCAL case 829: @@ -17271,31 +17403,31 @@ yydefault: var yyLOCAL Statement //line sql.y:4538 { - yyLOCAL = &ShowMigrationLogs{UUID: string(yyDollar[3].str)} + yyLOCAL = &Show{&ShowBasic{Command: VitessVariables, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL case 830: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement //line sql.y:4542 { - yyLOCAL = &ShowThrottledApps{} + yyLOCAL = &Show{&ShowBasic{Command: VitessMigrations, Filter: yyDollar[4].showFilterUnion(), DbName: yyDollar[3].identifierCS}} } yyVAL.union = yyLOCAL case 831: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement //line sql.y:4546 { - yyLOCAL = &Show{&ShowBasic{Command: VitessReplicationStatus, Filter: yyDollar[3].showFilterUnion()}} + yyLOCAL = &ShowMigrationLogs{UUID: string(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 832: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement //line sql.y:4550 { - yyLOCAL = &ShowThrottlerStatus{} + yyLOCAL = &ShowThrottledApps{} } yyVAL.union = yyLOCAL case 833: @@ -17303,7 +17435,7 @@ yydefault: var yyLOCAL Statement //line sql.y:4554 { - yyLOCAL = &Show{&ShowBasic{Command: VschemaTables}} + yyLOCAL = &Show{&ShowBasic{Command: VitessReplicationStatus, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL case 834: @@ -17311,7 +17443,7 @@ yydefault: var yyLOCAL Statement //line sql.y:4558 { - yyLOCAL = &Show{&ShowBasic{Command: VschemaKeyspaces}} + yyLOCAL = &ShowThrottlerStatus{} } yyVAL.union = yyLOCAL case 835: @@ -17319,71 +17451,71 @@ yydefault: var yyLOCAL Statement //line sql.y:4562 { - yyLOCAL = &Show{&ShowBasic{Command: VschemaVindexes}} + yyLOCAL = &Show{&ShowBasic{Command: VschemaTables}} } yyVAL.union = yyLOCAL case 836: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement //line sql.y:4566 { - yyLOCAL = &Show{&ShowBasic{Command: VschemaVindexes, Tbl: yyDollar[5].tableName}} + yyLOCAL = &Show{&ShowBasic{Command: VschemaKeyspaces}} } yyVAL.union = yyLOCAL case 837: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement //line sql.y:4570 { - yyLOCAL = &Show{&ShowBasic{Command: Warnings}} + yyLOCAL = &Show{&ShowBasic{Command: VschemaVindexes}} } yyVAL.union = yyLOCAL case 838: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement //line sql.y:4574 { - yyLOCAL = &Show{&ShowBasic{Command: VitessShards, Filter: yyDollar[3].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: VschemaVindexes, Tbl: yyDollar[5].tableName}} } yyVAL.union = yyLOCAL case 839: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement //line sql.y:4578 { - yyLOCAL = &Show{&ShowBasic{Command: VitessTablets, Filter: yyDollar[3].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: Warnings}} } yyVAL.union = yyLOCAL case 840: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement //line sql.y:4582 { - yyLOCAL = &Show{&ShowBasic{Command: VitessTarget}} + yyLOCAL = &Show{&ShowBasic{Command: VitessShards, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL case 841: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4589 +//line sql.y:4586 { - yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].identifierCI.String())}} + yyLOCAL = &Show{&ShowBasic{Command: VitessTablets, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL case 842: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4593 +//line sql.y:4590 { - yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + string(yyDollar[3].str)}} + yyLOCAL = &Show{&ShowBasic{Command: VitessTarget}} } yyVAL.union = yyLOCAL case 843: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement //line sql.y:4597 { - yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + yyDollar[3].identifierCI.String()}} + yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].identifierCI.String())}} } yyVAL.union = yyLOCAL case 844: @@ -17395,11 +17527,11 @@ yydefault: } yyVAL.union = yyLOCAL case 845: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement //line sql.y:4605 { - yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str)}} + yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + yyDollar[3].identifierCI.String()}} } yyVAL.union = yyLOCAL case 846: @@ -17407,31 +17539,31 @@ yydefault: var yyLOCAL Statement //line sql.y:4609 { - yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + string(yyDollar[3].str) + " " + String(yyDollar[4].tableName)}} + yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + string(yyDollar[3].str)}} } yyVAL.union = yyLOCAL case 847: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement //line sql.y:4613 { - yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + string(yyDollar[3].str) + " " + String(yyDollar[4].tableName)}} + yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str)}} } yyVAL.union = yyLOCAL case 848: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement //line sql.y:4617 { - yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[3].str)}} + yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + string(yyDollar[3].str) + " " + String(yyDollar[4].tableName)}} } yyVAL.union = yyLOCAL case 849: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement //line sql.y:4621 { - yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str)}} + yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str) + " " + string(yyDollar[3].str) + " " + String(yyDollar[4].tableName)}} } yyVAL.union = yyLOCAL case 850: @@ -17439,7 +17571,7 @@ yydefault: var yyLOCAL Statement //line sql.y:4625 { - yyLOCAL = &Show{&ShowTransactionStatus{TransactionID: string(yyDollar[5].str)}} + yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[3].str)}} } yyVAL.union = yyLOCAL case 851: @@ -17447,7 +17579,7 @@ yydefault: var yyLOCAL Statement //line sql.y:4629 { - yyLOCAL = &Show{&ShowTransactionStatus{}} + yyLOCAL = &Show{&ShowOther{Command: string(yyDollar[2].str)}} } yyVAL.union = yyLOCAL case 852: @@ -17455,677 +17587,681 @@ yydefault: var yyLOCAL Statement //line sql.y:4633 { - yyLOCAL = &Show{&ShowTransactionStatus{Keyspace: yyDollar[5].identifierCS.String()}} + yyLOCAL = &Show{&ShowTransactionStatus{TransactionID: string(yyDollar[5].str)}} } yyVAL.union = yyLOCAL case 853: - yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4638 + yyDollar = yyS[yypt-3 : yypt+1] + var yyLOCAL Statement +//line sql.y:4637 { + yyLOCAL = &Show{&ShowTransactionStatus{}} } + yyVAL.union = yyLOCAL case 854: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4640 + yyDollar = yyS[yypt-5 : yypt+1] + var yyLOCAL Statement +//line sql.y:4641 { + yyLOCAL = &Show{&ShowTransactionStatus{Keyspace: yyDollar[5].identifierCS.String()}} } + yyVAL.union = yyLOCAL case 855: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4644 +//line sql.y:4646 { - yyVAL.str = "" } case 856: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:4648 { - yyVAL.str = "extended " } case 857: yyDollar = yyS[yypt-0 : yypt+1] +//line sql.y:4652 + { + yyVAL.str = "" + } + case 858: + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:4656 + { + yyVAL.str = "extended " + } + case 859: + yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:4654 +//line sql.y:4662 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 858: + case 860: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4658 +//line sql.y:4666 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 859: + case 861: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4664 +//line sql.y:4672 { yyVAL.str = string(yyDollar[1].str) } - case 860: + case 862: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4668 +//line sql.y:4676 { yyVAL.str = string(yyDollar[1].str) } - case 861: + case 863: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4674 +//line sql.y:4682 { yyVAL.identifierCS = NewIdentifierCS("") } - case 862: + case 864: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4678 +//line sql.y:4686 { yyVAL.identifierCS = yyDollar[2].identifierCS } - case 863: + case 865: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4682 +//line sql.y:4690 { yyVAL.identifierCS = yyDollar[2].identifierCS } - case 864: + case 866: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4688 +//line sql.y:4696 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 865: + case 867: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4692 +//line sql.y:4700 { yyLOCAL = &ShowFilter{Like: string(yyDollar[2].str)} } yyVAL.union = yyLOCAL - case 866: + case 868: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4696 +//line sql.y:4704 { yyLOCAL = &ShowFilter{Filter: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 867: + case 869: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4702 +//line sql.y:4710 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 868: + case 870: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:4706 +//line sql.y:4714 { yyLOCAL = &ShowFilter{Like: string(yyDollar[2].str)} } yyVAL.union = yyLOCAL - case 869: + case 871: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4712 +//line sql.y:4720 { yyVAL.empty = struct{}{} } - case 870: + case 872: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4716 +//line sql.y:4724 { yyVAL.empty = struct{}{} } - case 871: + case 873: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4720 +//line sql.y:4728 { yyVAL.empty = struct{}{} } - case 872: + case 874: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4726 +//line sql.y:4734 { yyVAL.str = string(yyDollar[1].str) } - case 873: + case 875: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4730 +//line sql.y:4738 { yyVAL.str = string(yyDollar[1].str) } - case 874: + case 876: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4736 +//line sql.y:4744 { yyLOCAL = &Use{DBName: yyDollar[2].identifierCS} } yyVAL.union = yyLOCAL - case 875: + case 877: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4740 +//line sql.y:4748 { yyLOCAL = &Use{DBName: IdentifierCS{v: ""}} } yyVAL.union = yyLOCAL - case 876: + case 878: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4744 +//line sql.y:4752 { yyLOCAL = &Use{DBName: NewIdentifierCS(yyDollar[2].identifierCS.String() + "@" + string(yyDollar[3].str))} } yyVAL.union = yyLOCAL - case 877: + case 879: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4751 +//line sql.y:4759 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 878: + case 880: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4755 +//line sql.y:4763 { yyVAL.identifierCS = NewIdentifierCS("@" + string(yyDollar[1].str)) } - case 879: + case 881: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4759 +//line sql.y:4767 { yyVAL.identifierCS = NewIdentifierCS("@@" + string(yyDollar[1].str)) } - case 880: + case 882: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4763 +//line sql.y:4771 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 881: + case 883: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4770 +//line sql.y:4778 { yyLOCAL = &Begin{Type: BeginStmt} } yyVAL.union = yyLOCAL - case 882: + case 884: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4774 +//line sql.y:4782 { yyLOCAL = &Begin{Type: StartTransactionStmt, TxAccessModes: yyDollar[3].txAccessModesUnion()} } yyVAL.union = yyLOCAL - case 883: + case 885: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []TxAccessMode -//line sql.y:4779 +//line sql.y:4787 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 884: + case 886: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []TxAccessMode -//line sql.y:4783 +//line sql.y:4791 { yyLOCAL = yyDollar[1].txAccessModesUnion() } yyVAL.union = yyLOCAL - case 885: + case 887: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []TxAccessMode -//line sql.y:4789 +//line sql.y:4797 { yyLOCAL = []TxAccessMode{yyDollar[1].txAccessModeUnion()} } yyVAL.union = yyLOCAL - case 886: + case 888: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4793 +//line sql.y:4801 { yySLICE := (*[]TxAccessMode)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].txAccessModeUnion()) } - case 887: + case 889: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL TxAccessMode -//line sql.y:4799 +//line sql.y:4807 { yyLOCAL = WithConsistentSnapshot } yyVAL.union = yyLOCAL - case 888: + case 890: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL TxAccessMode -//line sql.y:4803 +//line sql.y:4811 { yyLOCAL = ReadWrite } yyVAL.union = yyLOCAL - case 889: + case 891: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL TxAccessMode -//line sql.y:4807 +//line sql.y:4815 { yyLOCAL = ReadOnly } yyVAL.union = yyLOCAL - case 890: + case 892: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4814 +//line sql.y:4822 { yyLOCAL = &Commit{} } yyVAL.union = yyLOCAL - case 891: + case 893: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4820 +//line sql.y:4828 { yyLOCAL = &Rollback{} } yyVAL.union = yyLOCAL - case 892: + case 894: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4824 +//line sql.y:4832 { yyLOCAL = &SRollback{Name: yyDollar[5].identifierCI} } yyVAL.union = yyLOCAL - case 893: + case 895: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4829 +//line sql.y:4837 { yyVAL.empty = struct{}{} } - case 894: + case 896: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4831 +//line sql.y:4839 { yyVAL.empty = struct{}{} } - case 895: + case 897: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4834 +//line sql.y:4842 { yyVAL.empty = struct{}{} } - case 896: + case 898: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4836 +//line sql.y:4844 { yyVAL.empty = struct{}{} } - case 897: + case 899: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4840 +//line sql.y:4848 { yyLOCAL = &Savepoint{Name: yyDollar[2].identifierCI} } yyVAL.union = yyLOCAL - case 898: + case 900: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4846 +//line sql.y:4854 { yyLOCAL = &Release{Name: yyDollar[3].identifierCI} } yyVAL.union = yyLOCAL - case 899: + case 901: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL ExplainType -//line sql.y:4851 +//line sql.y:4859 { yyLOCAL = EmptyType } yyVAL.union = yyLOCAL - case 900: + case 902: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ExplainType -//line sql.y:4855 +//line sql.y:4863 { yyLOCAL = JSONType } yyVAL.union = yyLOCAL - case 901: + case 903: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ExplainType -//line sql.y:4859 +//line sql.y:4867 { yyLOCAL = TreeType } yyVAL.union = yyLOCAL - case 902: + case 904: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ExplainType -//line sql.y:4863 +//line sql.y:4871 { yyLOCAL = TraditionalType } yyVAL.union = yyLOCAL - case 903: + case 905: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ExplainType -//line sql.y:4867 +//line sql.y:4875 { yyLOCAL = AnalyzeType } yyVAL.union = yyLOCAL - case 904: + case 906: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL VExplainType -//line sql.y:4872 +//line sql.y:4880 { yyLOCAL = PlanVExplainType } yyVAL.union = yyLOCAL - case 905: + case 907: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL VExplainType -//line sql.y:4876 +//line sql.y:4884 { yyLOCAL = PlanVExplainType } yyVAL.union = yyLOCAL - case 906: + case 908: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL VExplainType -//line sql.y:4880 +//line sql.y:4888 { yyLOCAL = AllVExplainType } yyVAL.union = yyLOCAL - case 907: + case 909: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL VExplainType -//line sql.y:4884 +//line sql.y:4892 { yyLOCAL = QueriesVExplainType } yyVAL.union = yyLOCAL - case 908: + case 910: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL VExplainType -//line sql.y:4888 +//line sql.y:4896 { yyLOCAL = TraceVExplainType } yyVAL.union = yyLOCAL - case 909: + case 911: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL VExplainType -//line sql.y:4892 +//line sql.y:4900 { yyLOCAL = KeysVExplainType } yyVAL.union = yyLOCAL - case 910: + case 912: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4898 +//line sql.y:4906 { yyVAL.str = yyDollar[1].str } - case 911: + case 913: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4902 +//line sql.y:4910 { yyVAL.str = yyDollar[1].str } - case 912: + case 914: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4906 +//line sql.y:4914 { yyVAL.str = yyDollar[1].str } - case 913: + case 915: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4912 +//line sql.y:4920 { yyLOCAL = yyDollar[1].tableStmtUnion() } yyVAL.union = yyLOCAL - case 914: + case 916: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4916 +//line sql.y:4924 { yyLOCAL = yyDollar[1].statementUnion() } yyVAL.union = yyLOCAL - case 915: + case 917: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4920 +//line sql.y:4928 { yyLOCAL = yyDollar[1].statementUnion() } yyVAL.union = yyLOCAL - case 916: + case 918: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:4924 +//line sql.y:4932 { yyLOCAL = yyDollar[1].statementUnion() } yyVAL.union = yyLOCAL - case 917: + case 919: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4929 +//line sql.y:4937 { yyVAL.str = "" } - case 918: + case 920: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4933 +//line sql.y:4941 { yyVAL.str = yyDollar[1].identifierCI.val } - case 919: + case 921: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4937 +//line sql.y:4945 { yyVAL.str = encodeSQLString(yyDollar[1].str) } - case 920: + case 922: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4943 +//line sql.y:4951 { yyLOCAL = &ExplainTab{Table: yyDollar[3].tableName, Wild: yyDollar[4].str} } yyVAL.union = yyLOCAL - case 921: + case 923: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4947 +//line sql.y:4955 { yyLOCAL = &ExplainStmt{Type: yyDollar[3].explainTypeUnion(), Statement: yyDollar[4].statementUnion(), Comments: Comments(yyDollar[2].strs).Parsed()} } yyVAL.union = yyLOCAL - case 922: + case 924: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:4953 +//line sql.y:4961 { yyLOCAL = &VExplainStmt{Type: yyDollar[3].vexplainTypeUnion(), Statement: yyDollar[4].statementUnion(), Comments: Comments(yyDollar[2].strs).Parsed()} } yyVAL.union = yyLOCAL - case 923: + case 925: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4959 +//line sql.y:4967 { yyLOCAL = &OtherAdmin{} } yyVAL.union = yyLOCAL - case 924: + case 926: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:4963 +//line sql.y:4971 { yyLOCAL = &OtherAdmin{} } yyVAL.union = yyLOCAL - case 925: + case 927: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:4969 +//line sql.y:4977 { yyLOCAL = &LockTables{Tables: yyDollar[3].tableAndLockTypesUnion()} } yyVAL.union = yyLOCAL - case 926: + case 928: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableAndLockTypes -//line sql.y:4975 +//line sql.y:4983 { yyLOCAL = TableAndLockTypes{yyDollar[1].tableAndLockTypeUnion()} } yyVAL.union = yyLOCAL - case 927: + case 929: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4979 +//line sql.y:4987 { yySLICE := (*TableAndLockTypes)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableAndLockTypeUnion()) } - case 928: + case 930: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *TableAndLockType -//line sql.y:4985 +//line sql.y:4993 { yyLOCAL = &TableAndLockType{Table: yyDollar[1].aliasedTableNameUnion(), Lock: yyDollar[2].lockTypeUnion()} } yyVAL.union = yyLOCAL - case 929: + case 931: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL LockType -//line sql.y:4991 +//line sql.y:4999 { yyLOCAL = Read } yyVAL.union = yyLOCAL - case 930: + case 932: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL LockType -//line sql.y:4995 +//line sql.y:5003 { yyLOCAL = ReadLocal } yyVAL.union = yyLOCAL - case 931: + case 933: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL LockType -//line sql.y:4999 +//line sql.y:5007 { yyLOCAL = Write } yyVAL.union = yyLOCAL - case 932: + case 934: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL LockType -//line sql.y:5003 +//line sql.y:5011 { yyLOCAL = LowPriorityWrite } yyVAL.union = yyLOCAL - case 933: + case 935: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:5009 +//line sql.y:5017 { yyLOCAL = &UnlockTables{} } yyVAL.union = yyLOCAL - case 934: + case 936: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:5015 +//line sql.y:5023 { yyLOCAL = &RevertMigration{Comments: Comments(yyDollar[2].strs).Parsed(), UUID: string(yyDollar[4].str)} } yyVAL.union = yyLOCAL - case 935: + case 937: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:5021 +//line sql.y:5029 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), FlushOptions: yyDollar[3].strs} } yyVAL.union = yyLOCAL - case 936: + case 938: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:5025 +//line sql.y:5033 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion()} } yyVAL.union = yyLOCAL - case 937: + case 939: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:5029 +//line sql.y:5037 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), WithLock: true} } yyVAL.union = yyLOCAL - case 938: + case 940: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:5033 +//line sql.y:5041 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), TableNames: yyDollar[4].tableNamesUnion()} } yyVAL.union = yyLOCAL - case 939: + case 941: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:5037 +//line sql.y:5045 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), TableNames: yyDollar[4].tableNamesUnion(), WithLock: true} } yyVAL.union = yyLOCAL - case 940: + case 942: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:5041 +//line sql.y:5049 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), TableNames: yyDollar[4].tableNamesUnion(), ForExport: true} } yyVAL.union = yyLOCAL - case 941: + case 943: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5047 +//line sql.y:5055 { yyVAL.strs = []string{yyDollar[1].str} } - case 942: + case 944: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5051 +//line sql.y:5059 { yyVAL.strs = append(yyDollar[1].strs, yyDollar[3].str) } - case 943: - yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5057 - { - yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) - } - case 944: - yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5061 - { - yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) - } case 945: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:5065 @@ -18139,16 +18275,16 @@ yydefault: yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) } case 947: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:5073 { - yyVAL.str = string(yyDollar[1].str) + yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) } case 948: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:5077 { - yyVAL.str = string(yyDollar[1].str) + yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) } case 949: yyDollar = yyS[yypt-1 : yypt+1] @@ -18157,28 +18293,28 @@ yydefault: yyVAL.str = string(yyDollar[1].str) } case 950: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:5085 { - yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) + yyDollar[3].str + yyVAL.str = string(yyDollar[1].str) } case 951: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:5089 { - yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) + yyVAL.str = string(yyDollar[1].str) } case 952: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:5093 { - yyVAL.str = string(yyDollar[1].str) + yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) + yyDollar[3].str } case 953: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:5097 { - yyVAL.str = string(yyDollar[1].str) + yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) } case 954: yyDollar = yyS[yypt-1 : yypt+1] @@ -18187,144 +18323,156 @@ yydefault: yyVAL.str = string(yyDollar[1].str) } case 955: + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:5105 + { + yyVAL.str = string(yyDollar[1].str) + } + case 956: + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:5109 + { + yyVAL.str = string(yyDollar[1].str) + } + case 957: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:5106 +//line sql.y:5114 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 956: + case 958: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:5110 +//line sql.y:5118 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 957: + case 959: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:5114 +//line sql.y:5122 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 958: + case 960: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5119 +//line sql.y:5127 { yyVAL.str = "" } - case 959: + case 961: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5123 +//line sql.y:5131 { yyVAL.str = " " + string(yyDollar[1].str) + " " + string(yyDollar[2].str) + " " + yyDollar[3].identifierCI.String() } - case 960: + case 962: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5128 +//line sql.y:5136 { setAllowComments(yylex, true) } - case 961: + case 963: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5132 +//line sql.y:5140 { yyVAL.strs = yyDollar[2].strs setAllowComments(yylex, false) } - case 962: + case 964: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5138 +//line sql.y:5146 { yyVAL.strs = nil } - case 963: + case 965: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5142 +//line sql.y:5150 { yyVAL.strs = append(yyDollar[1].strs, yyDollar[2].str) } - case 964: + case 966: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:5148 +//line sql.y:5156 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 965: + case 967: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:5152 +//line sql.y:5160 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 966: + case 968: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:5156 +//line sql.y:5164 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 967: + case 969: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5161 +//line sql.y:5169 { yyVAL.str = "" } - case 968: + case 970: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5165 +//line sql.y:5173 { yyVAL.str = SQLNoCacheStr } - case 969: + case 971: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5169 +//line sql.y:5177 { yyVAL.str = SQLCacheStr } - case 970: + case 972: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:5174 +//line sql.y:5182 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 971: + case 973: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:5178 +//line sql.y:5186 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 972: + case 974: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:5182 +//line sql.y:5190 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 973: + case 975: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:5188 +//line sql.y:5196 { yyLOCAL = &PrepareStmt{Name: yyDollar[3].identifierCI, Comments: Comments(yyDollar[2].strs).Parsed(), Statement: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 974: + case 976: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:5192 +//line sql.y:5200 { yyLOCAL = &PrepareStmt{ Name: yyDollar[3].identifierCI, @@ -18333,604 +18481,600 @@ yydefault: } } yyVAL.union = yyLOCAL - case 975: + case 977: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:5202 +//line sql.y:5210 { yyLOCAL = &ExecuteStmt{Name: yyDollar[3].identifierCI, Comments: Comments(yyDollar[2].strs).Parsed(), Arguments: yyDollar[4].variablesUnion()} } yyVAL.union = yyLOCAL - case 976: + case 978: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*Variable -//line sql.y:5207 +//line sql.y:5215 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 977: + case 979: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []*Variable -//line sql.y:5211 +//line sql.y:5219 { yyLOCAL = yyDollar[2].variablesUnion() } yyVAL.union = yyLOCAL - case 978: + case 980: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:5217 +//line sql.y:5225 { yyLOCAL = &DeallocateStmt{Comments: Comments(yyDollar[2].strs).Parsed(), Name: yyDollar[4].identifierCI} } yyVAL.union = yyLOCAL - case 979: + case 981: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:5221 +//line sql.y:5229 { yyLOCAL = &DeallocateStmt{Comments: Comments(yyDollar[2].strs).Parsed(), Name: yyDollar[4].identifierCI} } yyVAL.union = yyLOCAL - case 980: + case 982: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5226 +//line sql.y:5234 { yyVAL.strs = nil } - case 981: + case 983: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5230 +//line sql.y:5238 { yyVAL.strs = yyDollar[1].strs } - case 982: + case 984: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5236 +//line sql.y:5244 { yyVAL.strs = []string{yyDollar[1].str} } - case 983: + case 985: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5240 +//line sql.y:5248 { yyVAL.strs = append(yyDollar[1].strs, yyDollar[2].str) } - case 984: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5246 - { - yyVAL.str = SQLNoCacheStr - } - case 985: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5250 - { - yyVAL.str = SQLCacheStr - } case 986: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:5254 { - yyVAL.str = DistinctStr + yyVAL.str = SQLNoCacheStr } case 987: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:5258 { - yyVAL.str = DistinctStr + yyVAL.str = SQLCacheStr } case 988: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:5262 { - yyVAL.str = HighPriorityStr + yyVAL.str = DistinctStr } case 989: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:5266 { - yyVAL.str = StraightJoinHint + yyVAL.str = DistinctStr } case 990: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:5270 { - yyVAL.str = SQLBufferResultStr + yyVAL.str = HighPriorityStr } case 991: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:5274 { - yyVAL.str = SQLSmallResultStr + yyVAL.str = StraightJoinHint } case 992: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:5278 { - yyVAL.str = SQLBigResultStr + yyVAL.str = SQLBufferResultStr } case 993: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:5282 { - yyVAL.str = SQLCalcFoundRowsStr + yyVAL.str = SQLSmallResultStr } case 994: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:5286 { - yyVAL.str = AllStr // These are not picked up by NewSelect, and so ALL will be dropped. But this is OK, since it's redundant anyway + yyVAL.str = SQLBigResultStr } case 995: yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:5290 + { + yyVAL.str = SQLCalcFoundRowsStr + } + case 996: + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:5294 + { + yyVAL.str = AllStr // These are not picked up by NewSelect, and so ALL will be dropped. But this is OK, since it's redundant anyway + } + case 997: + yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *SelectExprs -//line sql.y:5292 +//line sql.y:5300 + { + yyLOCAL = &SelectExprs{Exprs: []SelectExpr{&StarExpr{}}} + } + yyVAL.union = yyLOCAL + case 998: + yyDollar = yyS[yypt-1 : yypt+1] + var yyLOCAL *SelectExprs +//line sql.y:5304 { yyLOCAL = &SelectExprs{Exprs: []SelectExpr{yyDollar[1].selectExprUnion()}} } yyVAL.union = yyLOCAL - case 996: + case 999: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SelectExprs -//line sql.y:5296 +//line sql.y:5308 { - if starExpr, ok := yyDollar[3].selectExprUnion().(*StarExpr); ok && starExpr.TableName.IsEmpty() { - yylex.Error("syntax error: unexpected '*'") - return 1 - } res := yyDollar[1].selectExprsUnion() res.Exprs = append(res.Exprs, yyDollar[3].selectExprUnion()) yyLOCAL = res } yyVAL.union = yyLOCAL - case 997: - yyDollar = yyS[yypt-1 : yypt+1] - var yyLOCAL SelectExpr -//line sql.y:5308 - { - yyLOCAL = &StarExpr{} - } - yyVAL.union = yyLOCAL - case 998: + case 1000: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:5312 +//line sql.y:5316 { yyLOCAL = &AliasedExpr{Expr: yyDollar[1].exprUnion(), As: yyDollar[2].identifierCI} } yyVAL.union = yyLOCAL - case 999: + case 1001: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:5316 +//line sql.y:5320 { yyLOCAL = &StarExpr{TableName: TableName{Name: yyDollar[1].identifierCS}} } yyVAL.union = yyLOCAL - case 1000: + case 1002: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:5320 +//line sql.y:5324 { yyLOCAL = &StarExpr{TableName: TableName{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCS}} } yyVAL.union = yyLOCAL - case 1001: + case 1003: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5325 +//line sql.y:5329 { yyVAL.identifierCI = IdentifierCI{} } - case 1002: + case 1004: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5329 +//line sql.y:5333 { yyVAL.identifierCI = yyDollar[1].identifierCI } - case 1003: + case 1005: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5333 +//line sql.y:5337 { yyVAL.identifierCI = yyDollar[2].identifierCI } - case 1005: + case 1007: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5340 +//line sql.y:5344 { yyVAL.identifierCI = NewIdentifierCI(string(yyDollar[1].str)) } - case 1006: + case 1008: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL TableExprs -//line sql.y:5345 +//line sql.y:5349 { yyLOCAL = TableExprs{&AliasedTableExpr{Expr: TableName{Name: NewIdentifierCS("dual")}}} } yyVAL.union = yyLOCAL - case 1007: + case 1009: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExprs -//line sql.y:5349 +//line sql.y:5353 { yyLOCAL = yyDollar[1].tableExprsUnion() } yyVAL.union = yyLOCAL - case 1008: + case 1010: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL TableExprs -//line sql.y:5355 +//line sql.y:5359 { yyLOCAL = yyDollar[2].tableExprsUnion() } yyVAL.union = yyLOCAL - case 1009: + case 1011: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExprs -//line sql.y:5361 +//line sql.y:5365 { yyLOCAL = TableExprs{yyDollar[1].tableExprUnion()} } yyVAL.union = yyLOCAL - case 1010: + case 1012: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5365 +//line sql.y:5369 { yySLICE := (*TableExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableExprUnion()) } - case 1013: + case 1015: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5375 +//line sql.y:5379 { yyLOCAL = yyDollar[1].aliasedTableNameUnion() } yyVAL.union = yyLOCAL - case 1014: + case 1016: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5379 +//line sql.y:5383 { yyLOCAL = &AliasedTableExpr{Expr: yyDollar[1].derivedTableUnion(), As: yyDollar[3].identifierCS, Columns: yyDollar[4].columnsUnion()} } yyVAL.union = yyLOCAL - case 1015: + case 1017: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5383 +//line sql.y:5387 { yyLOCAL = &ParenTableExpr{Exprs: yyDollar[2].tableExprsUnion()} } yyVAL.union = yyLOCAL - case 1016: + case 1018: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5387 +//line sql.y:5391 { yyLOCAL = yyDollar[1].tableExprUnion() } yyVAL.union = yyLOCAL - case 1017: + case 1019: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *DerivedTable -//line sql.y:5393 +//line sql.y:5397 { yyLOCAL = &DerivedTable{Lateral: false, Select: yyDollar[1].tableStmtUnion()} } yyVAL.union = yyLOCAL - case 1018: + case 1020: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *DerivedTable -//line sql.y:5397 +//line sql.y:5401 { yyLOCAL = &DerivedTable{Lateral: true, Select: yyDollar[2].tableStmtUnion()} } yyVAL.union = yyLOCAL - case 1019: + case 1021: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *AliasedTableExpr -//line sql.y:5403 +//line sql.y:5407 { yyLOCAL = &AliasedTableExpr{Expr: yyDollar[1].tableName, As: yyDollar[2].identifierCS, Hints: yyDollar[3].indexHintsUnion()} } yyVAL.union = yyLOCAL - case 1020: + case 1022: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *AliasedTableExpr -//line sql.y:5407 +//line sql.y:5411 { yyLOCAL = &AliasedTableExpr{Expr: yyDollar[1].tableName, Partitions: yyDollar[4].partitionsUnion(), As: yyDollar[6].identifierCS, Hints: yyDollar[7].indexHintsUnion()} } yyVAL.union = yyLOCAL - case 1021: + case 1023: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Columns -//line sql.y:5412 +//line sql.y:5416 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1022: + case 1024: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Columns -//line sql.y:5416 +//line sql.y:5420 { yyLOCAL = yyDollar[2].columnsUnion() } yyVAL.union = yyLOCAL - case 1023: + case 1025: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Columns -//line sql.y:5421 +//line sql.y:5425 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1024: + case 1026: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:5425 +//line sql.y:5429 { yyLOCAL = yyDollar[1].columnsUnion() } yyVAL.union = yyLOCAL - case 1025: + case 1027: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:5431 +//line sql.y:5435 { yyLOCAL = Columns{yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL - case 1026: + case 1028: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5435 +//line sql.y:5439 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) } - case 1027: + case 1029: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*Variable -//line sql.y:5441 +//line sql.y:5445 { yyLOCAL = []*Variable{yyDollar[1].variableUnion()} } yyVAL.union = yyLOCAL - case 1028: + case 1030: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5445 +//line sql.y:5449 { yySLICE := (*[]*Variable)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].variableUnion()) } - case 1029: + case 1031: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:5451 +//line sql.y:5455 { yyLOCAL = Columns{yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL - case 1030: + case 1032: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:5455 +//line sql.y:5459 { yyLOCAL = Columns{NewIdentifierCI(string(yyDollar[1].str))} } yyVAL.union = yyLOCAL - case 1031: + case 1033: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5459 +//line sql.y:5463 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) } - case 1032: + case 1034: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5463 +//line sql.y:5467 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, NewIdentifierCI(string(yyDollar[3].str))) } - case 1033: + case 1035: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Partitions -//line sql.y:5469 +//line sql.y:5473 { yyLOCAL = Partitions{yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL - case 1034: + case 1036: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5473 +//line sql.y:5477 { yySLICE := (*Partitions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) } - case 1035: + case 1037: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5486 +//line sql.y:5490 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion(), Condition: yyDollar[4].joinCondition} } yyVAL.union = yyLOCAL - case 1036: + case 1038: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5490 +//line sql.y:5494 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion(), Condition: yyDollar[4].joinCondition} } yyVAL.union = yyLOCAL - case 1037: + case 1039: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5494 +//line sql.y:5498 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion(), Condition: yyDollar[4].joinCondition} } yyVAL.union = yyLOCAL - case 1038: + case 1040: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL TableExpr -//line sql.y:5498 +//line sql.y:5502 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion()} } yyVAL.union = yyLOCAL - case 1039: + case 1041: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5504 +//line sql.y:5508 { yyVAL.joinCondition = &JoinCondition{On: yyDollar[2].exprUnion()} } - case 1040: + case 1042: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:5506 +//line sql.y:5510 { yyVAL.joinCondition = &JoinCondition{Using: yyDollar[3].columnsUnion()} } - case 1041: + case 1043: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5510 +//line sql.y:5514 { yyVAL.joinCondition = &JoinCondition{} } - case 1042: + case 1044: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5512 +//line sql.y:5516 { yyVAL.joinCondition = yyDollar[1].joinCondition } - case 1043: + case 1045: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5516 +//line sql.y:5520 { yyVAL.joinCondition = &JoinCondition{} } - case 1044: + case 1046: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5518 +//line sql.y:5522 { yyVAL.joinCondition = &JoinCondition{On: yyDollar[2].exprUnion()} } - case 1045: + case 1047: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5521 +//line sql.y:5525 { yyVAL.empty = struct{}{} } - case 1046: + case 1048: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5523 +//line sql.y:5527 { yyVAL.empty = struct{}{} } - case 1047: + case 1049: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5526 +//line sql.y:5530 { yyVAL.identifierCS = NewIdentifierCS("") } - case 1048: + case 1050: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5530 +//line sql.y:5534 { yyVAL.identifierCS = yyDollar[1].identifierCS } - case 1049: + case 1051: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5534 +//line sql.y:5538 { yyVAL.identifierCS = yyDollar[2].identifierCS } - case 1051: + case 1053: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5541 +//line sql.y:5545 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 1052: + case 1054: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL JoinType -//line sql.y:5547 +//line sql.y:5551 { yyLOCAL = NormalJoinType } yyVAL.union = yyLOCAL - case 1053: + case 1055: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5551 +//line sql.y:5555 { yyLOCAL = NormalJoinType } yyVAL.union = yyLOCAL - case 1054: + case 1056: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5555 +//line sql.y:5559 { yyLOCAL = NormalJoinType } yyVAL.union = yyLOCAL - case 1055: + case 1057: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL JoinType -//line sql.y:5561 +//line sql.y:5565 { yyLOCAL = StraightJoinType } yyVAL.union = yyLOCAL - case 1056: + case 1058: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5567 +//line sql.y:5571 { yyLOCAL = LeftJoinType } yyVAL.union = yyLOCAL - case 1057: + case 1059: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL JoinType -//line sql.y:5571 +//line sql.y:5575 { yyLOCAL = LeftJoinType } yyVAL.union = yyLOCAL - case 1058: + case 1060: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5575 +//line sql.y:5579 { yyLOCAL = RightJoinType } yyVAL.union = yyLOCAL - case 1059: + case 1061: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL JoinType -//line sql.y:5579 +//line sql.y:5583 { yyLOCAL = RightJoinType } yyVAL.union = yyLOCAL - case 1060: + case 1062: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5585 +//line sql.y:5589 { yyLOCAL = NaturalJoinType } yyVAL.union = yyLOCAL - case 1061: + case 1063: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:5589 +//line sql.y:5593 { if yyDollar[2].joinTypeUnion() == LeftJoinType { yyLOCAL = NaturalLeftJoinType @@ -18939,667 +19083,667 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1062: + case 1064: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5599 +//line sql.y:5603 { yyVAL.tableName = yyDollar[2].tableName } - case 1063: + case 1065: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5603 +//line sql.y:5607 { yyVAL.tableName = yyDollar[1].tableName } - case 1064: + case 1066: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5609 +//line sql.y:5613 { yyVAL.tableName = TableName{Name: yyDollar[1].identifierCS} } - case 1065: + case 1067: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5613 +//line sql.y:5617 { yyVAL.tableName = TableName{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCS} } - case 1066: + case 1068: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:5619 +//line sql.y:5623 { yyVAL.tableName = TableName{Name: yyDollar[1].identifierCS} } - case 1067: + case 1069: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL IndexHints -//line sql.y:5624 +//line sql.y:5628 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1068: + case 1070: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IndexHints -//line sql.y:5628 +//line sql.y:5632 { yyLOCAL = yyDollar[1].indexHintsUnion() } yyVAL.union = yyLOCAL - case 1069: + case 1071: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IndexHints -//line sql.y:5634 +//line sql.y:5638 { yyLOCAL = IndexHints{yyDollar[1].indexHintUnion()} } yyVAL.union = yyLOCAL - case 1070: + case 1072: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:5638 +//line sql.y:5642 { yySLICE := (*IndexHints)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].indexHintUnion()) } - case 1071: + case 1073: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5644 +//line sql.y:5648 { yyLOCAL = &IndexHint{Type: UseOp, ForType: yyDollar[3].indexHintForTypeUnion(), Indexes: yyDollar[5].columnsUnion()} } yyVAL.union = yyLOCAL - case 1072: + case 1074: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5648 +//line sql.y:5652 { yyLOCAL = &IndexHint{Type: UseOp, ForType: yyDollar[3].indexHintForTypeUnion()} } yyVAL.union = yyLOCAL - case 1073: + case 1075: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5652 +//line sql.y:5656 { yyLOCAL = &IndexHint{Type: IgnoreOp, ForType: yyDollar[3].indexHintForTypeUnion(), Indexes: yyDollar[5].columnsUnion()} } yyVAL.union = yyLOCAL - case 1074: + case 1076: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5656 +//line sql.y:5660 { yyLOCAL = &IndexHint{Type: ForceOp, ForType: yyDollar[3].indexHintForTypeUnion(), Indexes: yyDollar[5].columnsUnion()} } yyVAL.union = yyLOCAL - case 1075: + case 1077: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5660 +//line sql.y:5664 { yyLOCAL = &IndexHint{Type: UseVindexOp, Indexes: yyDollar[4].columnsUnion()} } yyVAL.union = yyLOCAL - case 1076: + case 1078: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *IndexHint -//line sql.y:5664 +//line sql.y:5668 { yyLOCAL = &IndexHint{Type: IgnoreVindexOp, Indexes: yyDollar[4].columnsUnion()} } yyVAL.union = yyLOCAL - case 1077: + case 1079: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL IndexHintForType -//line sql.y:5669 +//line sql.y:5673 { yyLOCAL = NoForType } yyVAL.union = yyLOCAL - case 1078: + case 1080: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL IndexHintForType -//line sql.y:5673 +//line sql.y:5677 { yyLOCAL = JoinForType } yyVAL.union = yyLOCAL - case 1079: + case 1081: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL IndexHintForType -//line sql.y:5677 +//line sql.y:5681 { yyLOCAL = OrderByForType } yyVAL.union = yyLOCAL - case 1080: + case 1082: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL IndexHintForType -//line sql.y:5681 +//line sql.y:5685 { yyLOCAL = GroupByForType } yyVAL.union = yyLOCAL - case 1081: + case 1083: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:5687 +//line sql.y:5691 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1082: + case 1084: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5691 +//line sql.y:5695 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 1083: + case 1085: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5698 +//line sql.y:5702 { yyLOCAL = &OrExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1084: + case 1086: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5702 +//line sql.y:5706 { yyLOCAL = &XorExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1085: + case 1087: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5706 +//line sql.y:5710 { yyLOCAL = &AndExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1086: + case 1088: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5710 +//line sql.y:5714 { yyLOCAL = &NotExpr{Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1087: + case 1089: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5714 +//line sql.y:5718 { yyLOCAL = &IsExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].isExprOperatorUnion()} } yyVAL.union = yyLOCAL - case 1088: + case 1090: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5718 +//line sql.y:5722 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1089: + case 1091: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5722 +//line sql.y:5726 { yyLOCAL = &AssignmentExpr{Left: yyDollar[1].variableUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1090: + case 1092: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5726 +//line sql.y:5730 { yyLOCAL = &MemberOfExpr{Value: yyDollar[1].exprUnion(), JSONArr: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1091: + case 1093: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5732 +//line sql.y:5736 { } - case 1092: + case 1094: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5735 +//line sql.y:5739 { } - case 1093: + case 1095: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5740 +//line sql.y:5744 { yyLOCAL = &IsExpr{Left: yyDollar[1].exprUnion(), Right: IsNullOp} } yyVAL.union = yyLOCAL - case 1094: + case 1096: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5744 +//line sql.y:5748 { yyLOCAL = &IsExpr{Left: yyDollar[1].exprUnion(), Right: IsNotNullOp} } yyVAL.union = yyLOCAL - case 1095: + case 1097: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5748 +//line sql.y:5752 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: yyDollar[2].comparisonExprOperatorUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1096: + case 1098: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5752 +//line sql.y:5756 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: yyDollar[2].comparisonExprOperatorUnion(), Modifier: Any, Right: yyDollar[4].subqueryUnion()} } yyVAL.union = yyLOCAL - case 1097: + case 1099: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5756 +//line sql.y:5760 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: yyDollar[2].comparisonExprOperatorUnion(), Modifier: Any, Right: yyDollar[4].subqueryUnion()} } yyVAL.union = yyLOCAL - case 1098: + case 1100: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5760 +//line sql.y:5764 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: yyDollar[2].comparisonExprOperatorUnion(), Modifier: All, Right: yyDollar[4].subqueryUnion()} } yyVAL.union = yyLOCAL - case 1099: + case 1101: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5764 +//line sql.y:5768 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1100: + case 1102: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5770 +//line sql.y:5774 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: InOp, Right: yyDollar[3].colTupleUnion()} } yyVAL.union = yyLOCAL - case 1101: + case 1103: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5774 +//line sql.y:5778 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotInOp, Right: yyDollar[4].colTupleUnion()} } yyVAL.union = yyLOCAL - case 1102: + case 1104: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5778 +//line sql.y:5782 { yyLOCAL = &BetweenExpr{Left: yyDollar[1].exprUnion(), IsBetween: true, From: yyDollar[3].exprUnion(), To: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1103: + case 1105: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5782 +//line sql.y:5786 { yyLOCAL = &BetweenExpr{Left: yyDollar[1].exprUnion(), IsBetween: false, From: yyDollar[4].exprUnion(), To: yyDollar[6].exprUnion()} } yyVAL.union = yyLOCAL - case 1104: + case 1106: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5786 +//line sql.y:5790 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: LikeOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1105: + case 1107: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5790 +//line sql.y:5794 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotLikeOp, Right: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1106: + case 1108: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5794 +//line sql.y:5798 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: LikeOp, Right: yyDollar[3].exprUnion(), Escape: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1107: + case 1109: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5798 +//line sql.y:5802 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotLikeOp, Right: yyDollar[4].exprUnion(), Escape: yyDollar[6].exprUnion()} } yyVAL.union = yyLOCAL - case 1108: + case 1110: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5802 +//line sql.y:5806 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: RegexpOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1109: + case 1111: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:5806 +//line sql.y:5810 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotRegexpOp, Right: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1110: + case 1112: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5810 +//line sql.y:5814 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1111: + case 1113: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5816 +//line sql.y:5820 { } - case 1112: + case 1114: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5819 +//line sql.y:5823 { } - case 1113: + case 1115: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5825 +//line sql.y:5829 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitOrOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1114: + case 1116: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5829 +//line sql.y:5833 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitAndOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1115: + case 1117: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5833 +//line sql.y:5837 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ShiftLeftOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1116: + case 1118: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5837 +//line sql.y:5841 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ShiftRightOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1117: + case 1119: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5841 +//line sql.y:5845 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: PlusOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1118: + case 1120: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5845 +//line sql.y:5849 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: MinusOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1119: + case 1121: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5849 +//line sql.y:5853 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprBinaryAdd, Date: yyDollar[1].exprUnion(), Unit: yyDollar[5].intervalTypeUnion(), Interval: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1120: + case 1122: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5853 +//line sql.y:5857 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprBinarySub, Date: yyDollar[1].exprUnion(), Unit: yyDollar[5].intervalTypeUnion(), Interval: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1121: + case 1123: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5857 +//line sql.y:5861 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: MultOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1122: + case 1124: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5861 +//line sql.y:5865 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: DivOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1123: + case 1125: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5865 +//line sql.y:5869 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ModOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1124: + case 1126: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5869 +//line sql.y:5873 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: IntDivOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1125: + case 1127: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5873 +//line sql.y:5877 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ModOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1126: + case 1128: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5877 +//line sql.y:5881 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitXorOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1127: + case 1129: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5881 +//line sql.y:5885 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1128: + case 1130: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5887 +//line sql.y:5891 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1129: + case 1131: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5891 +//line sql.y:5895 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1130: + case 1132: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5895 +//line sql.y:5899 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1131: + case 1133: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5899 +//line sql.y:5903 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1132: + case 1134: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5903 +//line sql.y:5907 { yyLOCAL = &CollateExpr{Expr: yyDollar[1].exprUnion(), Collation: yyDollar[3].str} } yyVAL.union = yyLOCAL - case 1133: + case 1135: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5907 +//line sql.y:5911 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1134: + case 1136: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5911 +//line sql.y:5915 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1135: + case 1137: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5915 +//line sql.y:5919 { yyLOCAL = yyDollar[1].variableUnion() } yyVAL.union = yyLOCAL - case 1136: + case 1138: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5919 +//line sql.y:5923 { yyLOCAL = yyDollar[2].exprUnion() // TODO: do we really want to ignore unary '+' before any kind of literals? } yyVAL.union = yyLOCAL - case 1137: + case 1139: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5923 +//line sql.y:5927 { yyLOCAL = &UnaryExpr{Operator: UMinusOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1138: + case 1140: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5927 +//line sql.y:5931 { yyLOCAL = &UnaryExpr{Operator: TildaOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1139: + case 1141: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5931 +//line sql.y:5935 { yyLOCAL = &UnaryExpr{Operator: BangOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1140: + case 1142: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5935 +//line sql.y:5939 { yyLOCAL = yyDollar[1].subqueryUnion() } yyVAL.union = yyLOCAL - case 1141: + case 1143: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:5939 +//line sql.y:5943 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1142: + case 1144: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5943 +//line sql.y:5947 { yyLOCAL = &ExistsExpr{Subquery: yyDollar[2].subqueryUnion()} } yyVAL.union = yyLOCAL - case 1143: + case 1145: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr -//line sql.y:5947 +//line sql.y:5951 { yyLOCAL = &MatchExpr{Columns: yyDollar[2].colNamesUnion(), Expr: yyDollar[5].exprUnion(), Option: yyDollar[6].matchExprOptionUnion()} } yyVAL.union = yyLOCAL - case 1144: + case 1146: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr -//line sql.y:5951 +//line sql.y:5955 { yyLOCAL = &CastExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].convertTypeUnion(), Array: yyDollar[6].booleanUnion()} } yyVAL.union = yyLOCAL - case 1145: + case 1147: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5955 +//line sql.y:5959 { yyLOCAL = &ConvertExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].convertTypeUnion()} } yyVAL.union = yyLOCAL - case 1146: + case 1148: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5959 +//line sql.y:5963 { yyLOCAL = &ConvertUsingExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].str} } yyVAL.union = yyLOCAL - case 1147: + case 1149: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5963 +//line sql.y:5967 { // From: https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#operator_binary // To convert a string expression to a binary string, these constructs are equivalent: @@ -19608,3218 +19752,3218 @@ yydefault: yyLOCAL = &ConvertExpr{Expr: yyDollar[2].exprUnion(), Type: &ConvertType{Type: yyDollar[1].str}} } yyVAL.union = yyLOCAL - case 1148: + case 1150: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:5971 +//line sql.y:5975 { yyLOCAL = &Default{ColName: yyDollar[2].str} } yyVAL.union = yyLOCAL - case 1149: + case 1151: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:5975 +//line sql.y:5979 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprBinaryAddLeft, Date: yyDollar[5].exprUnion(), Unit: yyDollar[3].intervalTypeUnion(), Interval: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1150: + case 1152: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:5979 +//line sql.y:5983 { yyLOCAL = &IntervalFuncExpr{Expr: yyDollar[3].exprUnion(), Exprs: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1151: + case 1153: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5983 +//line sql.y:5987 { yyLOCAL = &JSONExtractExpr{JSONDoc: yyDollar[1].exprUnion(), PathList: []Expr{yyDollar[3].exprUnion()}} } yyVAL.union = yyLOCAL - case 1152: + case 1154: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:5987 +//line sql.y:5991 { yyLOCAL = &JSONUnquoteExpr{JSONValue: &JSONExtractExpr{JSONDoc: yyDollar[1].exprUnion(), PathList: []Expr{yyDollar[3].exprUnion()}}} } yyVAL.union = yyLOCAL - case 1153: + case 1155: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*ColName -//line sql.y:5993 +//line sql.y:5997 { yyLOCAL = yyDollar[1].colNamesUnion() } yyVAL.union = yyLOCAL - case 1154: + case 1156: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*ColName -//line sql.y:5997 +//line sql.y:6001 { yyLOCAL = yyDollar[2].colNamesUnion() } yyVAL.union = yyLOCAL - case 1155: + case 1157: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*ColName -//line sql.y:6003 +//line sql.y:6007 { yyLOCAL = []*ColName{yyDollar[1].colNameUnion()} } yyVAL.union = yyLOCAL - case 1156: + case 1158: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:6007 +//line sql.y:6011 { yySLICE := (*[]*ColName)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].colNameUnion()) } - case 1157: + case 1159: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TrimType -//line sql.y:6013 +//line sql.y:6017 { yyLOCAL = BothTrimType } yyVAL.union = yyLOCAL - case 1158: + case 1160: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TrimType -//line sql.y:6017 +//line sql.y:6021 { yyLOCAL = LeadingTrimType } yyVAL.union = yyLOCAL - case 1159: + case 1161: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TrimType -//line sql.y:6021 +//line sql.y:6025 { yyLOCAL = TrailingTrimType } yyVAL.union = yyLOCAL - case 1160: + case 1162: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL FrameUnitType -//line sql.y:6027 +//line sql.y:6031 { yyLOCAL = FrameRowsType } yyVAL.union = yyLOCAL - case 1161: + case 1163: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL FrameUnitType -//line sql.y:6031 +//line sql.y:6035 { yyLOCAL = FrameRangeType } yyVAL.union = yyLOCAL - case 1162: + case 1164: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:6038 +//line sql.y:6042 { yyLOCAL = CumeDistExprType } yyVAL.union = yyLOCAL - case 1163: + case 1165: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:6042 +//line sql.y:6046 { yyLOCAL = DenseRankExprType } yyVAL.union = yyLOCAL - case 1164: + case 1166: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:6046 +//line sql.y:6050 { yyLOCAL = PercentRankExprType } yyVAL.union = yyLOCAL - case 1165: + case 1167: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:6050 +//line sql.y:6054 { yyLOCAL = RankExprType } yyVAL.union = yyLOCAL - case 1166: + case 1168: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ArgumentLessWindowExprType -//line sql.y:6054 +//line sql.y:6058 { yyLOCAL = RowNumberExprType } yyVAL.union = yyLOCAL - case 1167: + case 1169: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:6060 +//line sql.y:6064 { yyLOCAL = &FramePoint{Type: CurrentRowType} } yyVAL.union = yyLOCAL - case 1168: + case 1170: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:6064 +//line sql.y:6068 { yyLOCAL = &FramePoint{Type: UnboundedPrecedingType} } yyVAL.union = yyLOCAL - case 1169: + case 1171: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:6068 +//line sql.y:6072 { yyLOCAL = &FramePoint{Type: UnboundedFollowingType} } yyVAL.union = yyLOCAL - case 1170: + case 1172: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:6072 +//line sql.y:6076 { yyLOCAL = &FramePoint{Type: ExprPrecedingType, Expr: yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL - case 1171: + case 1173: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:6076 +//line sql.y:6080 { yyLOCAL = &FramePoint{Type: ExprPrecedingType, Expr: yyDollar[2].exprUnion(), Unit: yyDollar[3].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1172: + case 1174: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:6080 +//line sql.y:6084 { yyLOCAL = &FramePoint{Type: ExprFollowingType, Expr: yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL - case 1173: + case 1175: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *FramePoint -//line sql.y:6084 +//line sql.y:6088 { yyLOCAL = &FramePoint{Type: ExprFollowingType, Expr: yyDollar[2].exprUnion(), Unit: yyDollar[3].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1174: + case 1176: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *FrameClause -//line sql.y:6089 +//line sql.y:6093 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1175: + case 1177: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *FrameClause -//line sql.y:6093 +//line sql.y:6097 { yyLOCAL = yyDollar[1].frameClauseUnion() } yyVAL.union = yyLOCAL - case 1176: + case 1178: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *FrameClause -//line sql.y:6099 +//line sql.y:6103 { yyLOCAL = &FrameClause{Unit: yyDollar[1].frameUnitTypeUnion(), Start: yyDollar[2].framePointUnion()} } yyVAL.union = yyLOCAL - case 1177: + case 1179: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *FrameClause -//line sql.y:6103 +//line sql.y:6107 { yyLOCAL = &FrameClause{Unit: yyDollar[1].frameUnitTypeUnion(), Start: yyDollar[3].framePointUnion(), End: yyDollar[5].framePointUnion()} } yyVAL.union = yyLOCAL - case 1178: + case 1180: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []Expr -//line sql.y:6108 +//line sql.y:6112 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1179: + case 1181: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []Expr -//line sql.y:6112 +//line sql.y:6116 { yyLOCAL = yyDollar[3].exprsUnion() } yyVAL.union = yyLOCAL - case 1180: + case 1182: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:6117 +//line sql.y:6121 { yyVAL.identifierCI = IdentifierCI{} } - case 1181: + case 1183: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:6121 +//line sql.y:6125 { yyVAL.identifierCI = yyDollar[1].identifierCI } - case 1182: + case 1184: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *WindowSpecification -//line sql.y:6127 +//line sql.y:6131 { yyLOCAL = &WindowSpecification{Name: yyDollar[1].identifierCI, PartitionClause: yyDollar[2].exprsUnion(), OrderClause: yyDollar[3].orderByUnion(), FrameClause: yyDollar[4].frameClauseUnion()} } yyVAL.union = yyLOCAL - case 1183: + case 1185: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *OverClause -//line sql.y:6133 +//line sql.y:6137 { yyLOCAL = &OverClause{WindowSpec: yyDollar[3].windowSpecificationUnion()} } yyVAL.union = yyLOCAL - case 1184: + case 1186: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *OverClause -//line sql.y:6137 +//line sql.y:6141 { yyLOCAL = &OverClause{WindowName: yyDollar[2].identifierCI} } yyVAL.union = yyLOCAL - case 1185: + case 1187: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *OverClause -//line sql.y:6143 +//line sql.y:6147 { yyLOCAL = yyDollar[1].overClauseUnion() } yyVAL.union = yyLOCAL - case 1186: + case 1188: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *OverClause -//line sql.y:6147 +//line sql.y:6151 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1187: + case 1189: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *NullTreatmentClause -//line sql.y:6152 +//line sql.y:6156 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1189: + case 1191: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *NullTreatmentClause -//line sql.y:6159 +//line sql.y:6163 { yyLOCAL = &NullTreatmentClause{yyDollar[1].nullTreatmentTypeUnion()} } yyVAL.union = yyLOCAL - case 1190: + case 1192: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL NullTreatmentType -//line sql.y:6165 +//line sql.y:6169 { yyLOCAL = RespectNullsType } yyVAL.union = yyLOCAL - case 1191: + case 1193: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL NullTreatmentType -//line sql.y:6169 +//line sql.y:6173 { yyLOCAL = IgnoreNullsType } yyVAL.union = yyLOCAL - case 1192: + case 1194: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL FirstOrLastValueExprType -//line sql.y:6175 +//line sql.y:6179 { yyLOCAL = FirstValueExprType } yyVAL.union = yyLOCAL - case 1193: + case 1195: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL FirstOrLastValueExprType -//line sql.y:6179 +//line sql.y:6183 { yyLOCAL = LastValueExprType } yyVAL.union = yyLOCAL - case 1194: + case 1196: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL FromFirstLastType -//line sql.y:6185 +//line sql.y:6189 { yyLOCAL = FromFirstType } yyVAL.union = yyLOCAL - case 1195: + case 1197: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL FromFirstLastType -//line sql.y:6189 +//line sql.y:6193 { yyLOCAL = FromLastType } yyVAL.union = yyLOCAL - case 1196: + case 1198: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *FromFirstLastClause -//line sql.y:6194 +//line sql.y:6198 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1198: + case 1200: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *FromFirstLastClause -//line sql.y:6201 +//line sql.y:6205 { yyLOCAL = &FromFirstLastClause{yyDollar[1].fromFirstLastTypeUnion()} } yyVAL.union = yyLOCAL - case 1199: + case 1201: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL LagLeadExprType -//line sql.y:6207 +//line sql.y:6211 { yyLOCAL = LagExprType } yyVAL.union = yyLOCAL - case 1200: + case 1202: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL LagLeadExprType -//line sql.y:6211 +//line sql.y:6215 { yyLOCAL = LeadExprType } yyVAL.union = yyLOCAL - case 1201: + case 1203: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *WindowDefinition -//line sql.y:6217 +//line sql.y:6221 { yyLOCAL = &WindowDefinition{Name: yyDollar[1].identifierCI, WindowSpec: yyDollar[4].windowSpecificationUnion()} } yyVAL.union = yyLOCAL - case 1202: + case 1204: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL WindowDefinitions -//line sql.y:6223 +//line sql.y:6227 { yyLOCAL = WindowDefinitions{yyDollar[1].windowDefinitionUnion()} } yyVAL.union = yyLOCAL - case 1203: + case 1205: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:6227 +//line sql.y:6231 { yySLICE := (*WindowDefinitions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].windowDefinitionUnion()) } - case 1204: + case 1206: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:6233 +//line sql.y:6237 { yyVAL.str = "" } - case 1205: + case 1207: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:6237 +//line sql.y:6241 { yyVAL.str = string(yyDollar[2].identifierCI.String()) } - case 1206: + case 1208: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL BoolVal -//line sql.y:6243 +//line sql.y:6247 { yyLOCAL = BoolVal(true) } yyVAL.union = yyLOCAL - case 1207: + case 1209: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL BoolVal -//line sql.y:6247 +//line sql.y:6251 { yyLOCAL = BoolVal(false) } yyVAL.union = yyLOCAL - case 1208: + case 1210: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:6254 +//line sql.y:6258 { yyLOCAL = IsTrueOp } yyVAL.union = yyLOCAL - case 1209: + case 1211: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:6258 +//line sql.y:6262 { yyLOCAL = IsNotTrueOp } yyVAL.union = yyLOCAL - case 1210: + case 1212: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:6262 +//line sql.y:6266 { yyLOCAL = IsFalseOp } yyVAL.union = yyLOCAL - case 1211: + case 1213: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:6266 +//line sql.y:6270 { yyLOCAL = IsNotFalseOp } yyVAL.union = yyLOCAL - case 1212: + case 1214: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:6272 +//line sql.y:6276 { yyLOCAL = yyDollar[1].comparisonExprOperatorUnion() } yyVAL.union = yyLOCAL - case 1213: + case 1215: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:6276 +//line sql.y:6280 { yyLOCAL = NullSafeEqualOp } yyVAL.union = yyLOCAL - case 1214: + case 1216: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:6282 +//line sql.y:6286 { yyLOCAL = EqualOp } yyVAL.union = yyLOCAL - case 1215: + case 1217: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:6286 +//line sql.y:6290 { yyLOCAL = LessThanOp } yyVAL.union = yyLOCAL - case 1216: + case 1218: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:6290 +//line sql.y:6294 { yyLOCAL = GreaterThanOp } yyVAL.union = yyLOCAL - case 1217: + case 1219: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:6294 +//line sql.y:6298 { yyLOCAL = LessEqualOp } yyVAL.union = yyLOCAL - case 1218: + case 1220: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:6298 +//line sql.y:6302 { yyLOCAL = GreaterEqualOp } yyVAL.union = yyLOCAL - case 1219: + case 1221: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:6302 +//line sql.y:6306 { yyLOCAL = NotEqualOp } yyVAL.union = yyLOCAL - case 1220: + case 1222: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColTuple -//line sql.y:6308 +//line sql.y:6312 { yyLOCAL = yyDollar[1].valTupleUnion() } yyVAL.union = yyLOCAL - case 1221: + case 1223: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColTuple -//line sql.y:6312 +//line sql.y:6316 { yyLOCAL = yyDollar[1].subqueryUnion() } yyVAL.union = yyLOCAL - case 1222: + case 1224: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColTuple -//line sql.y:6316 +//line sql.y:6320 { yyLOCAL = ListArg(yyDollar[1].str[2:]) markBindVariable(yylex, yyDollar[1].str[2:]) } yyVAL.union = yyLOCAL - case 1223: + case 1225: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Subquery -//line sql.y:6323 +//line sql.y:6327 { yyLOCAL = &Subquery{yyDollar[1].tableStmtUnion()} } yyVAL.union = yyLOCAL - case 1224: + case 1226: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []Expr -//line sql.y:6329 +//line sql.y:6333 { yyLOCAL = []Expr{yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL - case 1225: + case 1227: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:6333 +//line sql.y:6337 { yySLICE := (*[]Expr)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].exprUnion()) } - case 1226: + case 1228: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6343 +//line sql.y:6347 { yyLOCAL = &FuncExpr{Name: yyDollar[1].identifierCI, Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1227: + case 1229: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6347 +//line sql.y:6351 { yyLOCAL = &FuncExpr{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCI, Exprs: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1228: + case 1230: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6357 +//line sql.y:6361 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("left"), Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1229: + case 1231: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6361 +//line sql.y:6365 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("right"), Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1230: + case 1232: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6365 +//line sql.y:6369 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1231: + case 1233: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6369 +//line sql.y:6373 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1232: + case 1234: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6373 +//line sql.y:6377 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1233: + case 1235: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6377 +//line sql.y:6381 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1234: + case 1236: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6381 +//line sql.y:6385 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].exprUnion(), From: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1235: + case 1237: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6385 +//line sql.y:6389 { yyLOCAL = &CaseExpr{Expr: yyDollar[2].exprUnion(), Whens: yyDollar[3].whensUnion(), Else: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1236: + case 1238: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6389 +//line sql.y:6393 { yyLOCAL = &ValuesFuncExpr{Name: yyDollar[3].colNameUnion()} } yyVAL.union = yyLOCAL - case 1237: + case 1239: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:6393 +//line sql.y:6397 { yyLOCAL = &InsertExpr{Str: yyDollar[3].exprUnion(), Pos: yyDollar[5].exprUnion(), Len: yyDollar[7].exprUnion(), NewStr: yyDollar[9].exprUnion()} } yyVAL.union = yyLOCAL - case 1238: + case 1240: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6397 +//line sql.y:6401 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1239: + case 1241: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6408 +//line sql.y:6412 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("utc_date")} } yyVAL.union = yyLOCAL - case 1240: + case 1242: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:6412 +//line sql.y:6416 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1241: + case 1243: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6418 +//line sql.y:6422 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("current_date")} } yyVAL.union = yyLOCAL - case 1242: + case 1244: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6422 +//line sql.y:6426 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("curdate")} } yyVAL.union = yyLOCAL - case 1243: + case 1245: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6426 +//line sql.y:6430 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("utc_time"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL - case 1244: + case 1246: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6431 +//line sql.y:6435 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("curtime"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL - case 1245: + case 1247: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:6436 +//line sql.y:6440 { yyLOCAL = &CurTimeFuncExpr{Name: NewIdentifierCI("current_time"), Fsp: yyDollar[2].integerUnion()} } yyVAL.union = yyLOCAL - case 1246: + case 1248: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6440 +//line sql.y:6444 { yyLOCAL = &CountStar{OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1247: + case 1249: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6444 +//line sql.y:6448 { yyLOCAL = &Count{Distinct: yyDollar[3].booleanUnion(), Args: yyDollar[4].exprsUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1248: + case 1250: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6448 +//line sql.y:6452 { yyLOCAL = &Max{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1249: + case 1251: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6452 +//line sql.y:6456 { yyLOCAL = &Min{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1250: + case 1252: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6456 +//line sql.y:6460 { yyLOCAL = &Sum{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1251: + case 1253: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6460 +//line sql.y:6464 { yyLOCAL = &Avg{Distinct: yyDollar[3].booleanUnion(), Arg: yyDollar[4].exprUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1252: + case 1254: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6464 +//line sql.y:6468 { yyLOCAL = &BitAnd{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1253: + case 1255: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6468 +//line sql.y:6472 { yyLOCAL = &BitOr{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1254: + case 1256: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6472 +//line sql.y:6476 { yyLOCAL = &BitXor{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1255: + case 1257: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6476 +//line sql.y:6480 { yyLOCAL = &Std{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1256: + case 1258: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6480 +//line sql.y:6484 { yyLOCAL = &StdDev{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1257: + case 1259: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6484 +//line sql.y:6488 { yyLOCAL = &StdPop{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1258: + case 1260: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6488 +//line sql.y:6492 { yyLOCAL = &StdSamp{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1259: + case 1261: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6492 +//line sql.y:6496 { yyLOCAL = &VarPop{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1260: + case 1262: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6496 +//line sql.y:6500 { yyLOCAL = &VarSamp{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1261: + case 1263: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6500 +//line sql.y:6504 { yyLOCAL = &Variance{Arg: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1262: + case 1264: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6504 +//line sql.y:6508 { yyLOCAL = &GroupConcatExpr{Distinct: yyDollar[3].booleanUnion(), Exprs: yyDollar[4].exprsUnion(), OrderBy: yyDollar[5].orderByUnion(), Separator: yyDollar[6].str, Limit: yyDollar[7].limitUnion()} } yyVAL.union = yyLOCAL - case 1263: + case 1265: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6508 +//line sql.y:6512 { yyLOCAL = &AnyValue{Arg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1264: + case 1266: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6512 +//line sql.y:6516 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprTimestampadd, Date: yyDollar[7].exprUnion(), Interval: yyDollar[5].exprUnion(), Unit: yyDollar[3].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1265: + case 1267: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6516 +//line sql.y:6520 { yyLOCAL = &TimestampDiffExpr{Unit: yyDollar[3].intervalTypeUnion(), Expr1: yyDollar[5].exprUnion(), Expr2: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1266: + case 1268: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6520 +//line sql.y:6524 { yyLOCAL = &ExtractFuncExpr{IntervalType: yyDollar[3].intervalTypeUnion(), Expr: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1267: + case 1269: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6524 +//line sql.y:6528 { yyLOCAL = &WeightStringFuncExpr{Expr: yyDollar[3].exprUnion(), As: yyDollar[4].convertTypeUnion()} } yyVAL.union = yyLOCAL - case 1268: + case 1270: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6528 +//line sql.y:6532 { yyLOCAL = &JSONPrettyExpr{JSONVal: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1269: + case 1271: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6532 +//line sql.y:6536 { yyLOCAL = &JSONStorageFreeExpr{JSONVal: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1270: + case 1272: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6536 +//line sql.y:6540 { yyLOCAL = &JSONStorageSizeExpr{JSONVal: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1271: + case 1273: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:6540 +//line sql.y:6544 { yyLOCAL = &JSONArrayAgg{Expr: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1272: + case 1274: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr -//line sql.y:6544 +//line sql.y:6548 { yyLOCAL = &JSONObjectAgg{Key: yyDollar[3].exprUnion(), Value: yyDollar[5].exprUnion(), OverClause: yyDollar[7].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1273: + case 1275: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6548 +//line sql.y:6552 { yyLOCAL = &TrimFuncExpr{TrimFuncType: LTrimType, Type: LeadingTrimType, StringArg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1274: + case 1276: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6552 +//line sql.y:6556 { yyLOCAL = &TrimFuncExpr{TrimFuncType: RTrimType, Type: TrailingTrimType, StringArg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1275: + case 1277: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr -//line sql.y:6556 +//line sql.y:6560 { yyLOCAL = &TrimFuncExpr{Type: yyDollar[3].trimTypeUnion(), TrimArg: yyDollar[4].exprUnion(), StringArg: yyDollar[6].exprUnion()} } yyVAL.union = yyLOCAL - case 1276: + case 1278: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6560 +//line sql.y:6564 { yyLOCAL = &TrimFuncExpr{StringArg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1277: + case 1279: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6564 +//line sql.y:6568 { yyLOCAL = &CharExpr{Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1278: + case 1280: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6568 +//line sql.y:6572 { yyLOCAL = &CharExpr{Exprs: yyDollar[3].exprsUnion(), Charset: yyDollar[5].str} } yyVAL.union = yyLOCAL - case 1279: + case 1281: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6572 +//line sql.y:6576 { yyLOCAL = &TrimFuncExpr{TrimArg: yyDollar[3].exprUnion(), StringArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1280: + case 1282: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6576 +//line sql.y:6580 { yyLOCAL = &LocateExpr{SubStr: yyDollar[3].exprUnion(), Str: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1281: + case 1283: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6580 +//line sql.y:6584 { yyLOCAL = &LocateExpr{SubStr: yyDollar[3].exprUnion(), Str: yyDollar[5].exprUnion(), Pos: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1282: + case 1284: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6584 +//line sql.y:6588 { yyLOCAL = &LocateExpr{SubStr: yyDollar[3].exprUnion(), Str: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1283: + case 1285: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6588 +//line sql.y:6592 { yyLOCAL = &LockingFunc{Type: GetLock, Name: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1284: + case 1286: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6592 +//line sql.y:6596 { yyLOCAL = &LockingFunc{Type: IsFreeLock, Name: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1285: + case 1287: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6596 +//line sql.y:6600 { yyLOCAL = &LockingFunc{Type: IsUsedLock, Name: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1286: + case 1288: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:6600 +//line sql.y:6604 { yyLOCAL = &LockingFunc{Type: ReleaseAllLocks} } yyVAL.union = yyLOCAL - case 1287: + case 1289: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6604 +//line sql.y:6608 { yyLOCAL = &LockingFunc{Type: ReleaseLock, Name: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1288: + case 1290: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6608 +//line sql.y:6612 { yyLOCAL = &JSONSchemaValidFuncExpr{Schema: yyDollar[3].exprUnion(), Document: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1289: + case 1291: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6612 +//line sql.y:6616 { yyLOCAL = &JSONSchemaValidationReportFuncExpr{Schema: yyDollar[3].exprUnion(), Document: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1290: + case 1292: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6616 +//line sql.y:6620 { yyLOCAL = &JSONArrayExpr{Params: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1291: + case 1293: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6620 +//line sql.y:6624 { yyLOCAL = &GeomFormatExpr{FormatType: BinaryFormat, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1292: + case 1294: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6624 +//line sql.y:6628 { yyLOCAL = &GeomFormatExpr{FormatType: BinaryFormat, Geom: yyDollar[3].exprUnion(), AxisOrderOpt: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1293: + case 1295: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6628 +//line sql.y:6632 { yyLOCAL = &GeomFormatExpr{FormatType: TextFormat, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1294: + case 1296: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6632 +//line sql.y:6636 { yyLOCAL = &GeomFormatExpr{FormatType: TextFormat, Geom: yyDollar[3].exprUnion(), AxisOrderOpt: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1295: + case 1297: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6636 +//line sql.y:6640 { yyLOCAL = &GeomPropertyFuncExpr{Property: IsEmpty, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1296: + case 1298: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6640 +//line sql.y:6644 { yyLOCAL = &GeomPropertyFuncExpr{Property: IsSimple, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1297: + case 1299: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6644 +//line sql.y:6648 { yyLOCAL = &GeomPropertyFuncExpr{Property: Dimension, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1298: + case 1300: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6648 +//line sql.y:6652 { yyLOCAL = &GeomPropertyFuncExpr{Property: Envelope, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1299: + case 1301: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6652 +//line sql.y:6656 { yyLOCAL = &GeomPropertyFuncExpr{Property: GeometryType, Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1300: + case 1302: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6656 +//line sql.y:6660 { yyLOCAL = &PointPropertyFuncExpr{Property: Latitude, Point: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1301: + case 1303: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6660 +//line sql.y:6664 { yyLOCAL = &PointPropertyFuncExpr{Property: Latitude, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1302: + case 1304: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6664 +//line sql.y:6668 { yyLOCAL = &PointPropertyFuncExpr{Property: Longitude, Point: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1303: + case 1305: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6668 +//line sql.y:6672 { yyLOCAL = &PointPropertyFuncExpr{Property: Longitude, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1304: + case 1306: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6672 +//line sql.y:6676 { yyLOCAL = &LinestrPropertyFuncExpr{Property: EndPoint, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1305: + case 1307: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6676 +//line sql.y:6680 { yyLOCAL = &LinestrPropertyFuncExpr{Property: IsClosed, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1306: + case 1308: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6680 +//line sql.y:6684 { yyLOCAL = &LinestrPropertyFuncExpr{Property: Length, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1307: + case 1309: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6684 +//line sql.y:6688 { yyLOCAL = &LinestrPropertyFuncExpr{Property: Length, Linestring: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1308: + case 1310: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6688 +//line sql.y:6692 { yyLOCAL = &LinestrPropertyFuncExpr{Property: NumPoints, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1309: + case 1311: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6692 +//line sql.y:6696 { yyLOCAL = &LinestrPropertyFuncExpr{Property: PointN, Linestring: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1310: + case 1312: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6696 +//line sql.y:6700 { yyLOCAL = &LinestrPropertyFuncExpr{Property: StartPoint, Linestring: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1311: + case 1313: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6700 +//line sql.y:6704 { yyLOCAL = &PointPropertyFuncExpr{Property: XCordinate, Point: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1312: + case 1314: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6704 +//line sql.y:6708 { yyLOCAL = &PointPropertyFuncExpr{Property: XCordinate, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1313: + case 1315: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6708 +//line sql.y:6712 { yyLOCAL = &PointPropertyFuncExpr{Property: YCordinate, Point: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1314: + case 1316: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6712 +//line sql.y:6716 { yyLOCAL = &PointPropertyFuncExpr{Property: YCordinate, Point: yyDollar[3].exprUnion(), ValueToSet: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1315: + case 1317: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6716 +//line sql.y:6720 { yyLOCAL = &GeomFromTextExpr{Type: GeometryFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1316: + case 1318: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6720 +//line sql.y:6724 { yyLOCAL = &GeomFromTextExpr{Type: GeometryFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1317: + case 1319: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6724 +//line sql.y:6728 { yyLOCAL = &GeomFromTextExpr{Type: GeometryFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1318: + case 1320: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6728 +//line sql.y:6732 { yyLOCAL = &GeomFromTextExpr{Type: GeometryCollectionFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1319: + case 1321: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6732 +//line sql.y:6736 { yyLOCAL = &GeomFromTextExpr{Type: GeometryCollectionFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1320: + case 1322: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6736 +//line sql.y:6740 { yyLOCAL = &GeomFromTextExpr{Type: GeometryCollectionFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1321: + case 1323: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6740 +//line sql.y:6744 { yyLOCAL = &GeomFromTextExpr{Type: LineStringFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1322: + case 1324: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6744 +//line sql.y:6748 { yyLOCAL = &GeomFromTextExpr{Type: LineStringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1323: + case 1325: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6748 +//line sql.y:6752 { yyLOCAL = &GeomFromTextExpr{Type: LineStringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1324: + case 1326: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6752 +//line sql.y:6756 { yyLOCAL = &GeomFromTextExpr{Type: MultiLinestringFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1325: + case 1327: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6756 +//line sql.y:6760 { yyLOCAL = &GeomFromTextExpr{Type: MultiLinestringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1326: + case 1328: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6760 +//line sql.y:6764 { yyLOCAL = &GeomFromTextExpr{Type: MultiLinestringFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1327: + case 1329: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6764 +//line sql.y:6768 { yyLOCAL = &GeomFromTextExpr{Type: MultiPointFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1328: + case 1330: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6768 +//line sql.y:6772 { yyLOCAL = &GeomFromTextExpr{Type: MultiPointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1329: + case 1331: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6772 +//line sql.y:6776 { yyLOCAL = &GeomFromTextExpr{Type: MultiPointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1330: + case 1332: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6776 +//line sql.y:6780 { yyLOCAL = &GeomFromTextExpr{Type: MultiPolygonFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1331: + case 1333: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6780 +//line sql.y:6784 { yyLOCAL = &GeomFromTextExpr{Type: MultiPolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1332: + case 1334: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6784 +//line sql.y:6788 { yyLOCAL = &GeomFromTextExpr{Type: MultiPolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1333: + case 1335: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6788 +//line sql.y:6792 { yyLOCAL = &GeomFromTextExpr{Type: PointFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1334: + case 1336: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6792 +//line sql.y:6796 { yyLOCAL = &GeomFromTextExpr{Type: PointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1335: + case 1337: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6796 +//line sql.y:6800 { yyLOCAL = &GeomFromTextExpr{Type: PointFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1336: + case 1338: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6800 +//line sql.y:6804 { yyLOCAL = &GeomFromTextExpr{Type: PolygonFromText, WktText: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1337: + case 1339: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6804 +//line sql.y:6808 { yyLOCAL = &GeomFromTextExpr{Type: PolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1338: + case 1340: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6808 +//line sql.y:6812 { yyLOCAL = &GeomFromTextExpr{Type: PolygonFromText, WktText: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1339: + case 1341: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6812 +//line sql.y:6816 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1340: + case 1342: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6816 +//line sql.y:6820 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1341: + case 1343: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6820 +//line sql.y:6824 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1342: + case 1344: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6824 +//line sql.y:6828 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryCollectionFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1343: + case 1345: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6828 +//line sql.y:6832 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryCollectionFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1344: + case 1346: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6832 +//line sql.y:6836 { yyLOCAL = &GeomFromWKBExpr{Type: GeometryCollectionFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1345: + case 1347: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6836 +//line sql.y:6840 { yyLOCAL = &GeomFromWKBExpr{Type: LineStringFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1346: + case 1348: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6840 +//line sql.y:6844 { yyLOCAL = &GeomFromWKBExpr{Type: LineStringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1347: + case 1349: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6844 +//line sql.y:6848 { yyLOCAL = &GeomFromWKBExpr{Type: LineStringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1348: + case 1350: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6848 +//line sql.y:6852 { yyLOCAL = &GeomFromWKBExpr{Type: MultiLinestringFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1349: + case 1351: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6852 +//line sql.y:6856 { yyLOCAL = &GeomFromWKBExpr{Type: MultiLinestringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1350: + case 1352: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6856 +//line sql.y:6860 { yyLOCAL = &GeomFromWKBExpr{Type: MultiLinestringFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1351: + case 1353: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6860 +//line sql.y:6864 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPointFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1352: + case 1354: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6864 +//line sql.y:6868 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1353: + case 1355: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6868 +//line sql.y:6872 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1354: + case 1356: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6872 +//line sql.y:6876 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPolygonFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1355: + case 1357: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6876 +//line sql.y:6880 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1356: + case 1358: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6880 +//line sql.y:6884 { yyLOCAL = &GeomFromWKBExpr{Type: MultiPolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1357: + case 1359: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6884 +//line sql.y:6888 { yyLOCAL = &GeomFromWKBExpr{Type: PointFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1358: + case 1360: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6888 +//line sql.y:6892 { yyLOCAL = &GeomFromWKBExpr{Type: PointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1359: + case 1361: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6892 +//line sql.y:6896 { yyLOCAL = &GeomFromWKBExpr{Type: PointFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1360: + case 1362: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6896 +//line sql.y:6900 { yyLOCAL = &GeomFromWKBExpr{Type: PolygonFromWKB, WkbBlob: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1361: + case 1363: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6900 +//line sql.y:6904 { yyLOCAL = &GeomFromWKBExpr{Type: PolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1362: + case 1364: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6904 +//line sql.y:6908 { yyLOCAL = &GeomFromWKBExpr{Type: PolygonFromWKB, WkbBlob: yyDollar[3].exprUnion(), Srid: yyDollar[5].exprUnion(), AxisOrderOpt: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1363: + case 1365: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6908 +//line sql.y:6912 { yyLOCAL = &PolygonPropertyFuncExpr{Property: Area, Polygon: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1364: + case 1366: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6912 +//line sql.y:6916 { yyLOCAL = &PolygonPropertyFuncExpr{Property: Centroid, Polygon: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1365: + case 1367: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6916 +//line sql.y:6920 { yyLOCAL = &PolygonPropertyFuncExpr{Property: ExteriorRing, Polygon: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1366: + case 1368: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6920 +//line sql.y:6924 { yyLOCAL = &PolygonPropertyFuncExpr{Property: InteriorRingN, Polygon: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1367: + case 1369: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6924 +//line sql.y:6928 { yyLOCAL = &PolygonPropertyFuncExpr{Property: NumInteriorRings, Polygon: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1368: + case 1370: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6928 +//line sql.y:6932 { yyLOCAL = &GeomCollPropertyFuncExpr{Property: GeometryN, GeomColl: yyDollar[3].exprUnion(), PropertyDefArg: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1369: + case 1371: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6932 +//line sql.y:6936 { yyLOCAL = &GeomCollPropertyFuncExpr{Property: NumGeometries, GeomColl: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1370: + case 1372: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6936 +//line sql.y:6940 { yyLOCAL = &GeoHashFromLatLongExpr{Longitude: yyDollar[3].exprUnion(), Latitude: yyDollar[5].exprUnion(), MaxLength: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1371: + case 1373: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6940 +//line sql.y:6944 { yyLOCAL = &GeoHashFromPointExpr{Point: yyDollar[3].exprUnion(), MaxLength: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1372: + case 1374: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6944 +//line sql.y:6948 { yyLOCAL = &GeomFromGeoHashExpr{GeomType: LatitudeFromHash, GeoHash: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1373: + case 1375: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6948 +//line sql.y:6952 { yyLOCAL = &GeomFromGeoHashExpr{GeomType: LongitudeFromHash, GeoHash: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1374: + case 1376: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6952 +//line sql.y:6956 { yyLOCAL = &GeomFromGeoHashExpr{GeomType: PointFromHash, GeoHash: yyDollar[3].exprUnion(), SridOpt: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1375: + case 1377: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6956 +//line sql.y:6960 { yyLOCAL = &GeomFromGeoJSONExpr{GeoJSON: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1376: + case 1378: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6960 +//line sql.y:6964 { yyLOCAL = &GeomFromGeoJSONExpr{GeoJSON: yyDollar[3].exprUnion(), HigherDimHandlerOpt: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1377: + case 1379: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6964 +//line sql.y:6968 { yyLOCAL = &GeomFromGeoJSONExpr{GeoJSON: yyDollar[3].exprUnion(), HigherDimHandlerOpt: yyDollar[5].exprUnion(), Srid: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1378: + case 1380: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6968 +//line sql.y:6972 { yyLOCAL = &GeoJSONFromGeomExpr{Geom: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1379: + case 1381: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6972 +//line sql.y:6976 { yyLOCAL = &GeoJSONFromGeomExpr{Geom: yyDollar[3].exprUnion(), MaxDecimalDigits: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1380: + case 1382: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6976 +//line sql.y:6980 { yyLOCAL = &GeoJSONFromGeomExpr{Geom: yyDollar[3].exprUnion(), MaxDecimalDigits: yyDollar[5].exprUnion(), Bitmask: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1381: + case 1383: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6980 +//line sql.y:6984 { yyLOCAL = &JSONObjectExpr{Params: yyDollar[3].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL - case 1382: + case 1384: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:6984 +//line sql.y:6988 { yyLOCAL = &JSONQuoteExpr{StringArg: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1383: + case 1385: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6988 +//line sql.y:6992 { yyLOCAL = &JSONContainsExpr{Target: yyDollar[3].exprUnion(), Candidate: yyDollar[5].exprsUnion()[0], PathList: yyDollar[5].exprsUnion()[1:]} } yyVAL.union = yyLOCAL - case 1384: + case 1386: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:6992 +//line sql.y:6996 { yyLOCAL = &JSONContainsPathExpr{JSONDoc: yyDollar[3].exprUnion(), OneOrAll: yyDollar[5].exprUnion(), PathList: yyDollar[7].exprsUnion()} } yyVAL.union = yyLOCAL - case 1385: + case 1387: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:6996 +//line sql.y:7000 { yyLOCAL = &JSONExtractExpr{JSONDoc: yyDollar[3].exprUnion(), PathList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1386: + case 1388: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7000 +//line sql.y:7004 { yyLOCAL = &JSONKeysExpr{JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1387: + case 1389: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7004 +//line sql.y:7008 { yyLOCAL = &JSONKeysExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1388: + case 1390: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7008 +//line sql.y:7012 { yyLOCAL = &JSONOverlapsExpr{JSONDoc1: yyDollar[3].exprUnion(), JSONDoc2: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1389: + case 1391: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7012 +//line sql.y:7016 { yyLOCAL = &JSONSearchExpr{JSONDoc: yyDollar[3].exprUnion(), OneOrAll: yyDollar[5].exprUnion(), SearchStr: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1390: + case 1392: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:7016 +//line sql.y:7020 { yyLOCAL = &JSONSearchExpr{JSONDoc: yyDollar[3].exprUnion(), OneOrAll: yyDollar[5].exprUnion(), SearchStr: yyDollar[7].exprUnion(), EscapeChar: yyDollar[9].exprsUnion()[0], PathList: yyDollar[9].exprsUnion()[1:]} } yyVAL.union = yyLOCAL - case 1391: + case 1393: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Expr -//line sql.y:7020 +//line sql.y:7024 { yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion()} } yyVAL.union = yyLOCAL - case 1392: + case 1394: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7024 +//line sql.y:7028 { yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion(), EmptyOnResponse: yyDollar[7].jtOnResponseUnion()} } yyVAL.union = yyLOCAL - case 1393: + case 1395: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7028 +//line sql.y:7032 { yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion(), ErrorOnResponse: yyDollar[7].jtOnResponseUnion()} } yyVAL.union = yyLOCAL - case 1394: + case 1396: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL Expr -//line sql.y:7032 +//line sql.y:7036 { yyLOCAL = &JSONValueExpr{JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion(), ReturningType: yyDollar[6].convertTypeUnion(), EmptyOnResponse: yyDollar[7].jtOnResponseUnion(), ErrorOnResponse: yyDollar[8].jtOnResponseUnion()} } yyVAL.union = yyLOCAL - case 1395: + case 1397: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7036 +//line sql.y:7040 { yyLOCAL = &JSONAttributesExpr{Type: DepthAttributeType, JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1396: + case 1398: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7040 +//line sql.y:7044 { yyLOCAL = &JSONAttributesExpr{Type: ValidAttributeType, JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1397: + case 1399: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7044 +//line sql.y:7048 { yyLOCAL = &JSONAttributesExpr{Type: TypeAttributeType, JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1398: + case 1400: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7048 +//line sql.y:7052 { yyLOCAL = &JSONAttributesExpr{Type: LengthAttributeType, JSONDoc: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1399: + case 1401: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7052 +//line sql.y:7056 { yyLOCAL = &JSONAttributesExpr{Type: LengthAttributeType, JSONDoc: yyDollar[3].exprUnion(), Path: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1400: + case 1402: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7056 +//line sql.y:7060 { yyLOCAL = &JSONValueModifierExpr{Type: JSONArrayAppendType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL - case 1401: + case 1403: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7060 +//line sql.y:7064 { yyLOCAL = &JSONValueModifierExpr{Type: JSONArrayInsertType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL - case 1402: + case 1404: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7064 +//line sql.y:7068 { yyLOCAL = &JSONValueModifierExpr{Type: JSONInsertType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL - case 1403: + case 1405: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7068 +//line sql.y:7072 { yyLOCAL = &JSONValueModifierExpr{Type: JSONReplaceType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL - case 1404: + case 1406: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7072 +//line sql.y:7076 { yyLOCAL = &JSONValueModifierExpr{Type: JSONSetType, JSONDoc: yyDollar[3].exprUnion(), Params: yyDollar[5].jsonObjectParamsUnion()} } yyVAL.union = yyLOCAL - case 1405: + case 1407: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7076 +//line sql.y:7080 { yyLOCAL = &JSONValueMergeExpr{Type: JSONMergeType, JSONDoc: yyDollar[3].exprUnion(), JSONDocList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1406: + case 1408: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7080 +//line sql.y:7084 { yyLOCAL = &JSONValueMergeExpr{Type: JSONMergePatchType, JSONDoc: yyDollar[3].exprUnion(), JSONDocList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1407: + case 1409: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7084 +//line sql.y:7088 { yyLOCAL = &JSONValueMergeExpr{Type: JSONMergePreserveType, JSONDoc: yyDollar[3].exprUnion(), JSONDocList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1408: + case 1410: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7088 +//line sql.y:7092 { yyLOCAL = &JSONRemoveExpr{JSONDoc: yyDollar[3].exprUnion(), PathList: yyDollar[5].exprsUnion()} } yyVAL.union = yyLOCAL - case 1409: + case 1411: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7092 +//line sql.y:7096 { yyLOCAL = &JSONUnquoteExpr{JSONValue: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1410: + case 1412: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7096 +//line sql.y:7100 { yyLOCAL = &MultiPolygonExpr{PolygonParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1411: + case 1413: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7100 +//line sql.y:7104 { yyLOCAL = &MultiPointExpr{PointParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1412: + case 1414: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7104 +//line sql.y:7108 { yyLOCAL = &MultiLinestringExpr{LinestringParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1413: + case 1415: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7108 +//line sql.y:7112 { yyLOCAL = &PolygonExpr{LinestringParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1414: + case 1416: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7112 +//line sql.y:7116 { yyLOCAL = &LineStringExpr{PointParams: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1415: + case 1417: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7116 +//line sql.y:7120 { yyLOCAL = &PointExpr{XCordinate: yyDollar[3].exprUnion(), YCordinate: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1416: + case 1418: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7120 +//line sql.y:7124 { yyLOCAL = &ArgumentLessWindowExpr{Type: yyDollar[1].argumentLessWindowExprTypeUnion(), OverClause: yyDollar[4].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1417: + case 1419: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7124 +//line sql.y:7128 { yyLOCAL = &FirstOrLastValueExpr{Type: yyDollar[1].firstOrLastValueExprTypeUnion(), Expr: yyDollar[3].exprUnion(), NullTreatmentClause: yyDollar[5].nullTreatmentClauseUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1418: + case 1420: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:7128 +//line sql.y:7132 { yyLOCAL = &NtileExpr{N: yyDollar[3].exprUnion(), OverClause: yyDollar[5].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1419: + case 1421: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL Expr -//line sql.y:7132 +//line sql.y:7136 { yyLOCAL = &NTHValueExpr{Expr: yyDollar[3].exprUnion(), N: yyDollar[5].exprUnion(), FromFirstLastClause: yyDollar[7].fromFirstLastClauseUnion(), NullTreatmentClause: yyDollar[8].nullTreatmentClauseUnion(), OverClause: yyDollar[9].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1420: + case 1422: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7136 +//line sql.y:7140 { yyLOCAL = &LagLeadExpr{Type: yyDollar[1].lagLeadExprTypeUnion(), Expr: yyDollar[3].exprUnion(), NullTreatmentClause: yyDollar[5].nullTreatmentClauseUnion(), OverClause: yyDollar[6].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1421: + case 1423: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL Expr -//line sql.y:7140 +//line sql.y:7144 { yyLOCAL = &LagLeadExpr{Type: yyDollar[1].lagLeadExprTypeUnion(), Expr: yyDollar[3].exprUnion(), N: yyDollar[5].exprUnion(), Default: yyDollar[6].exprUnion(), NullTreatmentClause: yyDollar[8].nullTreatmentClauseUnion(), OverClause: yyDollar[9].overClauseUnion()} } yyVAL.union = yyLOCAL - case 1422: + case 1424: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7144 +//line sql.y:7148 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprAdddate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1423: + case 1425: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7148 +//line sql.y:7152 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprAdddate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[5].exprUnion(), Unit: IntervalNone} } yyVAL.union = yyLOCAL - case 1424: + case 1426: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7152 +//line sql.y:7156 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprDateAdd, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1425: + case 1427: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7156 +//line sql.y:7160 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprDateSub, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1426: + case 1428: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7160 +//line sql.y:7164 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprSubdate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[6].exprUnion(), Unit: yyDollar[7].intervalTypeUnion()} } yyVAL.union = yyLOCAL - case 1427: + case 1429: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7164 +//line sql.y:7168 { yyLOCAL = &IntervalDateExpr{Syntax: IntervalDateExprSubdate, Date: yyDollar[3].exprUnion(), Interval: yyDollar[5].exprUnion(), Unit: IntervalNone} } yyVAL.union = yyLOCAL - case 1432: + case 1434: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7174 +//line sql.y:7178 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1433: + case 1435: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7178 +//line sql.y:7182 { yyLOCAL = NewIntLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 1434: + case 1436: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7182 +//line sql.y:7186 { yyLOCAL = yyDollar[1].variableUnion() } yyVAL.union = yyLOCAL - case 1435: + case 1437: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7186 +//line sql.y:7190 { yyLOCAL = parseBindVariable(yylex, yyDollar[1].str[1:]) } yyVAL.union = yyLOCAL - case 1436: + case 1438: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:7191 +//line sql.y:7195 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1437: + case 1439: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7195 +//line sql.y:7199 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 1438: + case 1440: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7201 +//line sql.y:7205 { yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1439: + case 1441: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7205 +//line sql.y:7209 { yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1440: + case 1442: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:7209 +//line sql.y:7213 { yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion()} } yyVAL.union = yyLOCAL - case 1441: + case 1443: yyDollar = yyS[yypt-12 : yypt+1] var yyLOCAL Expr -//line sql.y:7213 +//line sql.y:7217 { yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion(), ReturnOption: yyDollar[11].exprUnion()} } yyVAL.union = yyLOCAL - case 1442: + case 1444: yyDollar = yyS[yypt-14 : yypt+1] var yyLOCAL Expr -//line sql.y:7217 +//line sql.y:7221 { // Match type is kept expression as TRIM( ' m ') is accepted yyLOCAL = &RegexpInstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion(), ReturnOption: yyDollar[11].exprUnion(), MatchType: yyDollar[13].exprUnion()} } yyVAL.union = yyLOCAL - case 1443: + case 1445: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7222 +//line sql.y:7226 { yyLOCAL = &RegexpLikeExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1444: + case 1446: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7226 +//line sql.y:7230 { yyLOCAL = &RegexpLikeExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), MatchType: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1445: + case 1447: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7230 +//line sql.y:7234 { yyLOCAL = &RegexpReplaceExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Repl: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1446: + case 1448: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:7234 +//line sql.y:7238 { yyLOCAL = &RegexpReplaceExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Repl: yyDollar[7].exprUnion(), Position: yyDollar[9].exprUnion()} } yyVAL.union = yyLOCAL - case 1447: + case 1449: yyDollar = yyS[yypt-12 : yypt+1] var yyLOCAL Expr -//line sql.y:7238 +//line sql.y:7242 { yyLOCAL = &RegexpReplaceExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Repl: yyDollar[7].exprUnion(), Position: yyDollar[9].exprUnion(), Occurrence: yyDollar[11].exprUnion()} } yyVAL.union = yyLOCAL - case 1448: + case 1450: yyDollar = yyS[yypt-14 : yypt+1] var yyLOCAL Expr -//line sql.y:7242 +//line sql.y:7246 { // Match type is kept expression as TRIM( ' m ') is accepted yyLOCAL = &RegexpReplaceExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Repl: yyDollar[7].exprUnion(), Position: yyDollar[9].exprUnion(), Occurrence: yyDollar[11].exprUnion(), MatchType: yyDollar[13].exprUnion()} } yyVAL.union = yyLOCAL - case 1449: + case 1451: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7247 +//line sql.y:7251 { yyLOCAL = &RegexpSubstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1450: + case 1452: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7251 +//line sql.y:7255 { yyLOCAL = &RegexpSubstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1451: + case 1453: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Expr -//line sql.y:7255 +//line sql.y:7259 { yyLOCAL = &RegexpSubstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion()} } yyVAL.union = yyLOCAL - case 1452: + case 1454: yyDollar = yyS[yypt-12 : yypt+1] var yyLOCAL Expr -//line sql.y:7259 +//line sql.y:7263 { // Match type is kept expression as TRIM( ' m ') is accepted yyLOCAL = &RegexpSubstrExpr{Expr: yyDollar[3].exprUnion(), Pattern: yyDollar[5].exprUnion(), Position: yyDollar[7].exprUnion(), Occurrence: yyDollar[9].exprUnion(), MatchType: yyDollar[11].exprUnion()} } yyVAL.union = yyLOCAL - case 1453: + case 1455: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7266 +//line sql.y:7270 { yyLOCAL = &ExtractValueExpr{Fragment: yyDollar[3].exprUnion(), XPathExpr: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1454: + case 1456: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7270 +//line sql.y:7274 { yyLOCAL = &UpdateXMLExpr{Target: yyDollar[3].exprUnion(), XPathExpr: yyDollar[5].exprUnion(), NewXML: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1455: + case 1457: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7276 +//line sql.y:7280 { yyLOCAL = &PerformanceSchemaFuncExpr{Type: FormatBytesType, Argument: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1456: + case 1458: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7280 +//line sql.y:7284 { yyLOCAL = &PerformanceSchemaFuncExpr{Type: FormatPicoTimeType, Argument: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1457: + case 1459: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:7284 +//line sql.y:7288 { yyLOCAL = &PerformanceSchemaFuncExpr{Type: PsCurrentThreadIDType} } yyVAL.union = yyLOCAL - case 1458: + case 1460: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7288 +//line sql.y:7292 { yyLOCAL = &PerformanceSchemaFuncExpr{Type: PsThreadIDType, Argument: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1459: + case 1461: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7294 +//line sql.y:7298 { yyLOCAL = >IDFuncExpr{Type: GTIDSubsetType, Set1: yyDollar[3].exprUnion(), Set2: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1460: + case 1462: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7298 +//line sql.y:7302 { yyLOCAL = >IDFuncExpr{Type: GTIDSubtractType, Set1: yyDollar[3].exprUnion(), Set2: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1461: + case 1463: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7302 +//line sql.y:7306 { yyLOCAL = >IDFuncExpr{Type: WaitForExecutedGTIDSetType, Set1: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1462: + case 1464: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7306 +//line sql.y:7310 { yyLOCAL = >IDFuncExpr{Type: WaitForExecutedGTIDSetType, Set1: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1463: + case 1465: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7310 +//line sql.y:7314 { yyLOCAL = >IDFuncExpr{Type: WaitUntilSQLThreadAfterGTIDSType, Set1: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1464: + case 1466: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:7314 +//line sql.y:7318 { yyLOCAL = >IDFuncExpr{Type: WaitUntilSQLThreadAfterGTIDSType, Set1: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 1465: + case 1467: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:7318 +//line sql.y:7322 { yyLOCAL = >IDFuncExpr{Type: WaitUntilSQLThreadAfterGTIDSType, Set1: yyDollar[3].exprUnion(), Timeout: yyDollar[5].exprUnion(), Channel: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 1466: + case 1468: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7323 +//line sql.y:7327 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1467: + case 1469: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7327 +//line sql.y:7331 { yyLOCAL = yyDollar[2].convertTypeUnion() } yyVAL.union = yyLOCAL - case 1468: + case 1470: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7333 +//line sql.y:7337 { yyLOCAL = IntervalDayHour } yyVAL.union = yyLOCAL - case 1469: + case 1471: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7337 +//line sql.y:7341 { yyLOCAL = IntervalDayMicrosecond } yyVAL.union = yyLOCAL - case 1470: + case 1472: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7341 +//line sql.y:7345 { yyLOCAL = IntervalDayMinute } yyVAL.union = yyLOCAL - case 1471: + case 1473: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7345 +//line sql.y:7349 { yyLOCAL = IntervalDaySecond } yyVAL.union = yyLOCAL - case 1472: + case 1474: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7349 +//line sql.y:7353 { yyLOCAL = IntervalHourMicrosecond } yyVAL.union = yyLOCAL - case 1473: + case 1475: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7353 +//line sql.y:7357 { yyLOCAL = IntervalHourMinute } yyVAL.union = yyLOCAL - case 1474: + case 1476: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7357 +//line sql.y:7361 { yyLOCAL = IntervalHourSecond } yyVAL.union = yyLOCAL - case 1475: + case 1477: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7361 +//line sql.y:7365 { yyLOCAL = IntervalMinuteMicrosecond } yyVAL.union = yyLOCAL - case 1476: + case 1478: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7365 +//line sql.y:7369 { yyLOCAL = IntervalMinuteSecond } yyVAL.union = yyLOCAL - case 1477: + case 1479: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7369 +//line sql.y:7373 { yyLOCAL = IntervalSecondMicrosecond } yyVAL.union = yyLOCAL - case 1478: + case 1480: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7373 +//line sql.y:7377 { yyLOCAL = IntervalYearMonth } yyVAL.union = yyLOCAL - case 1479: + case 1481: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7377 +//line sql.y:7381 { yyLOCAL = IntervalDay } yyVAL.union = yyLOCAL - case 1480: + case 1482: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7381 +//line sql.y:7385 { yyLOCAL = IntervalWeek } yyVAL.union = yyLOCAL - case 1481: + case 1483: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7385 +//line sql.y:7389 { yyLOCAL = IntervalHour } yyVAL.union = yyLOCAL - case 1482: + case 1484: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7389 +//line sql.y:7393 { yyLOCAL = IntervalMinute } yyVAL.union = yyLOCAL - case 1483: + case 1485: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7393 +//line sql.y:7397 { yyLOCAL = IntervalMonth } yyVAL.union = yyLOCAL - case 1484: + case 1486: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7397 +//line sql.y:7401 { yyLOCAL = IntervalQuarter } yyVAL.union = yyLOCAL - case 1485: + case 1487: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7401 +//line sql.y:7405 { yyLOCAL = IntervalSecond } yyVAL.union = yyLOCAL - case 1486: + case 1488: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7405 +//line sql.y:7409 { yyLOCAL = IntervalMicrosecond } yyVAL.union = yyLOCAL - case 1487: + case 1489: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7409 +//line sql.y:7413 { yyLOCAL = IntervalYear } yyVAL.union = yyLOCAL - case 1488: + case 1490: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7415 +//line sql.y:7419 { yyLOCAL = IntervalDay } yyVAL.union = yyLOCAL - case 1489: + case 1491: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7419 +//line sql.y:7423 { yyLOCAL = IntervalWeek } yyVAL.union = yyLOCAL - case 1490: + case 1492: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7423 +//line sql.y:7427 { yyLOCAL = IntervalHour } yyVAL.union = yyLOCAL - case 1491: + case 1493: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7427 +//line sql.y:7431 { yyLOCAL = IntervalMinute } yyVAL.union = yyLOCAL - case 1492: + case 1494: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7431 +//line sql.y:7435 { yyLOCAL = IntervalMonth } yyVAL.union = yyLOCAL - case 1493: + case 1495: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7435 +//line sql.y:7439 { yyLOCAL = IntervalQuarter } yyVAL.union = yyLOCAL - case 1494: + case 1496: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7439 +//line sql.y:7443 { yyLOCAL = IntervalSecond } yyVAL.union = yyLOCAL - case 1495: + case 1497: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7443 +//line sql.y:7447 { yyLOCAL = IntervalMicrosecond } yyVAL.union = yyLOCAL - case 1496: + case 1498: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7447 +//line sql.y:7451 { yyLOCAL = IntervalYear } yyVAL.union = yyLOCAL - case 1497: + case 1499: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7451 +//line sql.y:7455 { yyLOCAL = IntervalDay } yyVAL.union = yyLOCAL - case 1498: + case 1500: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7455 +//line sql.y:7459 { yyLOCAL = IntervalWeek } yyVAL.union = yyLOCAL - case 1499: + case 1501: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7459 +//line sql.y:7463 { yyLOCAL = IntervalHour } yyVAL.union = yyLOCAL - case 1500: + case 1502: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7463 +//line sql.y:7467 { yyLOCAL = IntervalMinute } yyVAL.union = yyLOCAL - case 1501: + case 1503: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7467 +//line sql.y:7471 { yyLOCAL = IntervalMonth } yyVAL.union = yyLOCAL - case 1502: + case 1504: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7471 +//line sql.y:7475 { yyLOCAL = IntervalQuarter } yyVAL.union = yyLOCAL - case 1503: + case 1505: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7475 +//line sql.y:7479 { yyLOCAL = IntervalSecond } yyVAL.union = yyLOCAL - case 1504: + case 1506: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7479 +//line sql.y:7483 { yyLOCAL = IntervalMicrosecond } yyVAL.union = yyLOCAL - case 1505: + case 1507: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IntervalType -//line sql.y:7483 +//line sql.y:7487 { yyLOCAL = IntervalYear } yyVAL.union = yyLOCAL - case 1508: + case 1510: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL int -//line sql.y:7493 +//line sql.y:7497 { yyLOCAL = 0 } yyVAL.union = yyLOCAL - case 1509: + case 1511: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL int -//line sql.y:7497 +//line sql.y:7501 { yyLOCAL = 0 } yyVAL.union = yyLOCAL - case 1510: + case 1512: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL int -//line sql.y:7501 +//line sql.y:7505 { yyLOCAL = convertStringToInt(yyDollar[2].str) } yyVAL.union = yyLOCAL - case 1511: + case 1513: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7511 +//line sql.y:7515 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("if"), Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1512: + case 1514: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7515 +//line sql.y:7519 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("database"), Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1513: + case 1515: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7519 +//line sql.y:7523 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("schema"), Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1514: + case 1516: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7523 +//line sql.y:7527 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("mod"), Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1515: + case 1517: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:7527 +//line sql.y:7531 { yyLOCAL = &FuncExpr{Name: NewIdentifierCI("replace"), Exprs: yyDollar[3].exprsUnion()} } yyVAL.union = yyLOCAL - case 1516: + case 1518: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7533 +//line sql.y:7537 { yyLOCAL = NoOption } yyVAL.union = yyLOCAL - case 1517: + case 1519: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7537 +//line sql.y:7541 { yyLOCAL = BooleanModeOpt } yyVAL.union = yyLOCAL - case 1518: + case 1520: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7541 +//line sql.y:7545 { yyLOCAL = NaturalLanguageModeOpt } yyVAL.union = yyLOCAL - case 1519: + case 1521: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7545 +//line sql.y:7549 { yyLOCAL = NaturalLanguageModeWithQueryExpansionOpt } yyVAL.union = yyLOCAL - case 1520: + case 1522: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:7549 +//line sql.y:7553 { yyLOCAL = QueryExpansionOpt } yyVAL.union = yyLOCAL - case 1521: + case 1523: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7555 +//line sql.y:7559 { yyVAL.str = string(yyDollar[1].identifierCI.String()) } - case 1522: + case 1524: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7559 +//line sql.y:7563 { yyVAL.str = string(yyDollar[1].str) } - case 1523: + case 1525: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7563 +//line sql.y:7567 { yyVAL.str = string(yyDollar[1].str) } - case 1524: + case 1526: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7569 +//line sql.y:7573 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1525: + case 1527: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7573 +//line sql.y:7577 { yyLOCAL = &ConvertType{Type: string(yyDollar[2].str), Length: ptr.Of(convertStringToInt(yyDollar[4].str))} } yyVAL.union = yyLOCAL - case 1526: + case 1528: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7577 +//line sql.y:7581 { yyLOCAL = &ConvertType{Type: string(yyDollar[2].str), Length: ptr.Of(convertStringToInt(yyDollar[4].str))} } yyVAL.union = yyLOCAL - case 1527: + case 1529: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7583 +//line sql.y:7587 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } yyVAL.union = yyLOCAL - case 1528: + case 1530: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7587 +//line sql.y:7591 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion(), Charset: yyDollar[3].columnCharset} } yyVAL.union = yyLOCAL - case 1529: + case 1531: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7591 +//line sql.y:7595 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1530: + case 1532: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7595 +//line sql.y:7599 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } yyVAL.union = yyLOCAL - case 1531: + case 1533: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7599 +//line sql.y:7603 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} yyLOCAL.Length = yyDollar[2].LengthScaleOption.Length yyLOCAL.Scale = yyDollar[2].LengthScaleOption.Scale } yyVAL.union = yyLOCAL - case 1532: + case 1534: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7605 +//line sql.y:7609 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1533: + case 1535: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7609 +//line sql.y:7613 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } yyVAL.union = yyLOCAL - case 1534: + case 1536: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7613 +//line sql.y:7617 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1535: + case 1537: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7617 +//line sql.y:7621 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1536: + case 1538: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7621 +//line sql.y:7625 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } yyVAL.union = yyLOCAL - case 1537: + case 1539: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7625 +//line sql.y:7629 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1538: + case 1540: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7629 +//line sql.y:7633 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1539: + case 1541: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7633 +//line sql.y:7637 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].intPtrUnion()} } yyVAL.union = yyLOCAL - case 1540: + case 1542: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7637 +//line sql.y:7641 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1541: + case 1543: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:7641 +//line sql.y:7645 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1542: + case 1544: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7647 +//line sql.y:7651 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1543: + case 1545: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:7651 +//line sql.y:7655 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1544: + case 1546: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:7656 +//line sql.y:7660 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1545: + case 1547: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7660 +//line sql.y:7664 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 1546: + case 1548: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7665 +//line sql.y:7669 { yyVAL.str = string("") } - case 1547: + case 1549: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7669 +//line sql.y:7673 { yyVAL.str = encodeSQLString(yyDollar[2].str) } - case 1548: + case 1550: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*When -//line sql.y:7675 +//line sql.y:7679 { yyLOCAL = []*When{yyDollar[1].whenUnion()} } yyVAL.union = yyLOCAL - case 1549: + case 1551: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:7679 +//line sql.y:7683 { yySLICE := (*[]*When)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].whenUnion()) } - case 1550: + case 1552: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *When -//line sql.y:7685 +//line sql.y:7689 { yyLOCAL = &When{Cond: yyDollar[2].exprUnion(), Val: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1551: + case 1553: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:7690 +//line sql.y:7694 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1552: + case 1554: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7694 +//line sql.y:7698 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 1553: + case 1555: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ColName -//line sql.y:7700 +//line sql.y:7704 { yyLOCAL = &ColName{Name: yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL - case 1554: + case 1556: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ColName -//line sql.y:7704 +//line sql.y:7708 { yyLOCAL = &ColName{Name: NewIdentifierCI(string(yyDollar[1].str))} } yyVAL.union = yyLOCAL - case 1555: + case 1557: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColName -//line sql.y:7708 +//line sql.y:7712 { yyLOCAL = &ColName{Qualifier: TableName{Name: yyDollar[1].identifierCS}, Name: yyDollar[3].identifierCI} } yyVAL.union = yyLOCAL - case 1556: + case 1558: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ColName -//line sql.y:7712 +//line sql.y:7716 { yyLOCAL = &ColName{Qualifier: TableName{Qualifier: yyDollar[1].identifierCS, Name: yyDollar[3].identifierCS}, Name: yyDollar[5].identifierCI} } yyVAL.union = yyLOCAL - case 1557: + case 1559: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7718 +//line sql.y:7722 { yyLOCAL = yyDollar[1].colNameUnion() } yyVAL.union = yyLOCAL - case 1558: + case 1560: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7722 +//line sql.y:7726 { yyLOCAL = &Offset{V: convertStringToInt(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 1559: + case 1561: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:7728 +//line sql.y:7732 { // TODO(sougou): Deprecate this construct. if yyDollar[1].identifierCI.Lowered() != "value" { @@ -22829,513 +22973,513 @@ yydefault: yyLOCAL = NewIntLiteral("1") } yyVAL.union = yyLOCAL - case 1560: + case 1562: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7737 +//line sql.y:7741 { yyLOCAL = NewIntLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 1561: + case 1563: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7741 +//line sql.y:7745 { yyLOCAL = parseBindVariable(yylex, yyDollar[1].str[1:]) } yyVAL.union = yyLOCAL - case 1562: + case 1564: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *GroupBy -//line sql.y:7746 +//line sql.y:7750 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1563: + case 1565: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *GroupBy -//line sql.y:7750 +//line sql.y:7754 { yyLOCAL = &GroupBy{Exprs: yyDollar[3].exprsUnion(), WithRollup: yyDollar[4].booleanUnion()} } yyVAL.union = yyLOCAL - case 1564: + case 1566: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:7755 +//line sql.y:7759 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1565: + case 1567: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:7759 +//line sql.y:7763 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1566: + case 1568: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:7765 +//line sql.y:7769 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1567: + case 1569: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:7769 +//line sql.y:7773 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 1568: + case 1570: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *NamedWindow -//line sql.y:7775 +//line sql.y:7779 { yyLOCAL = &NamedWindow{yyDollar[2].windowDefinitionsUnion()} } yyVAL.union = yyLOCAL - case 1569: + case 1571: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL NamedWindows -//line sql.y:7781 +//line sql.y:7785 { yyLOCAL = NamedWindows{yyDollar[1].namedWindowUnion()} } yyVAL.union = yyLOCAL - case 1570: + case 1572: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7785 +//line sql.y:7789 { yySLICE := (*NamedWindows)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].namedWindowUnion()) } - case 1571: + case 1573: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL NamedWindows -//line sql.y:7790 +//line sql.y:7794 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1572: + case 1574: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL NamedWindows -//line sql.y:7794 +//line sql.y:7798 { yyLOCAL = yyDollar[1].namedWindowsUnion() } yyVAL.union = yyLOCAL - case 1573: + case 1575: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL OrderBy -//line sql.y:7799 +//line sql.y:7803 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1574: + case 1576: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderBy -//line sql.y:7803 +//line sql.y:7807 { yyLOCAL = yyDollar[1].orderByUnion() } yyVAL.union = yyLOCAL - case 1575: + case 1577: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL OrderBy -//line sql.y:7809 +//line sql.y:7813 { yyLOCAL = yyDollar[3].orderByUnion() } yyVAL.union = yyLOCAL - case 1576: + case 1578: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderBy -//line sql.y:7815 +//line sql.y:7819 { yyLOCAL = OrderBy{yyDollar[1].orderUnion()} } yyVAL.union = yyLOCAL - case 1577: + case 1579: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7819 +//line sql.y:7823 { yySLICE := (*OrderBy)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].orderUnion()) } - case 1578: + case 1580: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Order -//line sql.y:7825 +//line sql.y:7829 { yyLOCAL = &Order{Expr: yyDollar[1].exprUnion(), Direction: yyDollar[2].orderDirectionUnion()} } yyVAL.union = yyLOCAL - case 1579: + case 1581: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL OrderDirection -//line sql.y:7830 +//line sql.y:7834 { yyLOCAL = AscOrder } yyVAL.union = yyLOCAL - case 1580: + case 1582: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderDirection -//line sql.y:7834 +//line sql.y:7838 { yyLOCAL = AscOrder } yyVAL.union = yyLOCAL - case 1581: + case 1583: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderDirection -//line sql.y:7838 +//line sql.y:7842 { yyLOCAL = DescOrder } yyVAL.union = yyLOCAL - case 1582: + case 1584: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *Limit -//line sql.y:7843 +//line sql.y:7847 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1583: + case 1585: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Limit -//line sql.y:7847 +//line sql.y:7851 { yyLOCAL = yyDollar[1].limitUnion() } yyVAL.union = yyLOCAL - case 1584: + case 1586: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Limit -//line sql.y:7853 +//line sql.y:7857 { yyLOCAL = &Limit{Rowcount: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1585: + case 1587: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Limit -//line sql.y:7857 +//line sql.y:7861 { yyLOCAL = &Limit{Offset: yyDollar[2].exprUnion(), Rowcount: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 1586: + case 1588: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Limit -//line sql.y:7861 +//line sql.y:7865 { yyLOCAL = &Limit{Offset: yyDollar[4].exprUnion(), Rowcount: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 1587: + case 1589: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7866 +//line sql.y:7870 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1588: + case 1590: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7870 +//line sql.y:7874 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion(), yyDollar[2].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 1589: + case 1591: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7874 +//line sql.y:7878 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion(), yyDollar[2].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 1590: + case 1592: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7878 +//line sql.y:7882 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 1591: + case 1593: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:7882 +//line sql.y:7886 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 1592: + case 1594: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7889 +//line sql.y:7893 { yyLOCAL = &LockOption{Type: DefaultType} } yyVAL.union = yyLOCAL - case 1593: + case 1595: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7893 +//line sql.y:7897 { yyLOCAL = &LockOption{Type: NoneType} } yyVAL.union = yyLOCAL - case 1594: + case 1596: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7897 +//line sql.y:7901 { yyLOCAL = &LockOption{Type: SharedType} } yyVAL.union = yyLOCAL - case 1595: + case 1597: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7901 +//line sql.y:7905 { yyLOCAL = &LockOption{Type: ExclusiveType} } yyVAL.union = yyLOCAL - case 1596: + case 1598: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7907 +//line sql.y:7911 { yyLOCAL = AlgorithmValue(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1597: + case 1599: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7911 +//line sql.y:7915 { yyLOCAL = AlgorithmValue(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1598: + case 1600: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7915 +//line sql.y:7919 { yyLOCAL = AlgorithmValue(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1599: + case 1601: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:7919 +//line sql.y:7923 { yyLOCAL = AlgorithmValue(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 1600: + case 1602: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7924 +//line sql.y:7928 { yyVAL.str = "" } - case 1602: + case 1604: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7931 +//line sql.y:7935 { yyVAL.str = string(yyDollar[3].str) } - case 1603: + case 1605: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7935 +//line sql.y:7939 { yyVAL.str = string(yyDollar[3].str) } - case 1604: + case 1606: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7939 +//line sql.y:7943 { yyVAL.str = string(yyDollar[3].str) } - case 1605: + case 1607: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7944 +//line sql.y:7948 { yyVAL.str = "" } - case 1606: + case 1608: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7948 +//line sql.y:7952 { yyVAL.str = yyDollar[3].str } - case 1607: + case 1609: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7954 +//line sql.y:7958 { yyVAL.str = string(yyDollar[1].str) } - case 1608: + case 1610: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7958 +//line sql.y:7962 { yyVAL.str = string(yyDollar[1].str) } - case 1609: + case 1611: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7963 +//line sql.y:7967 { yyVAL.str = "" } - case 1610: + case 1612: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:7967 +//line sql.y:7971 { yyVAL.str = yyDollar[2].str } - case 1611: + case 1613: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:7972 +//line sql.y:7976 { yyVAL.str = "cascaded" } - case 1612: + case 1614: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7976 +//line sql.y:7980 { yyVAL.str = string(yyDollar[1].str) } - case 1613: + case 1615: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:7980 +//line sql.y:7984 { yyVAL.str = string(yyDollar[1].str) } - case 1614: + case 1616: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*ProcParameter -//line sql.y:7985 +//line sql.y:7989 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1615: + case 1617: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*ProcParameter -//line sql.y:7989 +//line sql.y:7993 { yyLOCAL = yyDollar[1].procParamsUnion() } yyVAL.union = yyLOCAL - case 1616: + case 1618: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*ProcParameter -//line sql.y:7995 +//line sql.y:7999 { yyLOCAL = []*ProcParameter{yyDollar[1].procParamUnion()} } yyVAL.union = yyLOCAL - case 1617: + case 1619: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:7999 +//line sql.y:8003 { yySLICE := (*[]*ProcParameter)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].procParamUnion()) } - case 1618: + case 1620: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ProcParameter -//line sql.y:8005 +//line sql.y:8009 { yyLOCAL = &ProcParameter{Mode: yyDollar[1].procParamModeUnion(), Name: yyDollar[2].identifierCI, Type: yyDollar[3].columnType} } yyVAL.union = yyLOCAL - case 1619: + case 1621: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL ProcParameterMode -//line sql.y:8010 +//line sql.y:8014 { yyLOCAL = InMode } yyVAL.union = yyLOCAL - case 1620: + case 1622: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ProcParameterMode -//line sql.y:8014 +//line sql.y:8018 { yyLOCAL = InMode } yyVAL.union = yyLOCAL - case 1621: + case 1623: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ProcParameterMode -//line sql.y:8018 +//line sql.y:8022 { yyLOCAL = InoutMode } yyVAL.union = yyLOCAL - case 1622: + case 1624: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ProcParameterMode -//line sql.y:8022 +//line sql.y:8026 { yyLOCAL = OutMode } yyVAL.union = yyLOCAL - case 1623: + case 1625: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *Definer -//line sql.y:8027 +//line sql.y:8031 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1625: + case 1627: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *Definer -//line sql.y:8034 +//line sql.y:8038 { yyLOCAL = yyDollar[3].definerUnion() } yyVAL.union = yyLOCAL - case 1626: + case 1628: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Definer -//line sql.y:8040 +//line sql.y:8044 { yyLOCAL = &Definer{ Name: string(yyDollar[1].str), } } yyVAL.union = yyLOCAL - case 1627: + case 1629: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *Definer -//line sql.y:8046 +//line sql.y:8050 { yyLOCAL = &Definer{ Name: string(yyDollar[1].str), } } yyVAL.union = yyLOCAL - case 1628: + case 1630: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Definer -//line sql.y:8052 +//line sql.y:8056 { yyLOCAL = &Definer{ Name: yyDollar[1].str, @@ -23343,503 +23487,503 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1629: + case 1631: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8061 +//line sql.y:8065 { yyVAL.str = encodeSQLString(yyDollar[1].str) } - case 1630: + case 1632: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8065 +//line sql.y:8069 { yyVAL.str = formatIdentifier(yyDollar[1].str) } - case 1631: + case 1633: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8070 +//line sql.y:8074 { yyVAL.str = "" } - case 1632: + case 1634: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8074 +//line sql.y:8078 { yyVAL.str = formatAddress(yyDollar[1].str) } - case 1633: + case 1635: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Lock -//line sql.y:8080 +//line sql.y:8084 { yyLOCAL = ForUpdateLock } yyVAL.union = yyLOCAL - case 1634: + case 1636: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Lock -//line sql.y:8084 +//line sql.y:8088 { yyLOCAL = ForUpdateLockNoWait } yyVAL.union = yyLOCAL - case 1635: + case 1637: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Lock -//line sql.y:8088 +//line sql.y:8092 { yyLOCAL = ForUpdateLockSkipLocked } yyVAL.union = yyLOCAL - case 1636: + case 1638: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Lock -//line sql.y:8092 +//line sql.y:8096 { yyLOCAL = ForShareLock } yyVAL.union = yyLOCAL - case 1637: + case 1639: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Lock -//line sql.y:8096 +//line sql.y:8100 { yyLOCAL = ForShareLockNoWait } yyVAL.union = yyLOCAL - case 1638: + case 1640: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Lock -//line sql.y:8100 +//line sql.y:8104 { yyLOCAL = ForShareLockSkipLocked } yyVAL.union = yyLOCAL - case 1639: + case 1641: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Lock -//line sql.y:8104 +//line sql.y:8108 { yyLOCAL = ShareModeLock } yyVAL.union = yyLOCAL - case 1640: + case 1642: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:8110 +//line sql.y:8114 { yyLOCAL = &SelectInto{Type: IntoOutfileS3, FileName: encodeSQLString(yyDollar[4].str), Charset: yyDollar[5].columnCharset, FormatOption: yyDollar[6].str, ExportOption: yyDollar[7].str, Manifest: yyDollar[8].str, Overwrite: yyDollar[9].str} } yyVAL.union = yyLOCAL - case 1641: + case 1643: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:8114 +//line sql.y:8118 { yyLOCAL = &SelectInto{Type: IntoDumpfile, FileName: encodeSQLString(yyDollar[3].str), Charset: ColumnCharset{}, FormatOption: "", ExportOption: "", Manifest: "", Overwrite: ""} } yyVAL.union = yyLOCAL - case 1642: + case 1644: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:8118 +//line sql.y:8122 { yyLOCAL = &SelectInto{Type: IntoOutfile, FileName: encodeSQLString(yyDollar[3].str), Charset: yyDollar[4].columnCharset, FormatOption: "", ExportOption: yyDollar[5].str, Manifest: "", Overwrite: ""} } yyVAL.union = yyLOCAL - case 1643: + case 1645: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:8122 +//line sql.y:8126 { yyLOCAL = &SelectInto{Type: IntoVariables, VarList: yyDollar[2].variablesUnion()} } yyVAL.union = yyLOCAL - case 1644: + case 1646: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:8128 +//line sql.y:8132 { yySLICE := (*[]*Variable)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].variableUnion()) } - case 1645: + case 1647: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*Variable -//line sql.y:8132 +//line sql.y:8136 { yyLOCAL = []*Variable{yyDollar[1].variableUnion()} } yyVAL.union = yyLOCAL - case 1646: + case 1648: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Variable -//line sql.y:8138 +//line sql.y:8142 { yyLOCAL = yyDollar[1].variableUnion() } yyVAL.union = yyLOCAL - case 1647: + case 1649: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Variable -//line sql.y:8142 +//line sql.y:8146 { yyLOCAL = &Variable{Name: createIdentifierCI(yyDollar[1].str), Scope: NoScope} } yyVAL.union = yyLOCAL - case 1648: + case 1650: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8147 +//line sql.y:8151 { yyVAL.str = "" } - case 1649: + case 1651: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:8151 +//line sql.y:8155 { yyVAL.str = " format csv" + yyDollar[3].str } - case 1650: + case 1652: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:8155 +//line sql.y:8159 { yyVAL.str = " format text" + yyDollar[3].str } - case 1651: + case 1653: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8160 +//line sql.y:8164 { yyVAL.str = "" } - case 1652: + case 1654: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8164 +//line sql.y:8168 { yyVAL.str = " header" } - case 1653: + case 1655: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8169 +//line sql.y:8173 { yyVAL.str = "" } - case 1654: + case 1656: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:8173 +//line sql.y:8177 { yyVAL.str = " manifest on" } - case 1655: + case 1657: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:8177 +//line sql.y:8181 { yyVAL.str = " manifest off" } - case 1656: + case 1658: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8182 +//line sql.y:8186 { yyVAL.str = "" } - case 1657: + case 1659: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:8186 +//line sql.y:8190 { yyVAL.str = " overwrite on" } - case 1658: + case 1660: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:8190 +//line sql.y:8194 { yyVAL.str = " overwrite off" } - case 1659: + case 1661: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:8196 +//line sql.y:8200 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 1660: + case 1662: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8201 +//line sql.y:8205 { yyVAL.str = "" } - case 1661: + case 1663: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:8205 +//line sql.y:8209 { yyVAL.str = " lines" + yyDollar[2].str } - case 1662: + case 1664: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8211 +//line sql.y:8215 { yyVAL.str = yyDollar[1].str } - case 1663: + case 1665: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:8215 +//line sql.y:8219 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 1664: + case 1666: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:8221 +//line sql.y:8225 { yyVAL.str = " starting by " + encodeSQLString(yyDollar[3].str) } - case 1665: + case 1667: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:8225 +//line sql.y:8229 { yyVAL.str = " terminated by " + encodeSQLString(yyDollar[3].str) } - case 1666: + case 1668: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8230 +//line sql.y:8234 { yyVAL.str = "" } - case 1667: + case 1669: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:8234 +//line sql.y:8238 { yyVAL.str = " " + yyDollar[1].str + yyDollar[2].str } - case 1668: + case 1670: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8240 +//line sql.y:8244 { yyVAL.str = yyDollar[1].str } - case 1669: + case 1671: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:8244 +//line sql.y:8248 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 1670: + case 1672: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:8250 +//line sql.y:8254 { yyVAL.str = " terminated by " + encodeSQLString(yyDollar[3].str) } - case 1671: + case 1673: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:8254 +//line sql.y:8258 { yyVAL.str = yyDollar[1].str + " enclosed by " + encodeSQLString(yyDollar[4].str) } - case 1672: + case 1674: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:8258 +//line sql.y:8262 { yyVAL.str = " escaped by " + encodeSQLString(yyDollar[3].str) } - case 1673: + case 1675: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8263 +//line sql.y:8267 { yyVAL.str = "" } - case 1674: + case 1676: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8267 +//line sql.y:8271 { yyVAL.str = " optionally" } - case 1675: + case 1677: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *Insert -//line sql.y:8280 +//line sql.y:8284 { yyLOCAL = &Insert{Rows: yyDollar[2].valuesUnion(), RowAlias: yyDollar[3].rowAliasUnion()} } yyVAL.union = yyLOCAL - case 1676: + case 1678: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Insert -//line sql.y:8284 +//line sql.y:8288 { yyLOCAL = &Insert{Rows: yyDollar[1].tableStmtUnion()} } yyVAL.union = yyLOCAL - case 1677: + case 1679: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL *Insert -//line sql.y:8288 +//line sql.y:8292 { yyLOCAL = &Insert{Columns: yyDollar[2].columnsUnion(), Rows: yyDollar[5].valuesUnion(), RowAlias: yyDollar[6].rowAliasUnion()} } yyVAL.union = yyLOCAL - case 1678: + case 1680: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *Insert -//line sql.y:8292 +//line sql.y:8296 { yyLOCAL = &Insert{Columns: []IdentifierCI{}, Rows: yyDollar[4].valuesUnion(), RowAlias: yyDollar[5].rowAliasUnion()} } yyVAL.union = yyLOCAL - case 1679: + case 1681: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Insert -//line sql.y:8296 +//line sql.y:8300 { yyLOCAL = &Insert{Columns: yyDollar[2].columnsUnion(), Rows: yyDollar[4].tableStmtUnion()} } yyVAL.union = yyLOCAL - case 1680: + case 1682: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:8302 +//line sql.y:8306 { yyLOCAL = Columns{yyDollar[1].identifierCI} } yyVAL.union = yyLOCAL - case 1681: + case 1683: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Columns -//line sql.y:8306 +//line sql.y:8310 { yyLOCAL = Columns{yyDollar[3].identifierCI} } yyVAL.union = yyLOCAL - case 1682: + case 1684: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:8310 +//line sql.y:8314 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].identifierCI) } - case 1683: + case 1685: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:8314 +//line sql.y:8318 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[5].identifierCI) } - case 1684: + case 1686: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *RowAlias -//line sql.y:8319 +//line sql.y:8323 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1685: + case 1687: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *RowAlias -//line sql.y:8323 +//line sql.y:8327 { yyLOCAL = &RowAlias{TableName: yyDollar[2].identifierCS} } yyVAL.union = yyLOCAL - case 1686: + case 1688: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *RowAlias -//line sql.y:8327 +//line sql.y:8331 { yyLOCAL = &RowAlias{TableName: yyDollar[2].identifierCS, Columns: yyDollar[4].columnsUnion()} } yyVAL.union = yyLOCAL - case 1687: + case 1689: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:8332 +//line sql.y:8336 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1688: + case 1690: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:8336 +//line sql.y:8340 { yyLOCAL = yyDollar[5].updateExprsUnion() } yyVAL.union = yyLOCAL - case 1689: + case 1691: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Values -//line sql.y:8342 +//line sql.y:8346 { yyLOCAL = Values{yyDollar[1].valTupleUnion()} } yyVAL.union = yyLOCAL - case 1690: + case 1692: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:8346 +//line sql.y:8350 { yySLICE := (*Values)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].valTupleUnion()) } - case 1691: + case 1693: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Values -//line sql.y:8352 +//line sql.y:8356 { yyLOCAL = Values{yyDollar[1].valTupleUnion()} } yyVAL.union = yyLOCAL - case 1692: + case 1694: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:8356 +//line sql.y:8360 { yySLICE := (*Values)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].valTupleUnion()) } - case 1693: + case 1695: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ValTuple -//line sql.y:8362 +//line sql.y:8366 { yyLOCAL = yyDollar[1].valTupleUnion() } yyVAL.union = yyLOCAL - case 1694: + case 1696: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ValTuple -//line sql.y:8366 +//line sql.y:8370 { yyLOCAL = ValTuple{} } yyVAL.union = yyLOCAL - case 1695: + case 1697: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ValTuple -//line sql.y:8372 +//line sql.y:8376 { yyLOCAL = yyDollar[1].valTupleUnion() } yyVAL.union = yyLOCAL - case 1696: + case 1698: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL ValTuple -//line sql.y:8376 +//line sql.y:8380 { yyLOCAL = ValTuple{} } yyVAL.union = yyLOCAL - case 1697: + case 1699: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ValTuple -//line sql.y:8382 +//line sql.y:8386 { yyLOCAL = ValTuple(yyDollar[2].exprsUnion()) } yyVAL.union = yyLOCAL - case 1698: + case 1700: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL ValTuple -//line sql.y:8388 +//line sql.y:8392 { yyLOCAL = ValTuple(yyDollar[3].exprsUnion()) } yyVAL.union = yyLOCAL - case 1701: + case 1703: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:8398 +//line sql.y:8402 { if len(yyDollar[1].valTupleUnion()) == 1 { yyLOCAL = yyDollar[1].valTupleUnion()[0] @@ -23848,300 +23992,300 @@ yydefault: } } yyVAL.union = yyLOCAL - case 1702: + case 1704: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:8408 +//line sql.y:8412 { yyLOCAL = UpdateExprs{yyDollar[1].updateExprUnion()} } yyVAL.union = yyLOCAL - case 1703: + case 1705: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:8412 +//line sql.y:8416 { yySLICE := (*UpdateExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].updateExprUnion()) } - case 1704: + case 1706: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *UpdateExpr -//line sql.y:8418 +//line sql.y:8422 { yyLOCAL = &UpdateExpr{Name: yyDollar[1].colNameUnion(), Expr: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 1706: + case 1708: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:8425 +//line sql.y:8429 { yyVAL.str = "charset" } - case 1709: + case 1711: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:8435 +//line sql.y:8439 { yyLOCAL = NewStrLiteral(yyDollar[1].identifierCI.String()) } yyVAL.union = yyLOCAL - case 1710: + case 1712: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:8439 +//line sql.y:8443 { yyLOCAL = NewStrLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 1711: + case 1713: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:8443 +//line sql.y:8447 { yyLOCAL = &Default{} } yyVAL.union = yyLOCAL - case 1714: + case 1716: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:8452 +//line sql.y:8456 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1715: + case 1717: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:8454 +//line sql.y:8458 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1716: + case 1718: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:8457 +//line sql.y:8461 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1717: + case 1719: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:8459 +//line sql.y:8463 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1718: + case 1720: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:8462 +//line sql.y:8466 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1719: + case 1721: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL bool -//line sql.y:8464 +//line sql.y:8468 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1720: + case 1722: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Ignore -//line sql.y:8467 +//line sql.y:8471 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 1721: + case 1723: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Ignore -//line sql.y:8469 +//line sql.y:8473 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 1722: + case 1724: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8472 +//line sql.y:8476 { yyVAL.empty = struct{}{} } - case 1723: + case 1725: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8474 +//line sql.y:8478 { yyVAL.empty = struct{}{} } - case 1724: + case 1726: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8476 +//line sql.y:8480 { yyVAL.empty = struct{}{} } - case 1725: + case 1727: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:8480 +//line sql.y:8484 { yyLOCAL = &CallProc{Name: yyDollar[2].tableName, Params: yyDollar[4].exprsUnion()} } yyVAL.union = yyLOCAL - case 1726: + case 1728: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []Expr -//line sql.y:8485 +//line sql.y:8489 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1727: + case 1729: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []Expr -//line sql.y:8489 +//line sql.y:8493 { yyLOCAL = yyDollar[1].exprsUnion() } yyVAL.union = yyLOCAL - case 1728: + case 1730: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:8494 +//line sql.y:8498 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 1729: + case 1731: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:8496 +//line sql.y:8500 { yyLOCAL = []*IndexOption{yyDollar[1].indexOptionUnion()} } yyVAL.union = yyLOCAL - case 1730: + case 1732: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:8500 +//line sql.y:8504 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str), String: string(yyDollar[2].identifierCI.String())} } yyVAL.union = yyLOCAL - case 1731: + case 1733: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8506 +//line sql.y:8510 { yyVAL.identifierCI = yyDollar[1].identifierCI } - case 1732: + case 1734: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8510 +//line sql.y:8514 { yyVAL.identifierCI = NewIdentifierCI(string(yyDollar[1].str)) } - case 1734: + case 1736: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8517 +//line sql.y:8521 { yyVAL.identifierCI = NewIdentifierCI(string(yyDollar[1].str)) } - case 1735: + case 1737: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8523 +//line sql.y:8527 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 1736: + case 1738: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8527 +//line sql.y:8531 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 1737: + case 1739: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:8533 +//line sql.y:8537 { yyVAL.identifierCS = NewIdentifierCS("") } - case 1738: + case 1740: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8537 +//line sql.y:8541 { yyVAL.identifierCS = yyDollar[1].identifierCS } - case 1740: + case 1742: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:8544 +//line sql.y:8548 { yyVAL.identifierCS = NewIdentifierCS(string(yyDollar[1].str)) } - case 1741: + case 1743: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:8550 +//line sql.y:8554 { yyLOCAL = &Kill{Type: yyDollar[2].killTypeUnion(), ProcesslistID: convertStringToUInt64(yyDollar[3].str)} } yyVAL.union = yyLOCAL - case 1742: + case 1744: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL KillType -//line sql.y:8556 +//line sql.y:8560 { yyLOCAL = ConnectionType } yyVAL.union = yyLOCAL - case 1743: + case 1745: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL KillType -//line sql.y:8560 +//line sql.y:8564 { yyLOCAL = ConnectionType } yyVAL.union = yyLOCAL - case 1744: + case 1746: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL KillType -//line sql.y:8564 +//line sql.y:8568 { yyLOCAL = QueryType } yyVAL.union = yyLOCAL - case 2411: + case 2413: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:9259 +//line sql.y:9263 { } - case 2412: + case 2414: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:9264 +//line sql.y:9268 { } - case 2413: + case 2415: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:9268 +//line sql.y:9272 { skipToEnd(yylex) } - case 2414: + case 2416: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:9273 +//line sql.y:9277 { skipToEnd(yylex) } - case 2415: + case 2417: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:9277 +//line sql.y:9281 { skipToEnd(yylex) } - case 2416: + case 2418: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:9281 +//line sql.y:9285 { skipToEnd(yylex) } diff --git a/go/vt/sqlparser/sql.y b/go/vt/sqlparser/sql.y index b16c82152da..b1341042e68 100644 --- a/go/vt/sqlparser/sql.y +++ b/go/vt/sqlparser/sql.y @@ -1235,13 +1235,21 @@ values_statement: } stream_statement: - STREAM comment_opt select_expression FROM table_name + STREAM comment_opt '*' FROM table_name + { + $$ = &Stream{Comments: Comments($2).Parsed(), SelectExpr: &StarExpr{}, Table: $5} + } +| STREAM comment_opt select_expression FROM table_name { $$ = &Stream{Comments: Comments($2).Parsed(), SelectExpr: $3, Table: $5} } vstream_statement: - VSTREAM comment_opt select_expression FROM table_name where_expression_opt limit_opt + VSTREAM comment_opt '*' FROM table_name where_expression_opt limit_opt + { + $$ = &VStream{Comments: Comments($2).Parsed(), SelectExpr: &StarExpr{}, Table: $5, Where: NewWhere(WhereClause, $6), Limit: $7} + } +| VSTREAM comment_opt select_expression FROM table_name where_expression_opt limit_opt { $$ = &VStream{Comments: Comments($2).Parsed(), SelectExpr: $3, Table: $5, Where: NewWhere(WhereClause, $6), Limit: $7} } @@ -5288,27 +5296,23 @@ select_option: } select_expression_list: - select_expression + '*' + { + $$ = &SelectExprs{Exprs: []SelectExpr{&StarExpr{}}} + } +| select_expression { $$ = &SelectExprs{Exprs: []SelectExpr{$1}} } | select_expression_list ',' select_expression { - if starExpr, ok := $3.(*StarExpr); ok && starExpr.TableName.IsEmpty() { - yylex.Error("syntax error: unexpected '*'") - return 1 - } res := $1 res.Exprs = append(res.Exprs, $3) $$ = res } select_expression: - '*' - { - $$ = &StarExpr{} - } -| expression as_ci_opt + expression as_ci_opt { $$ = &AliasedExpr{Expr: $1, As: $2} } diff --git a/go/vt/vtgate/planbuilder/testdata/dml_cases.json b/go/vt/vtgate/planbuilder/testdata/dml_cases.json index d6d4b563cfe..b8633ecc9ba 100644 --- a/go/vt/vtgate/planbuilder/testdata/dml_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/dml_cases.json @@ -4038,7 +4038,7 @@ { "comment": "insert using select with more columns in select after accounting for star column", "query": "insert into music(id, user_id) select id, *, 2 from user", - "plan": "syntax error: unexpected '*' at position 44", + "plan": "syntax error at position 44", "skip_e2e": true }, { diff --git a/go/vt/vtgate/planbuilder/testdata/unknown_schema_cases.json b/go/vt/vtgate/planbuilder/testdata/unknown_schema_cases.json index 8647220afd8..b3e0e78c3ef 100644 --- a/go/vt/vtgate/planbuilder/testdata/unknown_schema_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/unknown_schema_cases.json @@ -47,7 +47,7 @@ { "comment": "ORDER BY on select multi *", "query": "select *, name, *, col from user order by col", - "plan": "syntax error: unexpected '*' at position 18" + "plan": "syntax error at position 18" }, { "comment": "Group by column number, used with non-aliased expression (duplicated code)", diff --git a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go index 320d7311f76..cdee6483ecc 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go @@ -640,7 +640,7 @@ func TestBuildPlayerPlan(t *testing.T) { Filter: "select c1, * from t1", }}, }, - err: "failed to build table replication plan for t1 table: syntax error: unexpected '*' at position 13 in query: select c1, * from t1", + err: "failed to build table replication plan for t1 table: syntax error at position 13 in query: select c1, * from t1", }, { // no distinct in func input: &binlogdatapb.Filter{ diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go index dd260567e7a..a9de7f05725 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go @@ -730,7 +730,7 @@ func TestPlanBuilder(t *testing.T) { // analyzeExpr tests. inTable: t1, inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select id, * from t1"}, - outErr: `syntax error: unexpected '*' at position 13`, + outErr: `syntax error at position 13`, }, { inTable: t1, inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select none from t1"}, From dd182a103034327db3a80bddd08d229ae1ea762f Mon Sep 17 00:00:00 2001 From: Arthur Schreiber Date: Tue, 31 Mar 2026 15:26:43 +0200 Subject: [PATCH 104/112] [release-22.0] Support Go 1.26 and later with Swiss maps always enabled (#19088) (#19765) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Štefan Baebler <319826+stefanb@users.noreply.github.com> Co-authored-by: Štefan Baebler <319826+stefanb@users.noreply.github.com> --- go/hack/ensure_swiss_map.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/go/hack/ensure_swiss_map.go b/go/hack/ensure_swiss_map.go index b09bde1121c..f57d1fb3e1a 100644 --- a/go/hack/ensure_swiss_map.go +++ b/go/hack/ensure_swiss_map.go @@ -1,4 +1,4 @@ -//go:build !goexperiment.swissmap +//go:build !goexperiment.swissmap && !go1.26 /* Copyright (c) 2009 The Go Authors. All rights reserved. @@ -32,7 +32,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // This is invalid Go code, and it will fail to compile if you disable // Swiss maps when building Vitess. Our runtime memory accounting system -// expects the map implementation in Go 1.24 to be Swiss. +// expects the map implementation in Go 1.24 and 1.25 to be Swiss. +// In Go 1.26 and later, Swiss maps are always enabled. package hack From 9c4103923fc1026718e25f123ba98d57aa4aec99 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Thu, 2 Apr 2026 14:04:11 +0200 Subject: [PATCH 105/112] [release-22.0] docker: use shared buildkit cache scope for bootstrap images (#19770) (#19778) Signed-off-by: Tim Vaillancourt Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/actions/build-bootstrap/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/build-bootstrap/action.yml b/.github/actions/build-bootstrap/action.yml index 365a379afd6..826063ff570 100644 --- a/.github/actions/build-bootstrap/action.yml +++ b/.github/actions/build-bootstrap/action.yml @@ -23,8 +23,8 @@ runs: files: docker/bootstrap/docker-bake.hcl load: true set: | - *.cache-from=type=gha - *.cache-to=type=gha,mode=max + *.cache-from=type=gha,scope=bootstrap + *.cache-to=type=gha,scope=bootstrap,mode=max env: BOOTSTRAP_VERSION: ${{ inputs.bootstrap-version }} BOOTSTRAP_FLAVOR: ${{ inputs.bootstrap-flavor }} From 5233eea17f6055eb12599e0e358375e93378a587 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Fri, 3 Apr 2026 14:00:24 -0700 Subject: [PATCH 106/112] [release-22.0] vttablet: handle applier metadata init failures in relay-log recovery (#19560) (#19788) Signed-off-by: Mohamed Hamza Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Mohamed Hamza --- go/mysql/sqlerror/constants.go | 13 +- go/mysql/sqlerror/sql_error.go | 22 +- go/mysql/sqlerror/sql_error_test.go | 12 +- go/vt/mysqlctl/fakemysqldaemon.go | 7 + go/vt/vttablet/tabletmanager/restore.go | 2 +- .../vttablet/tabletmanager/rpc_replication.go | 138 +++++-- .../tabletmanager/rpc_replication_test.go | 376 ++++++++++++++++++ go/vt/vttablet/tabletmanager/tm_init.go | 4 +- go/vt/vttablet/tabletmanager/tm_init_test.go | 99 ++++- .../testlib/planned_reparent_shard_test.go | 331 ++++++++------- go/vt/wrangler/testlib/reparent_utils_test.go | 87 ++-- 11 files changed, 868 insertions(+), 223 deletions(-) diff --git a/go/mysql/sqlerror/constants.go b/go/mysql/sqlerror/constants.go index 9ac29ef7d9f..8f725f02585 100644 --- a/go/mysql/sqlerror/constants.go +++ b/go/mysql/sqlerror/constants.go @@ -104,6 +104,7 @@ const ( ERDupUnique = ErrorCode(1169) ERRequiresPrimaryKey = ErrorCode(1173) ERCantDoThisDuringAnTransaction = ErrorCode(1179) + ERMasterInfo = ErrorCode(1201) ERReadOnlyTransaction = ErrorCode(1207) ERCannotAddForeign = ErrorCode(1215) ERNoReferencedRow = ErrorCode(1216) @@ -126,7 +127,17 @@ const ( ErNoReferencedRow2 = ErrorCode(1452) ERInnodbIndexCorrupt = ErrorCode(1817) ERDupIndex = ErrorCode(1831) - ERInnodbReadOnly = ErrorCode(1874) + + // MySQL used 1871/1872 for master-info and relay-log-info initialization + // errors through 8.0.32, and reassigned those numbers in 8.0.33 to + // connection-metadata and applier-metadata initialization errors. These + // errnos therefore map to different metadata types depending on version. + ERReplicaMasterInfoInitRepository = ErrorCode(1871) + ERReplicaRelayLogInfoInitRepository = ErrorCode(1872) + ERReplicaConnectionMetadataInitRepository = ErrorCode(1871) + ERReplicaApplierMetadataInitRepository = ErrorCode(1872) + + ERInnodbReadOnly = ErrorCode(1874) ERVectorConversion = ErrorCode(6138) diff --git a/go/mysql/sqlerror/sql_error.go b/go/mysql/sqlerror/sql_error.go index 4600f0927cc..b7a7c6dc6c0 100644 --- a/go/mysql/sqlerror/sql_error.go +++ b/go/mysql/sqlerror/sql_error.go @@ -93,10 +93,23 @@ func (se *SQLError) SQLState() string { return se.State } -var errExtract = regexp.MustCompile(`\(errno ([0-9]*)\) \(sqlstate ([0-9a-zA-Z]{5})\)`) +var ( + // errExtract matches Vitess-wrapped SQL errors ending with `(errno ) (sqlstate )`. + errExtract = regexp.MustCompile(`\(errno ([0-9]*)\) \(sqlstate ([0-9a-zA-Z]{5})\)`) + + // nativeErrExtract matches native MySQL server errors using `ERROR (): `. + nativeErrExtract = regexp.MustCompile(`ERROR ([0-9]*) \(([0-9a-zA-Z]{5})\):`) +) // NewSQLErrorFromError returns a *SQLError from the provided error. -// If it's not the right type, it still tries to get it from a regexp. +// +// - If err already is a *SQLError, it returns err unchanged. +// - If err is a Vitess error with a mapped MySQL code, it returns the converted SQLError. +// - If err contains a Vitess-wrapped `(errno ) (sqlstate )` suffix, it extracts that code and state. +// - If err contains a native MySQL `ERROR (): ` string, it extracts that code and state. +// - Otherwise, it maps the Vitess error code to a MySQL error code when one is defined and returns +// a generic SQLError with that code and err.Error() as the message. +// // Notes about the `error` return type: // The function really returns *SQLError or `nil`. Seemingly, the function could just return // `*SQLError` type. However, it really must return `error`. The reason is the way `golang` @@ -128,6 +141,11 @@ func NewSQLErrorFromError(err error) error { return extractSQLErrorFromMessage(match, msg) } + match = nativeErrExtract.FindStringSubmatch(msg) + if len(match) >= 2 { + return extractSQLErrorFromMessage(match, msg) + } + return mapToSQLErrorFromErrorCode(err, msg) } diff --git a/go/mysql/sqlerror/sql_error_test.go b/go/mysql/sqlerror/sql_error_test.go index 9e73138d60f..9c05cdd2190 100644 --- a/go/mysql/sqlerror/sql_error_test.go +++ b/go/mysql/sqlerror/sql_error_test.go @@ -54,7 +54,7 @@ func TestDemuxResourceExhaustedErrors(t *testing.T) { } func TestNewSQLErrorFromError(t *testing.T) { - var tCases = []struct { + tCases := []struct { err error num ErrorCode ha HandlerErrorCode @@ -155,6 +155,16 @@ func TestNewSQLErrorFromError(t *testing.T) { num: ERNoDb, ss: SSNoDB, }, + { + err: fmt.Errorf("ERROR 1201 (HY000): Could not initialize master info structure; more error messages can be found in the MySQL error log"), + num: ERMasterInfo, + ss: SSUnknownSQLState, + }, + { + err: fmt.Errorf("ERROR 1872 (HY000): Replica failed to initialize applier metadata structure from the repository"), + num: ERReplicaApplierMetadataInitRepository, + ss: SSUnknownSQLState, + }, { err: fmt.Errorf("just some random text here"), num: ERUnknownError, diff --git a/go/vt/mysqlctl/fakemysqldaemon.go b/go/vt/mysqlctl/fakemysqldaemon.go index 73d8a87dbf5..eccf6011278 100644 --- a/go/vt/mysqlctl/fakemysqldaemon.go +++ b/go/vt/mysqlctl/fakemysqldaemon.go @@ -137,6 +137,9 @@ type FakeMysqlDaemon struct { // SetReplicationSourceError is used by SetReplicationSource. SetReplicationSourceError error + // SetReplicationSourceFunc overrides SetReplicationSource when it is set. + SetReplicationSourceFunc func(ctx context.Context, host string, port int32, heartbeatInterval float64, stopReplicationBefore bool, startReplicationAfter bool) error + // StopReplicationError error is used by StopReplication. StopReplicationError error @@ -515,6 +518,10 @@ func (fmd *FakeMysqlDaemon) SetReplicationPosition(ctx context.Context, pos repl // SetReplicationSource is part of the MysqlDaemon interface. func (fmd *FakeMysqlDaemon) SetReplicationSource(ctx context.Context, host string, port int32, heartbeatInterval float64, stopReplicationBefore bool, startReplicationAfter bool) error { + if fmd.SetReplicationSourceFunc != nil { + return fmd.SetReplicationSourceFunc(ctx, host, port, heartbeatInterval, stopReplicationBefore, startReplicationAfter) + } + input := fmt.Sprintf("%v:%v", host, port) found := false for _, sourceInput := range fmd.SetReplicationSourceInputs { diff --git a/go/vt/vttablet/tabletmanager/restore.go b/go/vt/vttablet/tabletmanager/restore.go index 54813e11bf3..05c29d19d0a 100644 --- a/go/vt/vttablet/tabletmanager/restore.go +++ b/go/vt/vttablet/tabletmanager/restore.go @@ -333,7 +333,7 @@ func (tm *TabletManager) disableReplication(ctx context.Context) error { return vterrors.Wrap(err, "failed to reset replication") } - if err := tm.MysqlDaemon.SetReplicationSource(ctx, "//", 0, 0, false, true); err != nil { + if err := tm.setReplicationSourceRecoverable(ctx, "//", 0, 0, false, true); err != nil { return vterrors.Wrap(err, "failed to disable replication") } diff --git a/go/vt/vttablet/tabletmanager/rpc_replication.go b/go/vt/vttablet/tabletmanager/rpc_replication.go index 0dbd785aa1a..1303d3f40c7 100644 --- a/go/vt/vttablet/tabletmanager/rpc_replication.go +++ b/go/vt/vttablet/tabletmanager/rpc_replication.go @@ -20,7 +20,6 @@ import ( "context" "fmt" "runtime" - "strings" "time" "vitess.io/vitess/go/mysql" @@ -306,7 +305,7 @@ func (tm *TabletManager) StartReplication(ctx context.Context, semiSync bool) er if err := tm.fixSemiSync(ctx, tm.Tablet().Type, semiSyncAction); err != nil { return err } - return tm.MysqlDaemon.StartReplication(ctx, tm.hookExtraEnv()) + return tm.startReplicationRecoverable(ctx) } // StartReplicationUntilAfter will start the replication and let it catch up @@ -496,7 +495,8 @@ func (tm *TabletManager) InitReplica(ctx context.Context, parent *topodatapb.Tab if err := tm.MysqlDaemon.SetReplicationPosition(ctx, pos); err != nil { return err } - if err := tm.MysqlDaemon.SetReplicationSource(ctx, ti.Tablet.MysqlHostname, ti.Tablet.MysqlPort, 0, false, true); err != nil { + + if err := tm.setReplicationSourceRecoverable(ctx, ti.Tablet.MysqlHostname, ti.Tablet.MysqlPort, 0, false, true); err != nil { return err } @@ -921,23 +921,19 @@ func (tm *TabletManager) setReplicationSourceLocked(ctx context.Context, parentA } if status.SourceHost != host || status.SourcePort != port || heartbeatInterval != 0 { // This handles both changing the address and starting replication. - if err := tm.MysqlDaemon.SetReplicationSource(ctx, host, port, heartbeatInterval, wasReplicating, shouldbeReplicating); err != nil { - if err := tm.handleRelayLogError(ctx, err); err != nil { - return err - } + if err := tm.setReplicationSourceRecoverable(ctx, host, port, heartbeatInterval, wasReplicating, shouldbeReplicating); err != nil { + return err } } else if shouldbeReplicating { // The address is correct. We need to restart replication so that any semi-sync changes if any - // are taken into account + // are taken into account. We don't attempt to recover from the known recoverable errors here + // because recovery requires running `STOP REPLICA` in order to reset the replication metadata. + // If we error the first time, we're likely to error the second time as well. if err := tm.MysqlDaemon.StopReplication(ctx, tm.hookExtraEnv()); err != nil { - if err := tm.handleRelayLogError(ctx, err); err != nil { - return err - } + return err } - if err := tm.MysqlDaemon.StartReplication(ctx, tm.hookExtraEnv()); err != nil { - if err := tm.handleRelayLogError(ctx, err); err != nil { - return err - } + if err := tm.startReplicationRecoverable(ctx); err != nil { + return err } } @@ -1199,25 +1195,113 @@ func (tm *TabletManager) fixSemiSyncAndReplication(ctx context.Context, tabletTy if err := tm.MysqlDaemon.StopReplication(ctx, tm.hookExtraEnv()); err != nil { return vterrors.Wrap(err, "failed to StopReplication") } - if err := tm.MysqlDaemon.StartReplication(ctx, tm.hookExtraEnv()); err != nil { + if err := tm.startReplicationRecoverable(ctx); err != nil { return vterrors.Wrap(err, "failed to StartReplication") } return nil } -// handleRelayLogError resets replication of the instance. -// This is required because sometimes MySQL gets stuck due to improper initialization of -// master info structure or related failures and throws errors like -// ERROR 1201 (HY000): Could not initialize master info structure; more error messages can be found in the MySQL error log -// These errors can only be resolved by resetting the replication, otherwise START REPLICA fails. -func (tm *TabletManager) handleRelayLogError(ctx context.Context, err error) error { - // attempt to fix this error: - // Replica failed to initialize relay log info structure from the repository (errno 1872) (sqlstate HY000) during query: START REPLICA +// startReplicationRecoverable starts replication and handles recoverable errors by resetting replication. +func (tm *TabletManager) startReplicationRecoverable(ctx context.Context) error { + err := tm.MysqlDaemon.StartReplication(ctx, tm.hookExtraEnv()) + if err == nil { + return nil + } + + // Try to recover from the error. + if err := tm.handleRecoverableReplicationInitError(ctx, err); err != nil { + return err + } + + return nil +} + +// setReplicationSourceRecoverable configures the requested replication source and optionally starts +// replication afterward. When possible, certain errors are recovered by reinitializing replication +// metadata. +func (tm *TabletManager) setReplicationSourceRecoverable(ctx context.Context, host string, port int32, heartbeatInterval float64, wasReplicating bool, shouldStartReplication bool) error { + // Let's first try to apply the requested source without starting replication afterwards. If the + // replica was replicating before, we stop replication first. + err := tm.MysqlDaemon.SetReplicationSource(ctx, host, port, heartbeatInterval, wasReplicating, false) + if err == nil { + // We succeeded, let's start replication but only if it was requested. + if !shouldStartReplication { + return nil + } + + return tm.startReplicationRecoverable(ctx) + } + + // We hit an error. If the error is not one of the recoverable ones, we can't recover and should return it. + if !isRecoverableReplicationInitializationError(err) { + return err + } + + log.Warningf( + "Encountered recoverable replication initialization error while changing replication source, resetting "+ + "replication parameters and reapplying source: source_host=%s, source_port=%d, error=%v", + host, port, err, + ) + + // If the replica was running when the source-change attempt failed, stop it + // explicitly before resetting replication metadata. + if wasReplicating { + if err := tm.MysqlDaemon.StopReplication(ctx, tm.hookExtraEnv()); err != nil { + return err + } + } + + // Recover from the error by reinitializing replication metadata through + // `RESET REPLICA ALL`. + if err := tm.MysqlDaemon.ResetReplicationParameters(ctx); err != nil { + return err + } + + // Now that we've reinitialized the replication metadata, try setting the source again. + if err := tm.MysqlDaemon.SetReplicationSource(ctx, host, port, heartbeatInterval, false, false); err != nil { + return err + } + + // The replication source has finally been set. Let's also start replication if it was requested. + if shouldStartReplication { + return tm.startReplicationRecoverable(ctx) + } + + return nil +} + +// recoverableReplicationInitializationErrorCodes is the set of replication initialization error +// codes that can be recovered from by reinitializing replication metadata. +// MySQL used 1871/1872 for master-info and relay-log-info initialization errors +// through 8.0.32, and reassigned those numbers in 8.0.33 to connection-metadata +// and applier-metadata initialization errors. +var recoverableReplicationInitializationErrorCodes = map[sqlerror.ErrorCode]struct{}{ + sqlerror.ERMasterInfo: {}, + sqlerror.ERReplicaConnectionMetadataInitRepository: {}, + sqlerror.ERReplicaApplierMetadataInitRepository: {}, +} + +// isRecoverableReplicationInitializationError reports whether an error can be recovered from by +// reinitializing replication metadata. +func isRecoverableReplicationInitializationError(err error) bool { + sqlErr, ok := sqlerror.NewSQLErrorFromError(err).(*sqlerror.SQLError) + if !ok || sqlErr == nil { + return false + } + + _, ok = recoverableReplicationInitializationErrorCodes[sqlErr.Number()] + return ok +} + +// handleRecoverableReplicationInitError repairs recoverable replication initialization +// failures by restarting replication. +func (tm *TabletManager) handleRecoverableReplicationInitError(ctx context.Context, err error) error { + // Attempt to self-heal by restarting replication when initialization fails. // see https://bugs.mysql.com/bug.php?id=83713 or https://github.com/vitessio/vitess/issues/5067 // The same fix also works for https://github.com/vitessio/vitess/issues/10955. - if strings.Contains(err.Error(), "Replica failed to initialize relay log info structure from the repository") || - strings.Contains(err.Error(), "Could not initialize master info structure") { - // Stop, reset and start replication again to resolve this error + if isRecoverableReplicationInitializationError(err) { + log.Warningf("Encountered recoverable replication initialization error, restarting replication: %v", err) + if err := tm.MysqlDaemon.RestartReplication(ctx, tm.hookExtraEnv()); err != nil { return err } diff --git a/go/vt/vttablet/tabletmanager/rpc_replication_test.go b/go/vt/vttablet/tabletmanager/rpc_replication_test.go index 31da3abb732..1bbc5e74290 100644 --- a/go/vt/vttablet/tabletmanager/rpc_replication_test.go +++ b/go/vt/vttablet/tabletmanager/rpc_replication_test.go @@ -18,6 +18,8 @@ package tabletmanager import ( "context" + "errors" + "fmt" "sync/atomic" "testing" "time" @@ -25,6 +27,7 @@ import ( "github.com/stretchr/testify/require" "golang.org/x/sync/semaphore" + "vitess.io/vitess/go/mysql/sqlerror" "vitess.io/vitess/go/protoutil" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/mysqlctl" @@ -36,6 +39,28 @@ import ( topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) +func newTestReplicationTM(tablet *topodatapb.Tablet, mysqlDaemon *mysqlctl.FakeMysqlDaemon, ts *topo.Server) *TabletManager { + waitForGrantsComplete := make(chan struct{}) + close(waitForGrantsComplete) + + return &TabletManager{ + actionSema: semaphore.NewWeighted(1), + TopoServer: ts, + MysqlDaemon: mysqlDaemon, + tabletAlias: tablet.Alias, + _waitForGrantsComplete: waitForGrantsComplete, + tmState: &tmState{ + displayState: displayState{ + tablet: tablet, + }, + }, + } +} + +func recoverableReplicationInitError() error { + return sqlerror.NewSQLError(sqlerror.ERMasterInfo, sqlerror.SSUnknownSQLState, "Could not initialize master info structure; more error messages can be found in the MySQL error log") +} + // TestWaitForGrantsToHaveApplied tests that waitForGrantsToHaveApplied only succeeds after waitForDBAGrants has been called. func TestWaitForGrantsToHaveApplied(t *testing.T) { tm := &TabletManager{ @@ -326,3 +351,354 @@ func TestUndoDemotePrimaryStateChange(t *testing.T) { require.NoError(t, err) require.False(t, isReadOnly) } + +func TestHandleRecoverableReplicationInitializationError(t *testing.T) { + testCases := []struct { + name string + inputErr error + shouldRestart bool + }{ + { + name: "relay log info repository error", + inputErr: sqlerror.NewSQLError(sqlerror.ERReplicaRelayLogInfoInitRepository, sqlerror.SSUnknownSQLState, "Replica failed to initialize relay log info structure from the repository"), + shouldRestart: true, + }, + { + name: "master info error", + inputErr: sqlerror.NewSQLError(sqlerror.ERMasterInfo, sqlerror.SSUnknownSQLState, "Could not initialize master info structure; more error messages can be found in the MySQL error log"), + shouldRestart: true, + }, + { + name: "connection metadata repository error", + inputErr: sqlerror.NewSQLError(sqlerror.ERReplicaConnectionMetadataInitRepository, sqlerror.SSUnknownSQLState, "Replica failed to initialize connection metadata structure from the repository"), + shouldRestart: true, + }, + { + name: "applier metadata message with wrong errno", + inputErr: sqlerror.NewSQLError(sqlerror.ERUnknownError, sqlerror.SSUnknownSQLState, "Replica failed to initialize applier metadata structure from the repository"), + shouldRestart: false, + }, + { + name: "mysqlctl wrapped master info error", + inputErr: errors.New("ExecuteFetch(START REPLICA) failed: Could not initialize master info structure; more error messages can be found in the MySQL error log (errno 1201) (sqlstate HY000)"), + shouldRestart: true, + }, + { + name: "native mysql master info error", + inputErr: errors.New("ERROR 1201 (HY000): Could not initialize master info structure; more error messages can be found in the MySQL error log"), + shouldRestart: true, + }, + { + name: "unrelated error", + inputErr: errors.New("unexpected replication failure"), + shouldRestart: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + fakeMysqlDaemon := newTestMysqlDaemon(t, 1) + if tc.shouldRestart { + fakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "STOP REPLICA", + "RESET REPLICA", + "START REPLICA", + } + } + + tablet := newTestTablet(t, 100, "ks", "0", nil) + tm := &TabletManager{ + MysqlDaemon: fakeMysqlDaemon, + tabletAlias: tablet.Alias, + tmState: &tmState{ + displayState: displayState{ + tablet: tablet, + }, + }, + } + + err := tm.handleRecoverableReplicationInitError(t.Context(), tc.inputErr) + if tc.shouldRestart { + require.NoError(t, err) + } else { + require.ErrorIs(t, err, tc.inputErr) + } + + require.NoError(t, fakeMysqlDaemon.CheckSuperQueryList()) + }) + } +} + +// TestStartReplicationRecoversFromRecoverableReplicationInitError verifies StartReplication self-heals recoverable init failures. +func TestStartReplicationRecoversFromRecoverableReplicationInitError(t *testing.T) { + fakeMysqlDaemon := newTestMysqlDaemon(t, 1) + fakeMysqlDaemon.StartReplicationError = recoverableReplicationInitError() + fakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "STOP REPLICA", + "RESET REPLICA", + "START REPLICA", + } + + tm := newTestReplicationTM(newTestTablet(t, 100, "ks", "0", nil), fakeMysqlDaemon, nil) + err := tm.StartReplication(t.Context(), false) + require.NoError(t, err) + require.NoError(t, fakeMysqlDaemon.CheckSuperQueryList()) +} + +// TestFixSemiSyncAndReplicationRecoversFromRecoverableReplicationInitializationError verifies semi-sync restart path self-heals recoverable init failures. +func TestFixSemiSyncAndReplicationRecoversFromRecoverableReplicationInitializationError(t *testing.T) { + fakeMysqlDaemon := newTestMysqlDaemon(t, 1) + fakeMysqlDaemon.Replicating = true + fakeMysqlDaemon.StartReplicationError = recoverableReplicationInitError() + fakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "STOP REPLICA", + "STOP REPLICA", + "RESET REPLICA", + "START REPLICA", + } + + tm := newTestReplicationTM(newTestTablet(t, 100, "ks", "0", nil), fakeMysqlDaemon, nil) + err := tm.fixSemiSyncAndReplication(t.Context(), topodatapb.TabletType_REPLICA, SemiSyncActionUnset) + require.NoError(t, err) + require.NoError(t, fakeMysqlDaemon.CheckSuperQueryList()) +} + +func TestSetReplicationSourceRecovery(t *testing.T) { + t.Run("InitReplica recovers from start replication error", func(t *testing.T) { + ctx := t.Context() + ts := memorytopo.NewServer(ctx, "cell1") + + // Create a shard with a primary that InitReplica will point to. + _, err := ts.GetOrCreateShard(ctx, "ks", "0") + require.NoError(t, err) + + parent := &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 200, + }, + Keyspace: "ks", + Shard: "0", + Type: topodatapb.TabletType_PRIMARY, + MysqlHostname: "mysql-primary", + MysqlPort: 3306, + } + require.NoError(t, ts.CreateTablet(ctx, parent)) + + fakeMysqlDaemon := newTestMysqlDaemon(t, 1) + + // Let the source change succeed, then fail the explicit START REPLICA so + // the recovery path is exercised after the source is already configured. + fakeMysqlDaemon.SetReplicationSourceInputs = []string{"mysql-primary:3306"} + fakeMysqlDaemon.StartReplicationError = recoverableReplicationInitError() + fakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "FAKE RESET BINARY LOGS AND GTIDS", + "FAKE SET GLOBAL gtid_purged", + "FAKE SET SOURCE", + "STOP REPLICA", + "RESET REPLICA", + "START REPLICA", + } + + tm := newTestReplicationTM(newTestTablet(t, 100, "ks", "0", nil), fakeMysqlDaemon, ts) + + // InitReplica should recover the start failure and still complete. + err = tm.InitReplica(ctx, parent.Alias, "", 0, false) + require.NoError(t, err) + require.Equal(t, "mysql-primary", fakeMysqlDaemon.CurrentSourceHost) + require.EqualValues(t, 3306, fakeMysqlDaemon.CurrentSourcePort) + require.NoError(t, fakeMysqlDaemon.CheckSuperQueryList()) + }) + + t.Run("SetReplicationSource recovers on source change for running replica", func(t *testing.T) { + ctx := t.Context() + ts := memorytopo.NewServer(ctx, "cell1") + + tablet := newTestTablet(t, 100, "ks", "0", nil) + fakeMysqlDaemon := newTestMysqlDaemon(t, 1) + + // Start from a running replica that still points at the old primary. + fakeMysqlDaemon.Replicating = true + fakeMysqlDaemon.CurrentSourceHost = "mysql-old-primary" + fakeMysqlDaemon.CurrentSourcePort = 3305 + fakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "STOP REPLICA", + "STOP REPLICA", + "FAKE RESET REPLICA ALL", + "FAKE SET SOURCE", + "START REPLICA", + } + + setSourceCalls := 0 + + // Fail the first source-change attempt after the internal STOP REPLICA. + // The second attempt should succeed after recovery has cleared the broken + // metadata and reapplied the requested source. + fakeMysqlDaemon.SetReplicationSourceFunc = func(ctx context.Context, host string, port int32, heartbeatInterval float64, stopReplicationBefore bool, startReplicationAfter bool) error { + setSourceCalls++ + + require.Equal(t, "mysql-new-primary", host) + require.EqualValues(t, 3306, port) + require.Zero(t, heartbeatInterval) + require.False(t, startReplicationAfter) + + if setSourceCalls == 1 { + require.True(t, stopReplicationBefore) + require.NoError(t, fakeMysqlDaemon.ExecuteSuperQueryList(ctx, []string{"STOP REPLICA"})) + return recoverableReplicationInitError() + } + + if setSourceCalls == 2 { + require.False(t, stopReplicationBefore) + require.NoError(t, fakeMysqlDaemon.ExecuteSuperQueryList(ctx, []string{"FAKE SET SOURCE"})) + + fakeMysqlDaemon.CurrentSourceHost = host + fakeMysqlDaemon.CurrentSourcePort = port + + return nil + } + + return fmt.Errorf("unexpected SetReplicationSource call %d", setSourceCalls) + } + + tm := &TabletManager{ + actionSema: semaphore.NewWeighted(1), + BatchCtx: ctx, + TopoServer: ts, + MysqlDaemon: fakeMysqlDaemon, + tmc: newFakeTMClient(), + tabletAlias: tablet.Alias, + _waitForGrantsComplete: make(chan struct{}), + tmState: &tmState{ + displayState: displayState{ + tablet: tablet, + }, + }, + } + close(tm._waitForGrantsComplete) + + // Register both the replica and the new primary in topo. + _, err := ts.GetOrCreateShard(ctx, "ks", "0") + require.NoError(t, err) + require.NoError(t, ts.CreateTablet(ctx, tablet)) + + parent := &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 200, + }, + Keyspace: "ks", + Shard: "0", + Type: topodatapb.TabletType_PRIMARY, + MysqlHostname: "mysql-new-primary", + MysqlPort: 3306, + } + require.NoError(t, ts.CreateTablet(ctx, parent)) + + // SetReplicationSource should recover the source-change error, then + // leave the replica configured for the new primary. + err = tm.SetReplicationSource(ctx, parent.Alias, 0, "", false, false, 0) + require.NoError(t, err) + + require.Equal(t, 2, setSourceCalls) + require.Equal(t, "mysql-new-primary", fakeMysqlDaemon.CurrentSourceHost) + require.EqualValues(t, 3306, fakeMysqlDaemon.CurrentSourcePort) + require.NoError(t, fakeMysqlDaemon.CheckSuperQueryList()) + }) + + t.Run("non-running replica reapplies source after recoverable source error", func(t *testing.T) { + fakeMysqlDaemon := newTestMysqlDaemon(t, 1) + fakeMysqlDaemon.CurrentSourceHost = "mysql-old-primary" + fakeMysqlDaemon.CurrentSourcePort = 3305 + fakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "FAKE RESET REPLICA ALL", + "FAKE SET SOURCE", + } + + setSourceCalls := 0 + + // When replication was not running, recovery should clear any stale source + // settings and reapply the requested source without starting replication. + fakeMysqlDaemon.SetReplicationSourceFunc = func(ctx context.Context, host string, port int32, heartbeatInterval float64, stopReplicationBefore bool, startReplicationAfter bool) error { + setSourceCalls++ + + require.Equal(t, "mysql-new-primary", host) + require.EqualValues(t, 3306, port) + require.False(t, stopReplicationBefore) + require.False(t, startReplicationAfter) + + if setSourceCalls == 1 { + return recoverableReplicationInitError() + } + + if setSourceCalls == 2 { + require.NoError(t, fakeMysqlDaemon.ExecuteSuperQueryList(ctx, []string{"FAKE SET SOURCE"})) + + fakeMysqlDaemon.CurrentSourceHost = host + fakeMysqlDaemon.CurrentSourcePort = port + + return nil + } + + return fmt.Errorf("unexpected SetReplicationSource call %d", setSourceCalls) + } + + tm := newTestReplicationTM(newTestTablet(t, 100, "ks", "0", nil), fakeMysqlDaemon, nil) + + err := tm.setReplicationSourceRecoverable(t.Context(), "mysql-new-primary", 3306, 0, false, false) + require.NoError(t, err) + require.Equal(t, 2, setSourceCalls) + require.Equal(t, "mysql-new-primary", fakeMysqlDaemon.CurrentSourceHost) + require.EqualValues(t, 3306, fakeMysqlDaemon.CurrentSourcePort) + require.NoError(t, fakeMysqlDaemon.CheckSuperQueryList()) + }) + + t.Run("non-running replica with start requested reapplies source and starts replication", func(t *testing.T) { + fakeMysqlDaemon := newTestMysqlDaemon(t, 1) + fakeMysqlDaemon.CurrentSourceHost = "mysql-old-primary" + fakeMysqlDaemon.CurrentSourcePort = 3305 + fakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "FAKE RESET REPLICA ALL", + "FAKE SET SOURCE", + "START REPLICA", + } + + setSourceCalls := 0 + + // A source-change failure can happen before the new source is applied. + // Recovery should clear the old source settings, reapply the requested + // source, and only then start replication. + fakeMysqlDaemon.SetReplicationSourceFunc = func(ctx context.Context, host string, port int32, heartbeatInterval float64, stopReplicationBefore bool, startReplicationAfter bool) error { + setSourceCalls++ + + require.Equal(t, "mysql-new-primary", host) + require.EqualValues(t, 3306, port) + require.False(t, stopReplicationBefore) + require.False(t, startReplicationAfter) + + if setSourceCalls == 1 { + return recoverableReplicationInitError() + } + + if setSourceCalls == 2 { + require.NoError(t, fakeMysqlDaemon.ExecuteSuperQueryList(ctx, []string{"FAKE SET SOURCE"})) + + fakeMysqlDaemon.CurrentSourceHost = host + fakeMysqlDaemon.CurrentSourcePort = port + + return nil + } + + return fmt.Errorf("unexpected SetReplicationSource call %d", setSourceCalls) + } + + tm := newTestReplicationTM(newTestTablet(t, 100, "ks", "0", nil), fakeMysqlDaemon, nil) + + err := tm.setReplicationSourceRecoverable(t.Context(), "mysql-new-primary", 3306, 0, false, true) + require.NoError(t, err) + require.Equal(t, 2, setSourceCalls) + require.Equal(t, "mysql-new-primary", fakeMysqlDaemon.CurrentSourceHost) + require.EqualValues(t, 3306, fakeMysqlDaemon.CurrentSourcePort) + require.NoError(t, fakeMysqlDaemon.CheckSuperQueryList()) + }) +} diff --git a/go/vt/vttablet/tabletmanager/tm_init.go b/go/vt/vttablet/tabletmanager/tm_init.go index 92fd5ffb19d..8aafb7366ab 100644 --- a/go/vt/vttablet/tabletmanager/tm_init.go +++ b/go/vt/vttablet/tabletmanager/tm_init.go @@ -1067,8 +1067,8 @@ func (tm *TabletManager) initializeReplication(ctx context.Context, tabletType t return "", vterrors.New(vtrpc.Code_FAILED_PRECONDITION, fmt.Sprintf("Errant GTID detected - %s; Primary GTID - %s, Replica GTID - %s", errantGtid, primaryPosition, replicaPos.String())) } - if err := tm.MysqlDaemon.SetReplicationSource(ctx, currentPrimary.Tablet.MysqlHostname, currentPrimary.Tablet.MysqlPort, 0, true, true); err != nil { - return "", vterrors.Wrap(err, "MysqlDaemon.SetReplicationSource failed") + if err := tm.setReplicationSourceRecoverable(ctx, currentPrimary.Tablet.MysqlHostname, currentPrimary.Tablet.MysqlPort, 0, true, true); err != nil { + return "", vterrors.Wrap(err, "failed to configure replication source") } return primaryStatus.Position, nil diff --git a/go/vt/vttablet/tabletmanager/tm_init_test.go b/go/vt/vttablet/tabletmanager/tm_init_test.go index a6c5d33c975..2245b78fd35 100644 --- a/go/vt/vttablet/tabletmanager/tm_init_test.go +++ b/go/vt/vttablet/tabletmanager/tm_init_test.go @@ -24,10 +24,12 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "golang.org/x/sync/semaphore" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/mysql/collations" "vitess.io/vitess/go/mysql/fakesqldb" + "vitess.io/vitess/go/mysql/replication" "vitess.io/vitess/go/protoutil" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/test/utils" @@ -39,6 +41,8 @@ import ( "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/memorytopo" "vitess.io/vitess/go/vt/topotools" + "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" + "vitess.io/vitess/go/vt/vtctl/reparentutil/reparenttestutil" "vitess.io/vitess/go/vt/vttablet/tabletmanager/semisyncmonitor" "vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv" "vitess.io/vitess/go/vt/vttablet/tabletservermock" @@ -684,9 +688,7 @@ func newTestMysqlDaemon(t *testing.T, port int32) *mysqlctl.FakeMysqlDaemon { return mysqld } -var ( - exporter = servenv.NewExporter("TestTabletManager", "") -) +var exporter = servenv.NewExporter("TestTabletManager", "") func newTestTM(t *testing.T, ts *topo.Server, uid int, keyspace, shard string, tags map[string]string) *TabletManager { // reset stats @@ -824,7 +826,8 @@ func TestWaitForDBAGrants(t *testing.T) { cluster.TearDown() } }, - }, { + }, + { name: "Failure due to timeout", waitTime: 300 * time.Millisecond, errWanted: "timed out after 300ms waiting for the dba user to have the required permissions", @@ -845,7 +848,8 @@ func TestWaitForDBAGrants(t *testing.T) { cluster.TearDown() } }, - }, { + }, + { name: "Success for externally managed tablet", waitTime: 300 * time.Millisecond, errWanted: "", @@ -868,7 +872,8 @@ func TestWaitForDBAGrants(t *testing.T) { cluster.TearDown() } }, - }, { + }, + { name: "Empty timeout", waitTime: 0, errWanted: "", @@ -878,7 +883,8 @@ func TestWaitForDBAGrants(t *testing.T) { } return tc, func() {} }, - }, { + }, + { name: "Empty config", waitTime: 300 * time.Millisecond, errWanted: "", @@ -961,3 +967,82 @@ func grantAllPrivilegesToUser(t *testing.T, connParams mysql.ConnParams, testUse require.NoError(t, err) conn.Close() } + +// TestInitReplicationRecovery verifies replica startup initialization self-heals recoverable +// init failures returned from SetReplicationSource. +func TestInitReplicationRecovery(t *testing.T) { + ctx := t.Context() + ts := memorytopo.NewServer(ctx, "cell1") + tablet := newTestTablet(t, 1, "ks", "0", nil) + fakeMysqlDaemon := newTestMysqlDaemon(t, 1) + + tm := &TabletManager{ + actionSema: semaphore.NewWeighted(1), + BatchCtx: ctx, + TopoServer: ts, + MysqlDaemon: fakeMysqlDaemon, + tmc: newFakeTMClient(), + tabletAlias: tablet.Alias, + _waitForGrantsComplete: make(chan struct{}), + tmState: &tmState{ + displayState: displayState{ + tablet: tablet, + }, + }, + } + close(tm._waitForGrantsComplete) + + _, err := ts.GetOrCreateShard(ctx, "ks", "0") + require.NoError(t, err) + require.NoError(t, ts.CreateTablet(ctx, tablet)) + + reparenttestutil.SetKeyspaceDurability(ctx, t, ts, "ks", policy.DurabilityNone) + + primary := &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "cell1", + Uid: 2, + }, + Hostname: "primary-host", + PortMap: map[string]int32{ + "vt": 1234, + "grpc": 3456, + }, + Keyspace: "ks", + Shard: "0", + Type: topodatapb.TabletType_PRIMARY, + MysqlHostname: "mysql-primary", + MysqlPort: 3306, + } + require.NoError(t, ts.CreateTablet(ctx, primary)) + _, err = ts.UpdateShardFields(ctx, "ks", "0", func(si *topo.ShardInfo) error { + si.PrimaryAlias = primary.Alias + return nil + }) + require.NoError(t, err) + + pos, err := replication.ParsePosition(gtidFlavor, gtidPosition) + require.NoError(t, err) + + // Make StartReplication return a recoverable init error and expect the + // startup path to self-heal by restarting replication. SetReplicationSource + // is called with startReplicationAfter=false so recovery only applies to + // the separate StartReplication call. + fakeMysqlDaemon.SetPrimaryPositionLocked(pos) + fakeMysqlDaemon.SetReplicationSourceInputs = []string{"mysql-primary:3306"} + fakeMysqlDaemon.StartReplicationError = recoverableReplicationInitError() + fakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "STOP REPLICA", + "FAKE SET SOURCE", + "STOP REPLICA", + "RESET REPLICA", + "START REPLICA", + } + + // initializeReplication should now succeed and return the primary position + // after self-healing the recoverable error. + gotPosition, err := tm.initializeReplication(ctx, topodatapb.TabletType_REPLICA) + require.NoError(t, err) + require.Equal(t, fmt.Sprintf("%s/%s", gtidFlavor, gtidPosition), gotPosition) + require.NoError(t, fakeMysqlDaemon.CheckSuperQueryList()) +} diff --git a/go/vt/wrangler/testlib/planned_reparent_shard_test.go b/go/vt/wrangler/testlib/planned_reparent_shard_test.go index f160ddfa32b..585078b1a34 100644 --- a/go/vt/wrangler/testlib/planned_reparent_shard_test.go +++ b/go/vt/wrangler/testlib/planned_reparent_shard_test.go @@ -23,6 +23,7 @@ import ( "time" "vitess.io/vitess/go/mysql/replication" + "vitess.io/vitess/go/mysql/sqlerror" "vitess.io/vitess/go/vt/mysqlctl" "vitess.io/vitess/go/vt/vtctl/reparentutil/policy" "vitess.io/vitess/go/vt/vtenv" @@ -263,8 +264,10 @@ func TestPlannedReparentShardNoError(t *testing.T) { defer goodReplica2.StopActionLoop(t) // run PlannedReparentShard - err := vp.Run([]string{"PlannedReparentShard", "--wait_replicas_timeout", "10s", "--keyspace_shard", newPrimary.Tablet.Keyspace + "/" + newPrimary.Tablet.Shard, "--new_primary", - topoproto.TabletAliasString(newPrimary.Tablet.Alias)}) + err := vp.Run([]string{ + "PlannedReparentShard", "--wait_replicas_timeout", "10s", "--keyspace_shard", newPrimary.Tablet.Keyspace + "/" + newPrimary.Tablet.Shard, "--new_primary", + topoproto.TabletAliasString(newPrimary.Tablet.Alias), + }) require.NoError(t, err) // check what was run @@ -596,79 +599,90 @@ func TestPlannedReparentShardWaitForPositionTimeout(t *testing.T) { } func TestPlannedReparentShardRelayLogError(t *testing.T) { - delay := discovery.GetTabletPickerRetryDelay() - defer func() { - discovery.SetTabletPickerRetryDelay(delay) - }() - discovery.SetTabletPickerRetryDelay(5 * time.Millisecond) - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - ts := memorytopo.NewServer(ctx, "cell1") - wr := wrangler.New(vtenv.NewTestEnv(), logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) - vp := NewVtctlPipe(ctx, t, ts) - defer vp.Close() - - // Create a primary, a couple good replicas - primary := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_PRIMARY, nil) - goodReplica1 := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) - - // old primary - primary.FakeMysqlDaemon.ReadOnly = false - primary.FakeMysqlDaemon.Replicating = false - primary.FakeMysqlDaemon.ReplicationStatusError = mysql.ErrNotReplica - primary.FakeMysqlDaemon.SetPrimaryPositionLocked(replication.Position{ - GTIDSet: replication.MariadbGTIDSet{ - 7: replication.MariadbGTID{ - Domain: 7, - Server: 123, - Sequence: 990, - }, + relayErrors := []struct { + name string + err error + }{ + { + name: "relay log info", + err: sqlerror.NewSQLError(sqlerror.ERReplicaRelayLogInfoInitRepository, sqlerror.SSUnknownSQLState, "Replica failed to initialize relay log info structure from the repository"), + }, + { + name: "master info", + err: sqlerror.NewSQLError(sqlerror.ERMasterInfo, sqlerror.SSUnknownSQLState, "Could not initialize master info structure; more error messages can be found in the MySQL error log"), + }, + { + name: "connection metadata", + err: sqlerror.NewSQLError(sqlerror.ERReplicaConnectionMetadataInitRepository, sqlerror.SSUnknownSQLState, "Replica failed to initialize connection metadata structure from the repository"), }, - }) - primary.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ - "SUBINSERT INTO _vt.reparent_journal (time_created_ns, action_name, primary_alias, replication_position) VALUES", } - primary.StartActionLoop(t, wr) - defer primary.StopActionLoop(t) - primary.TM.QueryServiceControl.(*tabletservermock.Controller).SetQueryServiceEnabledForTests(true) - // goodReplica1 is replicating - goodReplica1.FakeMysqlDaemon.ReadOnly = true - goodReplica1.FakeMysqlDaemon.Replicating = true - goodReplica1.FakeMysqlDaemon.SetReplicationSourceInputs = append(goodReplica1.FakeMysqlDaemon.SetReplicationSourceInputs, topoproto.MysqlAddr(primary.Tablet)) - goodReplica1.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ - // These 3 statements come from tablet startup - "STOP REPLICA", - "FAKE SET SOURCE", - "START REPLICA", - // simulate error that will trigger a call to RestartReplication - "STOP REPLICA", - "RESET REPLICA", - "START REPLICA", - "START REPLICA", + for _, relayError := range relayErrors { + t.Run(relayError.name, func(t *testing.T) { + delay := discovery.GetTabletPickerRetryDelay() + defer func() { + discovery.SetTabletPickerRetryDelay(delay) + }() + discovery.SetTabletPickerRetryDelay(5 * time.Millisecond) + + ctx := t.Context() + ts := memorytopo.NewServer(ctx, "cell1") + wr := wrangler.New(vtenv.NewTestEnv(), logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) + vp := NewVtctlPipe(ctx, t, ts) + defer vp.Close() + + // Create a primary, a couple good replicas + primary := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_PRIMARY, nil) + goodReplica1 := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) + + // old primary + primary.FakeMysqlDaemon.ReadOnly = false + primary.FakeMysqlDaemon.Replicating = false + primary.FakeMysqlDaemon.ReplicationStatusError = mysql.ErrNotReplica + primary.FakeMysqlDaemon.SetPrimaryPositionLocked(replication.Position{ + GTIDSet: replication.MariadbGTIDSet{ + 7: replication.MariadbGTID{ + Domain: 7, + Server: 123, + Sequence: 990, + }, + }, + }) + primary.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "SUBINSERT INTO _vt.reparent_journal (time_created_ns, action_name, primary_alias, replication_position) VALUES", + } + primary.StartActionLoop(t, wr) + defer primary.StopActionLoop(t) + primary.TM.QueryServiceControl.(*tabletservermock.Controller).SetQueryServiceEnabledForTests(true) + + // goodReplica1 is replicating + goodReplica1.FakeMysqlDaemon.ReadOnly = true + goodReplica1.FakeMysqlDaemon.Replicating = true + goodReplica1.FakeMysqlDaemon.SetReplicationSourceInputs = append(goodReplica1.FakeMysqlDaemon.SetReplicationSourceInputs, topoproto.MysqlAddr(primary.Tablet)) + goodReplica1.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + // These 3 statements come from tablet startup + "STOP REPLICA", + "FAKE SET SOURCE", + "START REPLICA", + } + goodReplica1.StartActionLoop(t, wr) + goodReplica1.FakeMysqlDaemon.StopReplicationError = relayError.err + defer goodReplica1.StopActionLoop(t) + + // run PlannedReparentShard + err := vp.Run([]string{ + "PlannedReparentShard", "--wait_replicas_timeout", "10s", "--keyspace_shard", primary.Tablet.Keyspace + "/" + primary.Tablet.Shard, "--new_primary", + topoproto.TabletAliasString(primary.Tablet.Alias), + }) + require.ErrorContains(t, err, "failed to SetReplicationSource") + require.ErrorContains(t, err, relayError.err.Error()) + // check what was run + err = primary.FakeMysqlDaemon.CheckSuperQueryList() + require.NoError(t, err) + err = goodReplica1.FakeMysqlDaemon.CheckSuperQueryList() + require.NoError(t, err) + }) } - goodReplica1.StartActionLoop(t, wr) - goodReplica1.FakeMysqlDaemon.StopReplicationError = errors.New("Replica failed to initialize relay log info structure from the repository") - defer goodReplica1.StopActionLoop(t) - - // run PlannedReparentShard - err := vp.Run([]string{"PlannedReparentShard", "--wait_replicas_timeout", "10s", "--keyspace_shard", primary.Tablet.Keyspace + "/" + primary.Tablet.Shard, "--new_primary", - topoproto.TabletAliasString(primary.Tablet.Alias)}) - require.NoError(t, err) - // check what was run - err = primary.FakeMysqlDaemon.CheckSuperQueryList() - require.NoError(t, err) - err = goodReplica1.FakeMysqlDaemon.CheckSuperQueryList() - require.NoError(t, err) - - assert.False(t, primary.FakeMysqlDaemon.ReadOnly, "primary.FakeMysqlDaemon.ReadOnly set") - assert.True(t, goodReplica1.FakeMysqlDaemon.ReadOnly, "goodReplica1.FakeMysqlDaemon.ReadOnly not set") - assert.True(t, primary.TM.QueryServiceControl.IsServing(), "primary...QueryServiceControl not serving") - - // verify the old primary was told to start replicating (and not - // the replica that wasn't replicating in the first place) - assert.True(t, goodReplica1.FakeMysqlDaemon.Replicating, "goodReplica1.FakeMysqlDaemon.Replicating not set") } // TestPlannedReparentShardRelayLogErrorStartReplication is similar to @@ -676,86 +690,109 @@ func TestPlannedReparentShardRelayLogError(t *testing.T) { // is not replicating to start with (IO_Thread is not running) and we // simulate an error from the attempt to start replication func TestPlannedReparentShardRelayLogErrorStartReplication(t *testing.T) { - delay := discovery.GetTabletPickerRetryDelay() - defer func() { - discovery.SetTabletPickerRetryDelay(delay) - }() - discovery.SetTabletPickerRetryDelay(5 * time.Millisecond) - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - ts := memorytopo.NewServer(ctx, "cell1") - wr := wrangler.New(vtenv.NewTestEnv(), logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) - vp := NewVtctlPipe(ctx, t, ts) - defer vp.Close() - - // Create a primary, a couple good replicas - primary := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_PRIMARY, nil) - goodReplica1 := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) - reparenttestutil.SetKeyspaceDurability(context.Background(), t, ts, "test_keyspace", policy.DurabilitySemiSync) - - // old primary - primary.FakeMysqlDaemon.ReadOnly = false - primary.FakeMysqlDaemon.Replicating = false - primary.FakeMysqlDaemon.ReplicationStatusError = mysql.ErrNotReplica - primary.FakeMysqlDaemon.SetPrimaryPositionLocked(replication.Position{ - GTIDSet: replication.MariadbGTIDSet{ - 7: replication.MariadbGTID{ - Domain: 7, - Server: 123, - Sequence: 990, - }, + relayErrors := []struct { + name string + err error + }{ + { + name: "relay log info", + err: sqlerror.NewSQLError(sqlerror.ERReplicaRelayLogInfoInitRepository, sqlerror.SSUnknownSQLState, "Replica failed to initialize relay log info structure from the repository"), + }, + { + name: "master info", + err: sqlerror.NewSQLError(sqlerror.ERMasterInfo, sqlerror.SSUnknownSQLState, "Could not initialize master info structure; more error messages can be found in the MySQL error log"), + }, + { + name: "connection metadata", + err: sqlerror.NewSQLError(sqlerror.ERReplicaConnectionMetadataInitRepository, sqlerror.SSUnknownSQLState, "Replica failed to initialize connection metadata structure from the repository"), }, - }) - primary.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ - "SUBINSERT INTO _vt.reparent_journal (time_created_ns, action_name, primary_alias, replication_position) VALUES", } - primary.StartActionLoop(t, wr) - defer primary.StopActionLoop(t) - primary.TM.QueryServiceControl.(*tabletservermock.Controller).SetQueryServiceEnabledForTests(true) - // goodReplica1 is not replicating - goodReplica1.FakeMysqlDaemon.ReadOnly = true - goodReplica1.FakeMysqlDaemon.Replicating = true - goodReplica1.FakeMysqlDaemon.IOThreadRunning = false - goodReplica1.FakeMysqlDaemon.SetReplicationSourceInputs = append(goodReplica1.FakeMysqlDaemon.SetReplicationSourceInputs, topoproto.MysqlAddr(primary.Tablet)) - goodReplica1.FakeMysqlDaemon.CurrentSourceHost = primary.Tablet.MysqlHostname - goodReplica1.FakeMysqlDaemon.CurrentSourcePort = primary.Tablet.MysqlPort - goodReplica1.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ - // simulate error that will trigger a call to RestartReplication - // These 3 statements come from tablet startup - "STOP REPLICA", - "FAKE SET SOURCE", - "START REPLICA", - // In SetReplicationSource, we find that the source host and port was already set correctly, - // So we try to stop and start replication. The first STOP REPLICA comes from there - "STOP REPLICA", - // During the START REPLICA call, we find a relay log error, so we try to restart replication. - "STOP REPLICA", - "RESET REPLICA", - "START REPLICA", + for _, relayError := range relayErrors { + t.Run(relayError.name, func(t *testing.T) { + delay := discovery.GetTabletPickerRetryDelay() + defer func() { + discovery.SetTabletPickerRetryDelay(delay) + }() + discovery.SetTabletPickerRetryDelay(5 * time.Millisecond) + + ctx := t.Context() + ts := memorytopo.NewServer(ctx, "cell1") + wr := wrangler.New(vtenv.NewTestEnv(), logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) + vp := NewVtctlPipe(ctx, t, ts) + defer vp.Close() + + // Create a primary, a couple good replicas + primary := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_PRIMARY, nil) + goodReplica1 := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) + reparenttestutil.SetKeyspaceDurability(t.Context(), t, ts, "test_keyspace", policy.DurabilitySemiSync) + + // old primary + primary.FakeMysqlDaemon.ReadOnly = false + primary.FakeMysqlDaemon.Replicating = false + primary.FakeMysqlDaemon.ReplicationStatusError = mysql.ErrNotReplica + primary.FakeMysqlDaemon.SetPrimaryPositionLocked(replication.Position{ + GTIDSet: replication.MariadbGTIDSet{ + 7: replication.MariadbGTID{ + Domain: 7, + Server: 123, + Sequence: 990, + }, + }, + }) + primary.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "SUBINSERT INTO _vt.reparent_journal (time_created_ns, action_name, primary_alias, replication_position) VALUES", + } + primary.StartActionLoop(t, wr) + defer primary.StopActionLoop(t) + primary.TM.QueryServiceControl.(*tabletservermock.Controller).SetQueryServiceEnabledForTests(true) + + // goodReplica1 is not replicating + goodReplica1.FakeMysqlDaemon.ReadOnly = true + goodReplica1.FakeMysqlDaemon.Replicating = true + goodReplica1.FakeMysqlDaemon.IOThreadRunning = false + goodReplica1.FakeMysqlDaemon.SetReplicationSourceInputs = append(goodReplica1.FakeMysqlDaemon.SetReplicationSourceInputs, topoproto.MysqlAddr(primary.Tablet)) + goodReplica1.FakeMysqlDaemon.CurrentSourceHost = primary.Tablet.MysqlHostname + goodReplica1.FakeMysqlDaemon.CurrentSourcePort = primary.Tablet.MysqlPort + goodReplica1.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + // simulate error that will trigger a call to RestartReplication + // These 3 statements come from tablet startup + "STOP REPLICA", + "FAKE SET SOURCE", + "START REPLICA", + // In SetReplicationSource, we find that the source host and port was already set correctly, + // So we try to stop and start replication. The first STOP REPLICA comes from there + "STOP REPLICA", + // During the START REPLICA call, we find a relay log error, so we try to restart replication. + "STOP REPLICA", + "RESET REPLICA", + "START REPLICA", + } + goodReplica1.StartActionLoop(t, wr) + goodReplica1.FakeMysqlDaemon.StartReplicationError = relayError.err + defer goodReplica1.StopActionLoop(t) + + // run PlannedReparentShard + err := vp.Run([]string{ + "PlannedReparentShard", "--wait_replicas_timeout", "10s", "--keyspace_shard", primary.Tablet.Keyspace + "/" + primary.Tablet.Shard, "--new_primary", + topoproto.TabletAliasString(primary.Tablet.Alias), + }) + require.NoError(t, err) + // check what was run + err = primary.FakeMysqlDaemon.CheckSuperQueryList() + require.NoError(t, err) + err = goodReplica1.FakeMysqlDaemon.CheckSuperQueryList() + require.NoError(t, err) + + assert.False(t, primary.FakeMysqlDaemon.ReadOnly, "primary.FakeMysqlDaemon.ReadOnly set") + assert.True(t, goodReplica1.FakeMysqlDaemon.ReadOnly, "goodReplica1.FakeMysqlDaemon.ReadOnly not set") + assert.True(t, primary.TM.QueryServiceControl.IsServing(), "primary...QueryServiceControl not serving") + + // verify the old primary was told to start replicating (and not + // the replica that wasn't replicating in the first place) + assert.True(t, goodReplica1.FakeMysqlDaemon.Replicating, "goodReplica1.FakeMysqlDaemon.Replicating not set") + }) } - goodReplica1.StartActionLoop(t, wr) - goodReplica1.FakeMysqlDaemon.StartReplicationError = errors.New("Replica failed to initialize relay log info structure from the repository") - defer goodReplica1.StopActionLoop(t) - - // run PlannedReparentShard - err := vp.Run([]string{"PlannedReparentShard", "--wait_replicas_timeout", "10s", "--keyspace_shard", primary.Tablet.Keyspace + "/" + primary.Tablet.Shard, "--new_primary", - topoproto.TabletAliasString(primary.Tablet.Alias)}) - require.NoError(t, err) - // check what was run - err = primary.FakeMysqlDaemon.CheckSuperQueryList() - require.NoError(t, err) - err = goodReplica1.FakeMysqlDaemon.CheckSuperQueryList() - require.NoError(t, err) - - assert.False(t, primary.FakeMysqlDaemon.ReadOnly, "primary.FakeMysqlDaemon.ReadOnly set") - assert.True(t, goodReplica1.FakeMysqlDaemon.ReadOnly, "goodReplica1.FakeMysqlDaemon.ReadOnly not set") - assert.True(t, primary.TM.QueryServiceControl.IsServing(), "primary...QueryServiceControl not serving") - - // verify the old primary was told to start replicating (and not - // the replica that wasn't replicating in the first place) - assert.True(t, goodReplica1.FakeMysqlDaemon.Replicating, "goodReplica1.FakeMysqlDaemon.Replicating not set") } // TestPlannedReparentShardPromoteReplicaFail simulates a failure of the PromoteReplica call diff --git a/go/vt/wrangler/testlib/reparent_utils_test.go b/go/vt/wrangler/testlib/reparent_utils_test.go index 7012822a017..c8686e73796 100644 --- a/go/vt/wrangler/testlib/reparent_utils_test.go +++ b/go/vt/wrangler/testlib/reparent_utils_test.go @@ -18,13 +18,13 @@ package testlib import ( "context" - "errors" "testing" "time" "github.com/stretchr/testify/require" "vitess.io/vitess/go/mysql/replication" + "vitess.io/vitess/go/mysql/sqlerror" "vitess.io/vitess/go/vt/discovery" "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/topo" @@ -215,41 +215,58 @@ func TestSetReplicationSource(t *testing.T) { primary.StartActionLoop(t, wr) defer primary.StopActionLoop(t) - // test when we receive a relay log error while starting replication - t.Run("Relay log error", func(t *testing.T) { - replica := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) - // replica loop - // We have to set the settings as replicating. Otherwise, - // the replication manager intervenes and tries to fix replication, - // which ends up making this test unpredictable. - replica.FakeMysqlDaemon.Replicating = true - replica.FakeMysqlDaemon.IOThreadRunning = true - replica.FakeMysqlDaemon.SetReplicationSourceInputs = append(replica.FakeMysqlDaemon.SetReplicationSourceInputs, topoproto.MysqlAddr(primary.Tablet)) - replica.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ - // These 3 statements come from tablet startup - "STOP REPLICA", - "FAKE SET SOURCE", - "START REPLICA", - // We stop and reset the replication parameters because of relay log issues. - "STOP REPLICA", - "STOP REPLICA", - "RESET REPLICA", - "START REPLICA", - } - replica.StartActionLoop(t, wr) - defer replica.StopActionLoop(t) - - // Set the correct error message that indicates we have received a relay log error. - replica.FakeMysqlDaemon.StartReplicationError = errors.New("ERROR 1201 (HY000): Could not initialize master info structure; more error messages can be found in the MySQL error log") - // run ReparentTablet - err = wr.SetReplicationSource(ctx, replica.Tablet) - require.NoError(t, err, "SetReplicationSource failed") + relayErrors := []struct { + name string + err error + uid uint32 + }{ + { + name: "master info relay error", + err: sqlerror.NewSQLError(sqlerror.ERMasterInfo, sqlerror.SSUnknownSQLState, "Could not initialize master info structure; more error messages can be found in the MySQL error log"), + uid: 2, + }, + { + name: "applier metadata relay error", + err: sqlerror.NewSQLError(sqlerror.ERReplicaApplierMetadataInitRepository, sqlerror.SSUnknownSQLState, "Replica failed to initialize applier metadata structure from the repository"), + uid: 5, + }, + } - // check what was run - err = replica.FakeMysqlDaemon.CheckSuperQueryList() - require.NoError(t, err, "CheckSuperQueryList failed") - checkSemiSyncEnabled(t, false, true, replica) - }) + for _, relayError := range relayErrors { + t.Run(relayError.name, func(t *testing.T) { + replica := NewFakeTablet(t, wr, "cell1", relayError.uid, topodatapb.TabletType_REPLICA, nil) + // replica loop + // We have to set the settings as replicating. Otherwise, + // the replication manager intervenes and tries to fix replication, + // which ends up making this test unpredictable. + replica.FakeMysqlDaemon.Replicating = true + replica.FakeMysqlDaemon.IOThreadRunning = true + replica.FakeMysqlDaemon.SetReplicationSourceInputs = append(replica.FakeMysqlDaemon.SetReplicationSourceInputs, topoproto.MysqlAddr(primary.Tablet)) + replica.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + // These 3 statements come from tablet startup + "STOP REPLICA", + "FAKE SET SOURCE", + "START REPLICA", + // We stop and reset the replication parameters because of relay log issues. + "STOP REPLICA", + "STOP REPLICA", + "RESET REPLICA", + "START REPLICA", + } + replica.StartActionLoop(t, wr) + defer replica.StopActionLoop(t) + + // Set the correct error message that indicates we have received a relay log error. + replica.FakeMysqlDaemon.StartReplicationError = relayError.err + err := wr.SetReplicationSource(ctx, replica.Tablet) + require.NoError(t, err, "SetReplicationSource failed") + + // check what was run + err = replica.FakeMysqlDaemon.CheckSuperQueryList() + require.NoError(t, err, "CheckSuperQueryList failed") + checkSemiSyncEnabled(t, false, true, replica) + }) + } t.Run("Errant GTIDs on the replica", func(t *testing.T) { replica := NewFakeTablet(t, wr, "cell1", 4, topodatapb.TabletType_REPLICA, nil) From b59de262f3371e31ffe753ae4be5cac5732bd426 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2026 16:50:47 +0200 Subject: [PATCH 107/112] [release-22.0] ci: add `setup-go` composite action (#19784) (#19803) Signed-off-by: Tim Vaillancourt Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> --- .github/actions/setup-go/action.yml | 30 +++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/actions/setup-go/action.yml diff --git a/.github/actions/setup-go/action.yml b/.github/actions/setup-go/action.yml new file mode 100644 index 00000000000..7cfc59898f9 --- /dev/null +++ b/.github/actions/setup-go/action.yml @@ -0,0 +1,30 @@ +name: "Set up Go" +description: "Set up Go with shared module caching" +inputs: + cache: + description: "Whether to cache Go modules" + default: "true" +runs: + using: "composite" + steps: + - name: Set up Go + id: setup-go + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + with: + go-version-file: go.mod + # Disable built-in caching; its key includes ImageOS which + # creates duplicate cache entries across runner types. + cache: false + + - name: Cache Go modules + if: inputs.cache == 'true' && (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) + uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + with: + # Same paths cached by actions/setup-go internally. + path: | + ~/go/pkg/mod + ~/.cache/go-build + # Cache by version/arch/hash. Construct hash using same method as actions/setup-go. + key: go-${{ steps.setup-go.outputs.go-version }}-${{ toLower(runner.os) }}-${{ toLower(runner.arch) }}-${{ hashFiles('go.sum') }} + restore-keys: | + go-${{ steps.setup-go.outputs.go-version }}-${{ toLower(runner.os) }}-${{ toLower(runner.arch) }}- From 0c7a0ae8bda6fcf3044504ac505bd11d368a51a0 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Tue, 7 Apr 2026 21:54:50 +0000 Subject: [PATCH 108/112] [release-22.0] Add ZooKeeper connection metrics to zk2topo (#19757) (#19791) Signed-off-by: Mohamed Hamza Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Mohamed Hamza --- go/vt/topo/zk2topo/zk_conn.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/go/vt/topo/zk2topo/zk_conn.go b/go/vt/topo/zk2topo/zk_conn.go index aa7ac13d281..eed4f2d8a15 100644 --- a/go/vt/topo/zk2topo/zk_conn.go +++ b/go/vt/topo/zk2topo/zk_conn.go @@ -32,6 +32,7 @@ import ( "github.com/z-division/go-zookeeper/zk" "golang.org/x/sync/semaphore" + "vitess.io/vitess/go/stats" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/servenv" ) @@ -55,6 +56,16 @@ var ( baseTimeout = 30 * time.Second certPath, keyPath, caPath, authFile string + + zkLockAcquisition = stats.NewGaugeDuration( + "ZkLockAcquisition", + "Time to acquire a zookeeper lock") + zkConnAcquisitionRetry = stats.NewCounter( + "ZkConnAcquisitionRetry", + "Number of retries to acquire a zookeeper connection") + zkConnState = stats.NewCountersWithSingleLabel( + "ZkConnState", + "Number of times the zookeeper connection has entered each state", "state") ) func init() { @@ -236,14 +247,18 @@ func (c *ZkConn) Close() error { func (c *ZkConn) withRetry(ctx context.Context, action func(conn *zk.Conn) error) (err error) { // Handle concurrent access to a Zookeeper server here. + start := time.Now() err = c.sem.Acquire(ctx, 1) if err != nil { return err } + duration := time.Since(start) + zkLockAcquisition.Set(duration) defer c.sem.Release(1) for i := 0; i < maxAttempts; i++ { if i > 0 { + zkConnAcquisitionRetry.Add(1) // Add a bit of backoff time before retrying: // 1 second base + up to 5 seconds. time.Sleep(1*time.Second + time.Duration(rand.Int64N(5e9))) @@ -324,6 +339,7 @@ func (c *ZkConn) maybeAddAuth(ctx context.Context) { // clears out the connection record. func (c *ZkConn) handleSessionEvents(conn *zk.Conn, session <-chan zk.Event) { for event := range session { + zkConnState.Add(event.State.String(), 1) switch event.State { case zk.StateDisconnected, zk.StateExpired, zk.StateConnecting: From b255825346542f28696477208d37f84eb29e9a91 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Wed, 8 Apr 2026 14:45:23 -0700 Subject: [PATCH 109/112] [release-22.0] Restart IO threads on replicas after ERS failure (#19805) (#19822) Signed-off-by: Mohamed Hamza Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Mohamed Hamza --- .../reparentutil/emergency_reparenter.go | 89 ++++++++++++++++++ go/vt/vtctl/reparentutil/replication.go | 36 +++++++- go/vt/vtctl/reparentutil/replication_test.go | 91 +++++++++++++++++++ 3 files changed, 215 insertions(+), 1 deletion(-) diff --git a/go/vt/vtctl/reparentutil/emergency_reparenter.go b/go/vt/vtctl/reparentutil/emergency_reparenter.go index 9f8d77f1534..b953d632ff3 100644 --- a/go/vt/vtctl/reparentutil/emergency_reparenter.go +++ b/go/vt/vtctl/reparentutil/emergency_reparenter.go @@ -151,6 +151,12 @@ func (erp *EmergencyReparenter) reparentShardLocked(ctx context.Context, ev *eve var ( stoppedReplicationSnapshot *replicationSnapshot + + // replicasToRestart is the list of replicas that need replication to be restarted + // in the case of an error after their IO threads have been stopped, but before + // the ERS restarts them as part of a successful reparent. + replicasToRestart []*topodatapb.Tablet + shardInfo *topo.ShardInfo prevPrimary *topodatapb.Tablet tabletMap map[string]*topo.TabletInfo @@ -163,6 +169,32 @@ func (erp *EmergencyReparenter) reparentShardLocked(ctx context.Context, ev *eve isGTIDBased bool ) + defer func() { + // If we succeeded, or there are no replicas that need replication restarted, + // we can return early. + if err == nil || len(replicasToRestart) == 0 { + return + } + + // We create a new context with a fresh timeout so that the parent context does not cancel early while + // we attempt to restart replication on the stopped replicas. + ctx, cancel := context.WithTimeout(context.WithoutCancel(ctx), topo.RemoteOperationTimeout) + defer cancel() + + // Make sure we still have the shard lock. + if lockErr := topo.CheckShardLocked(ctx, keyspace, shard); lockErr != nil { + erp.logger.Warningf("skipping replication restart cleanup because the shard lock was lost for %s/%s: %v", keyspace, shard, lockErr) + return + } + + cleanupErr := erp.restartReplicationOnStoppedReplicas(ctx, prevPrimary, replicasToRestart, opts.durability) + if cleanupErr == nil { + return + } + + err = fmt.Errorf("%w, and restart replication cleanup failed: %v", err, cleanupErr) + }() + shardInfo, err = erp.ts.GetShard(ctx, keyspace, shard) if err != nil { return err @@ -207,6 +239,16 @@ func (erp *EmergencyReparenter) reparentShardLocked(ctx context.Context, ev *eve // Stop replication on all the tablets and build their status map stoppedReplicationSnapshot, err = stopReplicationAndBuildStatusMaps(ctx, erp.tmc, ev, tabletMap, shardInfo.PrimaryAlias, topo.RemoteOperationTimeout, opts.IgnoreReplicas, opts.NewPrimaryAlias, opts.durability, opts.WaitAllTablets, erp.logger) + + // If stoppedReplicationSnapshot is not nil, it means we have stopped replication on at + // least one replica. We'll keep track of the replicas that had their IO threads stopped + // so we can restart them later in case of an error that causes us to return early and + // leaves replication stopped. We do this before checking the error so that we ensure we + // handle partial failures (where we've stopped some replicas but failed on others) correctly. + if stoppedReplicationSnapshot != nil { + replicasToRestart = stoppedReplicationSnapshot.replicasWithStoppedIO(tabletMap) + } + if err != nil { return vterrors.Wrapf(err, "failed to stop replication and build status maps: %v", err) } @@ -277,6 +319,10 @@ func (erp *EmergencyReparenter) reparentShardLocked(ctx context.Context, ev *eve return vterrors.Wrap(err, lostTopologyLockMsg) } + // Relay logs have been successfully applied and we're ready to start repointing replicas, + // so we no longer need to restart replication manually in the event of an error. + replicasToRestart = nil + // initialize the newPrimary with the intermediate source, override this value if it is not the ideal candidate newPrimary := intermediateSource if !isIdeal { @@ -328,6 +374,49 @@ func (erp *EmergencyReparenter) reparentShardLocked(ctx context.Context, ev *eve return err } +// restartReplicationOnStoppedReplicas restarts replication on replicas whose IO threads were +// stopped by ERS before the operation aborted. +func (erp *EmergencyReparenter) restartReplicationOnStoppedReplicas( + ctx context.Context, + prevPrimary *topodatapb.Tablet, + replicas []*topodatapb.Tablet, + durability policy.Durabler, +) error { + erp.logger.Infof("restarting replication on %d replicas whose IO threads were stopped by ERS", len(replicas)) + + rec := concurrency.AllErrorRecorder{} + wg := sync.WaitGroup{} + + // Start replication on each stopped replica concurrently. + for _, replica := range replicas { + alias := topoproto.TabletAliasString(replica.Alias) + + semiSync := false + if prevPrimary != nil { + semiSync = policy.IsReplicaSemiSync(durability, prevPrimary, replica) + } + + wg.Add(1) + go func() { + defer wg.Done() + + erp.logger.Infof("restarting replication on %q after failed ERS", alias) + if err := erp.tmc.StartReplication(ctx, replica, semiSync); err != nil { + err := vterrors.Wrapf(err, "failed to restart replication on %q after failed ERS", alias) + rec.RecordError(err) + } + }() + } + + wg.Wait() + + if rec.HasErrors() { + return rec.Error() + } + + return nil +} + func (erp *EmergencyReparenter) waitForAllRelayLogsToApply( ctx context.Context, validCandidates map[string]replication.Position, diff --git a/go/vt/vtctl/reparentutil/replication.go b/go/vt/vtctl/reparentutil/replication.go index 6fa5ea5c1cd..d2ef5576374 100644 --- a/go/vt/vtctl/reparentutil/replication.go +++ b/go/vt/vtctl/reparentutil/replication.go @@ -161,6 +161,40 @@ type replicationSnapshot struct { tabletsBackupState map[string]bool } +// replicasWithStoppedIO returns the reachable replicas whose IO threads ERS +// stopped and should restart during cleanup. +func (rs *replicationSnapshot) replicasWithStoppedIO(tabletMap map[string]*topo.TabletInfo) []*topodatapb.Tablet { + replicas := make([]*topodatapb.Tablet, 0, len(rs.statusMap)) + + for alias, stopStatus := range rs.statusMap { + ioThreadWasRunning, err := replicaIOThreadWasRunning(stopStatus) + if err != nil || !ioThreadWasRunning { + continue + } + + tabletInfo := tabletMap[alias] + if tabletInfo == nil || tabletInfo.Tablet == nil { + continue + } + + replicas = append(replicas, tabletInfo.Tablet) + } + + return replicas +} + +// replicaIOThreadWasRunning returns true if a StopReplicationStatus indicates +// that ERS stopped a healthy IO thread that should restart during cleanup. +func replicaIOThreadWasRunning(stopStatus *replicationdatapb.StopReplicationStatus) (bool, error) { + if stopStatus == nil || stopStatus.Before == nil { + return false, vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "could not determine Before state of StopReplicationStatus %v", stopStatus) + } + + replStatus := replication.ProtoToReplicationStatus(stopStatus.Before) + + return replStatus.IOHealthy(), nil +} + // tabletAliasError wraps an error with the tablet alias that produced it. type tabletAliasError struct { alias *topodatapb.TabletAlias @@ -345,7 +379,7 @@ func stopReplicationAndBuildStatusMaps( // check that the tablets we were able to reach are sufficient for us to guarantee that no new write will be accepted by any tablet revokeSuccessful := haveRevoked(durability, res.reachableTablets, allTablets) if !revokeSuccessful { - return nil, vterrors.Wrapf(errRecorder.Error(), "could not reach sufficient tablets to guarantee safety: %v", errRecorder.Error()) + return res, vterrors.Wrapf(errRecorder.Error(), "could not reach sufficient tablets to guarantee safety: %v", errRecorder.Error()) } return res, nil diff --git a/go/vt/vtctl/reparentutil/replication_test.go b/go/vt/vtctl/reparentutil/replication_test.go index 57f76a903a1..136cd8f8a82 100644 --- a/go/vt/vtctl/reparentutil/replication_test.go +++ b/go/vt/vtctl/reparentutil/replication_test.go @@ -1482,6 +1482,97 @@ func TestReplicaWasRunning(t *testing.T) { } } +func TestReplicaIOThreadWasRunning(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + in *replicationdatapb.StopReplicationStatus + expected bool + shouldErr bool + }{ + { + name: "io thread running", + in: &replicationdatapb.StopReplicationStatus{ + Before: &replicationdatapb.Status{ + IoState: int32(replication.ReplicationStateRunning), + SqlState: int32(replication.ReplicationStateStopped), + }, + }, + expected: true, + }, + { + name: "io thread connecting without an io error", + in: &replicationdatapb.StopReplicationStatus{ + Before: &replicationdatapb.Status{ + IoState: int32(replication.ReplicationStateConnecting), + LastIoError: "", + SqlState: int32(replication.ReplicationStateStopped), + }, + }, + expected: true, + }, + { + name: "io thread connecting with an io error", + in: &replicationdatapb.StopReplicationStatus{ + Before: &replicationdatapb.Status{ + IoState: int32(replication.ReplicationStateConnecting), + LastIoError: "dial tcp 127.0.0.1:3306: connect: connection refused", + SqlState: int32(replication.ReplicationStateStopped), + }, + }, + expected: false, + }, + { + name: "only sql thread running", + in: &replicationdatapb.StopReplicationStatus{ + Before: &replicationdatapb.Status{ + IoState: int32(replication.ReplicationStateStopped), + SqlState: int32(replication.ReplicationStateRunning), + }, + }, + expected: false, + }, + { + name: "no replication threads running", + in: &replicationdatapb.StopReplicationStatus{ + Before: &replicationdatapb.Status{ + IoState: int32(replication.ReplicationStateStopped), + SqlState: int32(replication.ReplicationStateStopped), + }, + }, + expected: false, + }, + { + name: "passing nil pointer results in an error", + in: nil, + shouldErr: true, + }, + { + name: "status.Before is nil results in an error", + in: &replicationdatapb.StopReplicationStatus{ + Before: nil, + }, + shouldErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + actual, err := replicaIOThreadWasRunning(tt.in) + if tt.shouldErr { + require.Error(t, err) + return + } + + require.NoError(t, err) + require.Equal(t, tt.expected, actual) + }) + } +} + // waitForRelayLogsToApplyTestTMClient implements just the WaitForPosition // method of the tmclient.TabletManagerClient interface for // TestWaitForRelayLogsToApply, with the necessary trackers to facilitate From 382646d44ad00c30e04da964dbacff9245b60ca2 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Fri, 10 Apr 2026 11:17:53 -0700 Subject: [PATCH 110/112] [release-22.0] go-upgrade: fix Go image digest rewrite matching (#19820) (#19828) Signed-off-by: Mohamed Hamza Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Mohamed Hamza --- go/tools/go-upgrade/go-upgrade.go | 111 +++++++++++++++++++------ go/tools/go-upgrade/go-upgrade_test.go | 26 +++++- 2 files changed, 112 insertions(+), 25 deletions(-) diff --git a/go/tools/go-upgrade/go-upgrade.go b/go/tools/go-upgrade/go-upgrade.go index ce2c984912c..f1187f1f746 100644 --- a/go/tools/go-upgrade/go-upgrade.go +++ b/go/tools/go-upgrade/go-upgrade.go @@ -46,9 +46,6 @@ const ( // dockerPlatformArch is the target architecture for the Go base image. dockerPlatformArch = "amd64" - // dockerImageDistro is the distro suffix used in Go base image tags. - dockerImageDistro = "bookworm" - // regexpFindBootstrapVersion greps the current bootstrap version from the Makefile. The bootstrap // version is composed of either one or two numbers, for instance: 18.1 or 18. // The expected format of the input is BOOTSTRAP_VERSION=18 or BOOTSTRAP_VERSION=18.1 @@ -76,13 +73,18 @@ const ( regexpReplaceTestGoBootstrapVersion = `\"bootstrap-version\",[[:space:]]*\"([0-9.]+)\"` ) -// regexpReplaceGolangDockerImage replaces the Go version and image digest in Dockerfiles. -// Example input: "FROM --platform=linux/amd64 golang:1.25.3-bookworm@sha256:abc AS builder" +// regexpReplaceGolangDockerImage matches Go image references that the upgrader rewrites. +// +// Supported forms include: +// - ARG image=golang:1.25.3-bookworm@sha256:abc +// - FROM golang:1.25.3-trixie@sha256:abc AS builder +// - FROM --platform=linux/amd64 golang:1.25.3-bookworm@sha256:abc AS builder +// +// The first capture group retains the reference prefix. The second capture group retains the distro. var regexpReplaceGolangDockerImage = fmt.Sprintf( - `(?i)(FROM[[:space:]]+--platform=%s/%s[[:space:]]+golang:)([0-9.]+-%s)@sha256:[a-f0-9]{64}`, + `(?i)((?:ARG[[:space:]]+image=|FROM(?:[[:space:]]+--platform=%s/%s)?[[:space:]]+)golang:)[0-9.]+-([a-z0-9]+)@sha256:[a-f0-9]{64}`, dockerPlatformOS, dockerPlatformArch, - dockerImageDistro, ) type ( @@ -353,11 +355,12 @@ func chooseNewVersion(curVersion *version.Version, latestVersions version.Collec } // replaceGoVersionInCodebase goes through all the files in the codebase where the -// Golang version must be updated +// Golang version must be updated. func replaceGoVersionInCodebase(old, new *version.Version) error { if old.Equal(new) { return nil } + explore := []string{ "./build.env", "./docker/bootstrap/Dockerfile.common", @@ -384,17 +387,8 @@ func replaceGoVersionInCodebase(old, new *version.Version) error { } } - dockerDigest, err := resolveGolangImageDigest(new) - if err != nil { - return err - } - for _, fileToChange := range filesToChange { - err = replaceInFile( - []*regexp.Regexp{regexp.MustCompile(regexpReplaceGolangDockerImage)}, - []string{fmt.Sprintf("${1}%s@%s", golangDockerTag(new), dockerDigest)}, - fileToChange, - ) + err = replaceGolangImageReferencesInFile(fileToChange, new) if err != nil { return err } @@ -416,8 +410,76 @@ func replaceGoVersionInCodebase(old, new *version.Version) error { return nil } -func resolveGolangImageDigest(goVersion *version.Version) (string, error) { - ref := "golang:" + golangDockerTag(goVersion) +// replaceGolangImageReferencesInFile rewrites pinned Go image references in the given file. +func replaceGolangImageReferencesInFile(fileToChange string, goVersion *version.Version) error { + contentRaw, err := os.ReadFile(fileToChange) + if err != nil { + return err + } + + content, err := replaceGolangImageReferences(string(contentRaw), goVersion) + if err != nil { + return err + } + + return os.WriteFile(fileToChange, []byte(content), 0o644) +} + +// replaceGolangImageReferences rewrites pinned Go image references while preserving each matched distro. +func replaceGolangImageReferences(content string, goVersion *version.Version) (string, error) { + golangImageRegexp := regexp.MustCompile(regexpReplaceGolangDockerImage) + matches := golangImageRegexp.FindAllStringSubmatch(content, -1) + if len(matches) == 0 { + return content, nil + } + + digestsByDistro := map[string]string{} + for _, match := range matches { + distro := match[2] + if _, ok := digestsByDistro[distro]; ok { + continue + } + + digest, err := resolveGolangImageDigest(goVersion, distro) + if err != nil { + return "", err + } + + digestsByDistro[distro] = digest + } + + var replaceErr error + replaced := golangImageRegexp.ReplaceAllStringFunc(content, func(match string) string { + if replaceErr != nil { + return match + } + + submatch := golangImageRegexp.FindStringSubmatch(match) + if len(submatch) != 3 { + replaceErr = fmt.Errorf("malformatted golang image reference: %s", match) + return match + } + + prefix := submatch[1] + distro := submatch[2] + digest, ok := digestsByDistro[distro] + if !ok { + replaceErr = fmt.Errorf("missing golang digest for distro %s", distro) + return match + } + + return fmt.Sprintf("%s%s@%s", prefix, golangDockerTag(goVersion, distro), digest) + }) + if replaceErr != nil { + return "", replaceErr + } + + return replaced, nil +} + +// resolveGolangImageDigest resolves the pinned digest for the given Go version and distro. +func resolveGolangImageDigest(goVersion *version.Version, distro string) (string, error) { + ref := "golang:" + golangDockerTag(goVersion, distro) digest, err := crane.Digest(ref, crane.WithPlatform(&gocr.Platform{OS: dockerPlatformOS, Architecture: dockerPlatformArch})) if err != nil { @@ -427,8 +489,9 @@ func resolveGolangImageDigest(goVersion *version.Version) (string, error) { return digest, nil } -func golangDockerTag(goVersion *version.Version) string { - return goVersion.String() + "-" + dockerImageDistro +// golangDockerTag returns the Golang Docker tag for the given version and distro. +func golangDockerTag(goVersion *version.Version, distro string) string { + return goVersion.String() + "-" + distro } func updateBootstrapVersionInCodebase(old, new string, newGoVersion *version.Version) error { @@ -477,7 +540,7 @@ func updateBootstrapVersionInCodebase(old, new string, newGoVersion *version.Ver } func updateBootstrapChangelog(new string, goVersion *version.Version) error { - file, err := os.OpenFile("./docker/bootstrap/CHANGELOG.md", os.O_RDWR, 0600) + file, err := os.OpenFile("./docker/bootstrap/CHANGELOG.md", os.O_RDWR, 0o644) if err != nil { return err } @@ -539,7 +602,7 @@ func replaceInFile(oldexps []*regexp.Regexp, new []string, fileToChange string) panic("old and new should be of the same length") } - f, err := os.OpenFile(fileToChange, os.O_RDWR, 0600) + f, err := os.OpenFile(fileToChange, os.O_RDWR, 0o644) if err != nil { return err } diff --git a/go/tools/go-upgrade/go-upgrade_test.go b/go/tools/go-upgrade/go-upgrade_test.go index 438d5dc783f..8556009ca1c 100644 --- a/go/tools/go-upgrade/go-upgrade_test.go +++ b/go/tools/go-upgrade/go-upgrade_test.go @@ -91,10 +91,34 @@ func TestRegularExpressions(t *testing.T) { regexp: regexpReplaceGolangDockerImage, input: "FROM --platform=linux/amd64 golang:1.25.3-bookworm@sha256:414a753c2f67d0efccb01b5f58b3d3a8a2cbb7c012ce9e535418b5b3492b2c24 AS builder", checkF: func(t *testing.T, regexp *regexp.Regexp, input string) { - res := regexp.ReplaceAllString(input, "${1}1.25.4-bookworm@sha256:1111111111111111111111111111111111111111111111111111111111111111") + res := regexp.ReplaceAllString(input, "${1}1.25.4-${2}@sha256:1111111111111111111111111111111111111111111111111111111111111111") require.Equal(t, "FROM --platform=linux/amd64 golang:1.25.4-bookworm@sha256:1111111111111111111111111111111111111111111111111111111111111111 AS builder", res) }, }, + { + regexp: regexpReplaceGolangDockerImage, + input: "FROM --platform=linux/arm64 golang:1.25.3-bookworm@sha256:414a753c2f67d0efccb01b5f58b3d3a8a2cbb7c012ce9e535418b5b3492b2c24 AS builder", + checkF: func(t *testing.T, regexp *regexp.Regexp, input string) { + res := regexp.ReplaceAllString(input, "${1}1.25.4-${2}@sha256:1111111111111111111111111111111111111111111111111111111111111111") + require.Equal(t, input, res) + }, + }, + { + regexp: regexpReplaceGolangDockerImage, + input: "FROM golang:1.25.3-trixie@sha256:414a753c2f67d0efccb01b5f58b3d3a8a2cbb7c012ce9e535418b5b3492b2c24 AS builder", + checkF: func(t *testing.T, regexp *regexp.Regexp, input string) { + res := regexp.ReplaceAllString(input, "${1}1.25.4-${2}@sha256:1111111111111111111111111111111111111111111111111111111111111111") + require.Equal(t, "FROM golang:1.25.4-trixie@sha256:1111111111111111111111111111111111111111111111111111111111111111 AS builder", res) + }, + }, + { + regexp: regexpReplaceGolangDockerImage, + input: "ARG image=golang:1.25.3-bookworm@sha256:414a753c2f67d0efccb01b5f58b3d3a8a2cbb7c012ce9e535418b5b3492b2c24", + checkF: func(t *testing.T, regexp *regexp.Regexp, input string) { + res := regexp.ReplaceAllString(input, "${1}1.25.4-${2}@sha256:1111111111111111111111111111111111111111111111111111111111111111") + require.Equal(t, "ARG image=golang:1.25.4-bookworm@sha256:1111111111111111111111111111111111111111111111111111111111111111", res) + }, + }, } for _, list := range lists { From 6700890c595a44ab243bee39ddd2ac2e2ab2d052 Mon Sep 17 00:00:00 2001 From: Mohamed Hamza Date: Wed, 3 Sep 2025 18:37:07 -0400 Subject: [PATCH 111/112] fix actions (#193) * fix actions Signed-off-by: Mohamed Hamza * fix actions --------- Signed-off-by: Mohamed Hamza --- .github/workflows/docker_build_images.yml | 4 ++-- .github/workflows/local_example.yml | 2 +- .github/workflows/region_example.yml | 2 +- .github/workflows/upgrade_downgrade_test_backups_e2e.yml | 2 +- .../upgrade_downgrade_test_backups_e2e_next_release.yml | 2 +- .github/workflows/upgrade_downgrade_test_backups_manual.yml | 2 +- .../upgrade_downgrade_test_backups_manual_next_release.yml | 2 +- .github/workflows/upgrade_downgrade_test_onlineddl_flow.yml | 2 +- .../upgrade_downgrade_test_query_serving_queries.yml | 2 +- .../upgrade_downgrade_test_query_serving_queries_2.yml | 2 +- ...de_downgrade_test_query_serving_queries_2_next_release.yml | 2 +- ...rade_downgrade_test_query_serving_queries_next_release.yml | 2 +- .../workflows/upgrade_downgrade_test_query_serving_schema.yml | 2 +- ...grade_downgrade_test_query_serving_schema_next_release.yml | 2 +- .../workflows/upgrade_downgrade_test_reparent_new_vtctl.yml | 2 +- .../upgrade_downgrade_test_reparent_new_vttablet.yml | 2 +- .../workflows/upgrade_downgrade_test_reparent_old_vtctl.yml | 2 +- .../upgrade_downgrade_test_reparent_old_vttablet.yml | 2 +- .github/workflows/upgrade_downgrade_test_semi_sync.yml | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/docker_build_images.yml b/.github/workflows/docker_build_images.yml index a9d4ed2ceeb..830e80c338d 100644 --- a/.github/workflows/docker_build_images.yml +++ b/.github/workflows/docker_build_images.yml @@ -16,7 +16,7 @@ permissions: read-all jobs: build_and_push_vttestserver: name: Build and push vttestserver - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ubuntu-latest-xl if: github.repository == 'vitessio/vitess' strategy: @@ -136,7 +136,7 @@ jobs: build_and_push_components: name: Build and push - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ubuntu-latest-xl if: github.repository == 'vitessio/vitess' && needs.build_and_push_lite.result == 'success' needs: - build_and_push_lite diff --git a/.github/workflows/local_example.yml b/.github/workflows/local_example.yml index 4959c81ea9d..f8566104a42 100644 --- a/.github/workflows/local_example.yml +++ b/.github/workflows/local_example.yml @@ -17,7 +17,7 @@ jobs: build: name: Local example using ${{ matrix.topo }} on Ubuntu - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ubuntu-latest-xl strategy: matrix: topo: [etcd,zk2] diff --git a/.github/workflows/region_example.yml b/.github/workflows/region_example.yml index b41c86084bf..f31ca93da23 100644 --- a/.github/workflows/region_example.yml +++ b/.github/workflows/region_example.yml @@ -17,7 +17,7 @@ jobs: build: name: Region Sharding example using ${{ matrix.topo }} on Ubuntu - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ubuntu-latest-xl strategy: matrix: topo: [etcd] diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml index b4d61f87368..8c8a2eea5cb 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml @@ -18,7 +18,7 @@ jobs: upgrade_downgrade_test_e2e: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Backups - E2E - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ubuntu-latest-xl steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml index 098479787f1..6d1466c9e69 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml @@ -19,7 +19,7 @@ jobs: upgrade_downgrade_test_e2e: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Backups - E2E - Next Release - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ubuntu-latest-xl steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual.yml b/.github/workflows/upgrade_downgrade_test_backups_manual.yml index c6129b636ee..d7ae8387d9b 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_manual.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_manual.yml @@ -20,7 +20,7 @@ jobs: upgrade_downgrade_test_manual: timeout-minutes: 40 name: Run Upgrade Downgrade Test - Backups - Manual - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ubuntu-latest-xl steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml b/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml index 42cdd5ee7e3..776c8c9e8b7 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml @@ -20,7 +20,7 @@ jobs: upgrade_downgrade_test_manual: timeout-minutes: 40 name: Run Upgrade Downgrade Test - Backups - Manual - Next Release - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ubuntu-latest-xl steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml b/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml index d3ffcf8de1c..f82b9259c43 100644 --- a/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml +++ b/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml @@ -22,7 +22,7 @@ jobs: upgrade_downgrade_test: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Online DDL flow - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ubuntu-latest-xl steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml index 3e536e324de..e85a49026cc 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml @@ -22,7 +22,7 @@ jobs: upgrade_downgrade_test: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Query Serving (Queries) - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ubuntu-latest-xl steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml index e0d2d5a07d5..72d5331e01a 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml @@ -21,7 +21,7 @@ jobs: upgrade_downgrade_test: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Query Serving (Queries - 2) - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ubuntu-latest-xl steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml index aacfaf41f55..9e7c5657334 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml @@ -22,7 +22,7 @@ jobs: upgrade_downgrade_test: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Query Serving (Queries - 2) Next Release - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ubuntu-latest-xl steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml index 06312eafd37..c64cee5b914 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml @@ -22,7 +22,7 @@ jobs: upgrade_downgrade_test: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Query Serving (Queries) Next Release - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ubuntu-latest-xl steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml index 2e174484524..50f750d3179 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml @@ -22,7 +22,7 @@ jobs: upgrade_downgrade_test: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Query Serving (Schema) - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ubuntu-latest-xl steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml index 8d7d89d4a34..76b5596f2c1 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml @@ -22,7 +22,7 @@ jobs: upgrade_downgrade_test: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Query Serving (Schema) Next Release - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ubuntu-latest-xl steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml b/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml index bfb66b5220c..6fe2dbf3db8 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml @@ -22,7 +22,7 @@ jobs: upgrade_downgrade_test: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Reparent New Vtctl - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ubuntu-latest-xl steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml b/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml index 170baa58c4b..682144e3b17 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml @@ -22,7 +22,7 @@ jobs: upgrade_downgrade_test: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Reparent New VTTablet - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ubuntu-latest-xl steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml b/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml index 7b57f1fee78..e61cd907752 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml @@ -22,7 +22,7 @@ jobs: upgrade_downgrade_test: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Reparent Old Vtctl - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ubuntu-latest-xl steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml b/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml index 10bd5b65b84..0d49f056861 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml @@ -22,7 +22,7 @@ jobs: upgrade_downgrade_test: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Reparent Old VTTablet - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ubuntu-latest-xl steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_semi_sync.yml b/.github/workflows/upgrade_downgrade_test_semi_sync.yml index b5e64799c35..37db536cb8a 100644 --- a/.github/workflows/upgrade_downgrade_test_semi_sync.yml +++ b/.github/workflows/upgrade_downgrade_test_semi_sync.yml @@ -18,7 +18,7 @@ jobs: upgrade_downgrade_test_e2e: timeout-minutes: 60 name: Run Semi Sync Upgrade Downgrade Test - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ubuntu-latest-xl steps: - name: Skip CI From edf67d9f3031bb9666c4f134da794b45e44d7a2f Mon Sep 17 00:00:00 2001 From: Arthur Schreiber Date: Thu, 28 May 2026 15:41:16 +0200 Subject: [PATCH 112/112] [release-22.0] CI: deflakes, fork runner fallback, codecov / milestone gating (#20197) Signed-off-by: Arthur Schreiber Co-authored-by: Claude Opus 4.7 (1M context) --- .github/workflows/assign_milestone.yml | 1 + .github/workflows/cluster_endtoend.yml | 2 +- .github/workflows/codecov.yml | 2 +- .github/workflows/local_example.yml | 2 +- .github/workflows/region_example.yml | 2 +- .github/workflows/unit_test.yml | 2 +- .../upgrade_downgrade_test_backups_e2e.yml | 2 +- ...owngrade_test_backups_e2e_next_release.yml | 2 +- .../upgrade_downgrade_test_backups_manual.yml | 2 +- ...grade_test_backups_manual_next_release.yml | 2 +- .../upgrade_downgrade_test_onlineddl_flow.yml | 2 +- ...e_downgrade_test_query_serving_queries.yml | 2 +- ...downgrade_test_query_serving_queries_2.yml | 2 +- ...t_query_serving_queries_2_next_release.yml | 2 +- ...est_query_serving_queries_next_release.yml | 2 +- ...de_downgrade_test_query_serving_schema.yml | 2 +- ...test_query_serving_schema_next_release.yml | 2 +- ...rade_downgrade_test_reparent_new_vtctl.yml | 2 +- ...e_downgrade_test_reparent_new_vttablet.yml | 2 +- ...rade_downgrade_test_reparent_old_vtctl.yml | 2 +- ...e_downgrade_test_reparent_old_vttablet.yml | 2 +- .../upgrade_downgrade_test_semi_sync.yml | 2 +- .github/workflows/vtop_example.yml | 2 +- go/mysql/auth_server_static_test.go | 27 ++++++++++++++----- go/mysql/server_test.go | 12 ++++++++- go/vt/vtgate/schema/tracker_test.go | 2 +- 26 files changed, 56 insertions(+), 30 deletions(-) diff --git a/.github/workflows/assign_milestone.yml b/.github/workflows/assign_milestone.yml index e0c0b100a74..2d42c849f26 100644 --- a/.github/workflows/assign_milestone.yml +++ b/.github/workflows/assign_milestone.yml @@ -13,6 +13,7 @@ env: jobs: build: + if: github.repository == 'vitessio/vitess' name: Assign Milestone runs-on: ubuntu-24.04 diff --git a/.github/workflows/cluster_endtoend.yml b/.github/workflows/cluster_endtoend.yml index 1d7d385e656..ec9feca7a5f 100644 --- a/.github/workflows/cluster_endtoend.yml +++ b/.github/workflows/cluster_endtoend.yml @@ -72,7 +72,7 @@ jobs: matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} name: Run endtoend tests on Cluster (${{ matrix.shard }}) - runs-on: ${{ contains(matrix.needs, 'larger-runner') && 'gh-hosted-runners-16cores-1-24.04' || 'ubuntu-24.04' }} + runs-on: ${{ github.repository == 'vitessio/vitess' && contains(matrix.needs, 'larger-runner') && 'gh-hosted-runners-16cores-1-24.04' || 'ubuntu-24.04' }} steps: - name: Harden the runner (Audit all outbound calls) diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 4bd18ad2a68..0880fc2a226 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -17,7 +17,7 @@ permissions: read-all jobs: test: - if: github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'Backport') + if: github.repository == 'vitessio/vitess' && (github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'Backport')) name: Code Coverage runs-on: oracle-vm-8cpu-32gb-x86-64 diff --git a/.github/workflows/local_example.yml b/.github/workflows/local_example.yml index 4959c81ea9d..99badad812d 100644 --- a/.github/workflows/local_example.yml +++ b/.github/workflows/local_example.yml @@ -17,7 +17,7 @@ jobs: build: name: Local example using ${{ matrix.topo }} on Ubuntu - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ${{ github.repository == 'vitessio/vitess' && 'gh-hosted-runners-16cores-1-24.04' || 'ubuntu-24.04' }} strategy: matrix: topo: [etcd,zk2] diff --git a/.github/workflows/region_example.yml b/.github/workflows/region_example.yml index b41c86084bf..1a6cf952b75 100644 --- a/.github/workflows/region_example.yml +++ b/.github/workflows/region_example.yml @@ -17,7 +17,7 @@ jobs: build: name: Region Sharding example using ${{ matrix.topo }} on Ubuntu - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ${{ github.repository == 'vitessio/vitess' && 'gh-hosted-runners-16cores-1-24.04' || 'ubuntu-24.04' }} strategy: matrix: topo: [etcd] diff --git a/.github/workflows/unit_test.yml b/.github/workflows/unit_test.yml index 467e7625b4c..f799f906b85 100644 --- a/.github/workflows/unit_test.yml +++ b/.github/workflows/unit_test.yml @@ -66,7 +66,7 @@ jobs: race: true name: "Unit Test (${{ matrix.race && (matrix.evalengine == '1' && 'Evalengine_' || '') || (matrix.evalengine == '1' && 'evalengine_' || '') }}${{ matrix.race && 'Race' || matrix.platform }})" - runs-on: ${{ matrix.race && 'gh-hosted-runners-16cores-1-24.04' || 'ubuntu-24.04' }} + runs-on: ${{ github.repository == 'vitessio/vitess' && matrix.race && 'gh-hosted-runners-16cores-1-24.04' || 'ubuntu-24.04' }} steps: - name: Harden the runner (Audit all outbound calls) diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml index b4d61f87368..13438491967 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml @@ -18,7 +18,7 @@ jobs: upgrade_downgrade_test_e2e: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Backups - E2E - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ${{ github.repository == 'vitessio/vitess' && 'gh-hosted-runners-16cores-1-24.04' || 'ubuntu-24.04' }} steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml index 098479787f1..f7afda39cf8 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml @@ -19,7 +19,7 @@ jobs: upgrade_downgrade_test_e2e: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Backups - E2E - Next Release - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ${{ github.repository == 'vitessio/vitess' && 'gh-hosted-runners-16cores-1-24.04' || 'ubuntu-24.04' }} steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual.yml b/.github/workflows/upgrade_downgrade_test_backups_manual.yml index c6129b636ee..20240889afe 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_manual.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_manual.yml @@ -20,7 +20,7 @@ jobs: upgrade_downgrade_test_manual: timeout-minutes: 40 name: Run Upgrade Downgrade Test - Backups - Manual - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ${{ github.repository == 'vitessio/vitess' && 'gh-hosted-runners-16cores-1-24.04' || 'ubuntu-24.04' }} steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml b/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml index 42cdd5ee7e3..ef92531e42c 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml @@ -20,7 +20,7 @@ jobs: upgrade_downgrade_test_manual: timeout-minutes: 40 name: Run Upgrade Downgrade Test - Backups - Manual - Next Release - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ${{ github.repository == 'vitessio/vitess' && 'gh-hosted-runners-16cores-1-24.04' || 'ubuntu-24.04' }} steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml b/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml index d3ffcf8de1c..ceee6513309 100644 --- a/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml +++ b/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml @@ -22,7 +22,7 @@ jobs: upgrade_downgrade_test: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Online DDL flow - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ${{ github.repository == 'vitessio/vitess' && 'gh-hosted-runners-16cores-1-24.04' || 'ubuntu-24.04' }} steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml index 3e536e324de..1f7b9af1ba8 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml @@ -22,7 +22,7 @@ jobs: upgrade_downgrade_test: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Query Serving (Queries) - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ${{ github.repository == 'vitessio/vitess' && 'gh-hosted-runners-16cores-1-24.04' || 'ubuntu-24.04' }} steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml index e0d2d5a07d5..a46719fdc84 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml @@ -21,7 +21,7 @@ jobs: upgrade_downgrade_test: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Query Serving (Queries - 2) - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ${{ github.repository == 'vitessio/vitess' && 'gh-hosted-runners-16cores-1-24.04' || 'ubuntu-24.04' }} steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml index aacfaf41f55..936156f4340 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml @@ -22,7 +22,7 @@ jobs: upgrade_downgrade_test: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Query Serving (Queries - 2) Next Release - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ${{ github.repository == 'vitessio/vitess' && 'gh-hosted-runners-16cores-1-24.04' || 'ubuntu-24.04' }} steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml index 06312eafd37..1849f1c0e4c 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml @@ -22,7 +22,7 @@ jobs: upgrade_downgrade_test: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Query Serving (Queries) Next Release - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ${{ github.repository == 'vitessio/vitess' && 'gh-hosted-runners-16cores-1-24.04' || 'ubuntu-24.04' }} steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml index 2e174484524..a105a5d6a16 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml @@ -22,7 +22,7 @@ jobs: upgrade_downgrade_test: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Query Serving (Schema) - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ${{ github.repository == 'vitessio/vitess' && 'gh-hosted-runners-16cores-1-24.04' || 'ubuntu-24.04' }} steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml index 8d7d89d4a34..d8a28b21443 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml @@ -22,7 +22,7 @@ jobs: upgrade_downgrade_test: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Query Serving (Schema) Next Release - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ${{ github.repository == 'vitessio/vitess' && 'gh-hosted-runners-16cores-1-24.04' || 'ubuntu-24.04' }} steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml b/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml index bfb66b5220c..f0cefbdb886 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml @@ -22,7 +22,7 @@ jobs: upgrade_downgrade_test: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Reparent New Vtctl - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ${{ github.repository == 'vitessio/vitess' && 'gh-hosted-runners-16cores-1-24.04' || 'ubuntu-24.04' }} steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml b/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml index 170baa58c4b..271556116d1 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml @@ -22,7 +22,7 @@ jobs: upgrade_downgrade_test: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Reparent New VTTablet - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ${{ github.repository == 'vitessio/vitess' && 'gh-hosted-runners-16cores-1-24.04' || 'ubuntu-24.04' }} steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml b/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml index 7b57f1fee78..0f5548076f7 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml @@ -22,7 +22,7 @@ jobs: upgrade_downgrade_test: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Reparent Old Vtctl - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ${{ github.repository == 'vitessio/vitess' && 'gh-hosted-runners-16cores-1-24.04' || 'ubuntu-24.04' }} steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml b/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml index 10bd5b65b84..10b8f4b5765 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml @@ -22,7 +22,7 @@ jobs: upgrade_downgrade_test: timeout-minutes: 60 name: Run Upgrade Downgrade Test - Reparent Old VTTablet - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ${{ github.repository == 'vitessio/vitess' && 'gh-hosted-runners-16cores-1-24.04' || 'ubuntu-24.04' }} steps: - name: Skip CI diff --git a/.github/workflows/upgrade_downgrade_test_semi_sync.yml b/.github/workflows/upgrade_downgrade_test_semi_sync.yml index b5e64799c35..1585e1cb64f 100644 --- a/.github/workflows/upgrade_downgrade_test_semi_sync.yml +++ b/.github/workflows/upgrade_downgrade_test_semi_sync.yml @@ -18,7 +18,7 @@ jobs: upgrade_downgrade_test_e2e: timeout-minutes: 60 name: Run Semi Sync Upgrade Downgrade Test - runs-on: gh-hosted-runners-16cores-1-24.04 + runs-on: ${{ github.repository == 'vitessio/vitess' && 'gh-hosted-runners-16cores-1-24.04' || 'ubuntu-24.04' }} steps: - name: Skip CI diff --git a/.github/workflows/vtop_example.yml b/.github/workflows/vtop_example.yml index 78987fae545..c3d545c821c 100644 --- a/.github/workflows/vtop_example.yml +++ b/.github/workflows/vtop_example.yml @@ -14,7 +14,7 @@ concurrency: jobs: build: name: VTop Example - runs-on: oracle-vm-8cpu-32gb-x86-64 + runs-on: ${{ github.repository == 'vitessio/vitess' && 'oracle-vm-8cpu-32gb-x86-64' || 'ubuntu-24.04' }} steps: - name: Skip CI diff --git a/go/mysql/auth_server_static_test.go b/go/mysql/auth_server_static_test.go index 352f74ec38c..70a5517adf9 100644 --- a/go/mysql/auth_server_static_test.go +++ b/go/mysql/auth_server_static_test.go @@ -180,10 +180,7 @@ func hupTest(t *testing.T, aStatic *AuthServerStatic, tmpFile *os.File, oldStr, syscall.Kill(syscall.Getpid(), syscall.SIGHUP) // wait for signal handler - require.EventuallyWithT(t, func(c *assert.CollectT) { - require.Nil(c, aStatic.getEntries()[oldStr], "Should not have old %s after config reload", oldStr) - require.Equal(c, newStr, aStatic.getEntries()[newStr][0].Password, "%s's Password should be '%s'", newStr, newStr) - }, 30*time.Second, 10*time.Millisecond, "config should be reloaded with new file after rotation") + waitForReload(t, aStatic, oldStr, newStr) } func hupTestWithRotation(t *testing.T, aStatic *AuthServerStatic, tmpFile *os.File, oldStr, newStr string) { @@ -192,9 +189,27 @@ func hupTestWithRotation(t *testing.T, aStatic *AuthServerStatic, tmpFile *os.Fi t.Fatalf("couldn't overwrite temp file: %v", err) } + waitForReload(t, aStatic, oldStr, newStr) +} + +// waitForReload polls aStatic until the auth file reload has dropped oldStr +// and installed newStr. +// +// We use `assert.X(c, ...)` (not `require.X`) inside the callback because +// testify v1.9 on this branch implements `CollectT.FailNow` as +// `panic("Assertion failed")`, and `EventuallyWithT` doesn't recover from +// that — a failed poll would crash the test instead of being retried. We +// also gate the `[0]` indexing on `NotEmpty` for the same reason: a panic +// inside the callback (e.g. `nil[0]`) escapes the goroutine. +func waitForReload(t *testing.T, aStatic *AuthServerStatic, oldStr, newStr string) { + t.Helper() require.EventuallyWithT(t, func(c *assert.CollectT) { - require.Nil(c, aStatic.getEntries()[oldStr], "Should not have old %s after config reload", oldStr) - require.Equal(c, newStr, aStatic.getEntries()[newStr][0].Password, "%s's Password should be '%s'", newStr, newStr) + assert.Nil(c, aStatic.getEntries()[oldStr], "Should not have old %s after config reload", oldStr) + entries := aStatic.getEntries()[newStr] + if !assert.NotEmpty(c, entries, "Should have new %s entries after config reload", newStr) { + return + } + assert.Equal(c, newStr, entries[0].Password, "%s's Password should be '%s'", newStr, newStr) }, 30*time.Second, 10*time.Millisecond, "config should be reloaded with new file after rotation") } diff --git a/go/mysql/server_test.go b/go/mysql/server_test.go index 781c142e7eb..6bd4b71ce6b 100644 --- a/go/mysql/server_test.go +++ b/go/mysql/server_test.go @@ -1024,7 +1024,17 @@ func TestTLSRequired(t *testing.T) { params.SslCert = path.Join(root, "revoked-client-cert.pem") params.SslKey = path.Join(root, "revoked-client-key.pem") conn, err = connectWithGoneServerHandling() - require.ErrorContains(t, err, "remote error: tls: bad certificate") + // On a happy day the client reads the server's TLS `bad_certificate` + // alert; on a less happy day the server's TCP close races ahead of the + // alert and the client sees `connection reset by peer` / `broken pipe`. + // Either outcome means the revoked cert was rejected, which is what the + // test cares about — so accept both. + errStr := err.Error() + require.True(t, + strings.Contains(errStr, "remote error: tls: bad certificate") || + strings.Contains(errStr, "connection reset by peer") || + strings.Contains(errStr, "broken pipe"), + "expected revoked-cert connection to be rejected, got: %v", err) if conn != nil { conn.Close() } diff --git a/go/vt/vtgate/schema/tracker_test.go b/go/vt/vtgate/schema/tracker_test.go index 6feeacb6864..90235ab4583 100644 --- a/go/vt/vtgate/schema/tracker_test.go +++ b/go/vt/vtgate/schema/tracker_test.go @@ -194,7 +194,7 @@ func TestTrackerNoLock(t *testing.T) { for i := 0; i < 500000; i++ { select { case ch <- th: - case <-time.After(10 * time.Millisecond): + case <-time.After(50 * time.Millisecond): t.Fatalf("failed to send health check to tracker") } }