diff --git a/pkg/cdc/watermark_updater.go b/pkg/cdc/watermark_updater.go index bd1787397921a..90d2f8fd36ce8 100644 --- a/pkg/cdc/watermark_updater.go +++ b/pkg/cdc/watermark_updater.go @@ -39,7 +39,7 @@ const ( getWatermarkFormat = "select watermark from mo_catalog.mo_cdc_watermark where account_id = %d and task_id = '%s' and table_id = '%s'" - getWatermarkCountFormat = "select count(1) from mo_catalog.mo_cdc_watermark where account_id = %d and task_id = '%s'" + getAllWatermarkFormat = "select table_id, watermark from mo_catalog.mo_cdc_watermark where account_id = %d and task_id = '%s'" updateWatermarkFormat = "update mo_catalog.mo_cdc_watermark set watermark='%s' where account_id = %d and task_id = '%s' and table_id = '%s'" @@ -128,14 +128,28 @@ func (u *WatermarkUpdater) GetFromDb(tableIdStr string) (watermark types.TS, err return types.StringToTS(watermarkStr), nil } -func (u *WatermarkUpdater) GetCountFromDb() (uint64, error) { - sql := fmt.Sprintf(getWatermarkCountFormat, u.accountId, u.taskId) +func (u *WatermarkUpdater) GetAllFromDb() (mp map[string]types.TS, err error) { + sql := fmt.Sprintf(getAllWatermarkFormat, u.accountId, u.taskId) ctx := defines.AttachAccountId(context.Background(), catalog.System_Account) res := u.ie.Query(ctx, sql, ie.SessionOverrideOptions{}) if res.Error() != nil { - return 0, res.Error() + err = res.Error() + return + } + + var tableIdStr string + var watermarkStr string + mp = make(map[string]types.TS) + for i := uint64(0); i < res.RowCount(); i++ { + if tableIdStr, err = res.GetString(ctx, i, 0); err != nil { + return + } + if watermarkStr, err = res.GetString(ctx, i, 1); err != nil { + return + } + mp[tableIdStr] = types.StringToTS(watermarkStr) } - return res.GetUint64(ctx, 0, 0) + return } func (u *WatermarkUpdater) UpdateMem(tableIdStr string, watermark types.TS) { diff --git a/pkg/cdc/watermark_updater_test.go b/pkg/cdc/watermark_updater_test.go index ac698a25cd5d3..55917c0c0ccb1 100644 --- a/pkg/cdc/watermark_updater_test.go +++ b/pkg/cdc/watermark_updater_test.go @@ -17,32 +17,35 @@ package cdc import ( "context" "regexp" + "strconv" "strings" "sync" "testing" "time" "github.com/google/uuid" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - + "github.com/matrixorigin/matrixone/pkg/common/moerr" "github.com/matrixorigin/matrixone/pkg/container/types" ie "github.com/matrixorigin/matrixone/pkg/util/internalExecutor" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) type wmMockSQLExecutor struct { - mp map[string]string - insertRe *regexp.Regexp - updateRe *regexp.Regexp - selectRe *regexp.Regexp + mp map[string]string + insertRe *regexp.Regexp + updateRe *regexp.Regexp + selectRe *regexp.Regexp + selectAllRe *regexp.Regexp } func newWmMockSQLExecutor() *wmMockSQLExecutor { return &wmMockSQLExecutor{ - mp: make(map[string]string), - insertRe: regexp.MustCompile(`^insert .* values \(.*\, .*\, \'(.*)\'\, .*\, .*\, \'(.*)\'\, \'\'\)$`), - updateRe: regexp.MustCompile(`^update .* set watermark\=\'(.*)\' where .* and table_id \= '(.*)'$`), - selectRe: regexp.MustCompile(`^select .* and table_id \= '(.*)'$`), + mp: make(map[string]string), + insertRe: regexp.MustCompile(`^insert .* values \(.*\, .*\, \'(.*)\'\, .*\, .*\, \'(.*)\'\, \'\'\)$`), + updateRe: regexp.MustCompile(`^update .* set watermark\=\'(.*)\' where .* and table_id \= '(.*)'$`), + selectRe: regexp.MustCompile(`^select .* and table_id \= '(.*)'$`), + selectAllRe: regexp.MustCompile(`^select .* where account_id \= (.*) and task_id .*`), } } @@ -97,7 +100,7 @@ func (res *internalExecResult) Column(ctx context.Context, i uint64) (name strin } func (res *internalExecResult) RowCount() uint64 { - return 1 + return uint64(len(res.resultSet.Data)) } func (res *internalExecResult) Row(ctx context.Context, i uint64) ([]interface{}, error) { @@ -117,17 +120,25 @@ func (res *internalExecResult) GetString(ctx context.Context, i uint64, j uint64 } func (m *wmMockSQLExecutor) Query(ctx context.Context, sql string, pts ie.SessionOverrideOptions) ie.InternalExecResult { - if strings.HasPrefix(sql, "select count") { - return &internalExecResult{ - affectedRows: 1, - resultSet: &MysqlResultSet{ - Columns: nil, - Name2Index: nil, - Data: [][]interface{}{ - {uint64(len(m.mp))}, + if strings.HasPrefix(sql, "select table_id") { + matches := m.selectAllRe.FindStringSubmatch(sql) + accountId, _ := strconv.Atoi(matches[1]) + if accountId == 1 { // normal path + var data [][]interface{} + for k, v := range m.mp { + data = append(data, []interface{}{k, v}) + } + return &internalExecResult{ + affectedRows: 1, + resultSet: &MysqlResultSet{ + Columns: nil, + Name2Index: nil, + Data: data, }, - }, - err: nil, + err: nil, + } + } else { // error path + return &internalExecResult{err: moerr.NewInternalErrorNoCtx("error")} } } else if strings.HasPrefix(sql, "select") { matches := m.selectRe.FindStringSubmatch(sql) @@ -212,9 +223,9 @@ func TestWatermarkUpdater_DbOps(t *testing.T) { } // ---------- init count is 0 - count, err := u.GetCountFromDb() + mp, err := u.GetAllFromDb() assert.NoError(t, err) - assert.Equal(t, uint64(0), count) + assert.Equal(t, 0, len(mp)) // ---------- insert into a record t1 := types.BuildTS(1, 1) @@ -226,9 +237,9 @@ func TestWatermarkUpdater_DbOps(t *testing.T) { err = u.InsertIntoDb(info1, t1) assert.NoError(t, err) // count is 1 - count, err = u.GetCountFromDb() + mp, err = u.GetAllFromDb() assert.NoError(t, err) - assert.Equal(t, uint64(1), count) + assert.Equal(t, 1, len(mp)) // get value of tableId 1 actual, err := u.GetFromDb("1_0") assert.NoError(t, err) @@ -263,17 +274,17 @@ func TestWatermarkUpdater_DbOps(t *testing.T) { err = u.DeleteFromDb("1_0") assert.NoError(t, err) // count is 2 - count, err = u.GetCountFromDb() + mp, err = u.GetAllFromDb() assert.NoError(t, err) - assert.Equal(t, uint64(2), count) + assert.Equal(t, 2, len(mp)) // ---------- delete all err = u.DeleteAllFromDb() assert.NoError(t, err) // count is 0 - count, err = u.GetCountFromDb() + mp, err = u.GetAllFromDb() assert.NoError(t, err) - assert.Equal(t, uint64(0), count) + assert.Equal(t, 0, len(mp)) } func TestWatermarkUpdater_Run(t *testing.T) { @@ -337,3 +348,13 @@ func TestWatermarkUpdater_flushAll(t *testing.T) { assert.NoError(t, err) assert.Equal(t, t2, actual) } + +func TestWatermarkUpdater_GetAllFromDb(t *testing.T) { + u := &WatermarkUpdater{ + accountId: 2, + taskId: uuid.New(), + ie: newWmMockSQLExecutor(), + } + _, err := u.GetAllFromDb() + assert.Error(t, err) +} diff --git a/pkg/frontend/authenticate_test.go b/pkg/frontend/authenticate_test.go index d51ec4f9863df..e815e10e1d256 100644 --- a/pkg/frontend/authenticate_test.go +++ b/pkg/frontend/authenticate_test.go @@ -174,6 +174,7 @@ func Test_checkTenantExistsOrNot(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) @@ -225,6 +226,7 @@ func Test_checkDatabaseExistsOrNot(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) @@ -254,6 +256,7 @@ func Test_createTablesInMoCatalogOfGeneralTenant(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) @@ -302,6 +305,7 @@ func Test_initFunction(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) @@ -380,6 +384,7 @@ func Test_initUser(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) sql2result := make(map[string]ExecResult) @@ -442,6 +447,7 @@ func Test_initRole(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) @@ -5492,6 +5498,7 @@ func Test_doDropFunctionWithDB(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) @@ -5520,6 +5527,7 @@ func Test_doDropFunction(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) @@ -5887,6 +5895,7 @@ func Test_doInterpretCall(t *testing.T) { ses.SetDatabaseName("procedure_test") pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") ses.rm = rm @@ -5926,6 +5935,7 @@ func Test_doInterpretCall(t *testing.T) { ses.SetDatabaseName("procedure_test") pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) ses.GetTxnCompileCtx().execCtx = &ExecCtx{reqCtx: ctx, proc: proc, ses: ses} rm, _ := NewRoutineManager(ctx, "") @@ -5978,6 +5988,7 @@ func Test_doInterpretCall(t *testing.T) { ses.SetDatabaseName("procedure_test") pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) ses.GetTxnCompileCtx().execCtx = &ExecCtx{reqCtx: ctx, proc: proc, ses: ses} @@ -6402,6 +6413,7 @@ func Test_doAlterUser(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -6457,6 +6469,7 @@ func Test_doAlterUser(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -6508,6 +6521,7 @@ func Test_doAlterUser(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") ses.rm = rm @@ -6582,6 +6596,7 @@ func Test_doAlterAccount(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -6636,6 +6651,7 @@ func Test_doAlterAccount(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -6690,6 +6706,7 @@ func Test_doAlterAccount(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -6740,6 +6757,7 @@ func Test_doAlterAccount(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -6791,6 +6809,7 @@ func Test_doAlterAccount(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -6838,6 +6857,7 @@ func Test_doAlterAccount(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -6892,6 +6912,7 @@ func Test_doAlterAccount(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -6936,6 +6957,7 @@ func Test_doAlterAccount(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -6984,6 +7006,7 @@ func Test_doAlterAccount(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -7032,6 +7055,7 @@ func Test_doAlterAccount(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -7090,6 +7114,7 @@ func Test_doDropAccount(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) ctx = defines.AttachAccountId(ctx, 0) @@ -7151,6 +7176,7 @@ func Test_doDropAccount(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -7197,6 +7223,7 @@ func Test_doDropAccount(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -7396,6 +7423,7 @@ func Test_genRevokeCases(t *testing.T) { func newSes(priv *privilege, ctrl *gomock.Controller) *Session { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) setSessionAlloc("", NewLeakCheckAllocator()) @@ -8431,6 +8459,7 @@ func TestCheckRoleWhetherTableOwner(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -8471,6 +8500,7 @@ func TestCheckRoleWhetherTableOwner(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -8519,6 +8549,7 @@ func TestCheckRoleWhetherTableOwner(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -8562,6 +8593,7 @@ func TestCheckRoleWhetherDatabaseOwner(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -8603,6 +8635,7 @@ func TestCheckRoleWhetherDatabaseOwner(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -8651,6 +8684,7 @@ func TestCheckRoleWhetherDatabaseOwner(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -8715,6 +8749,7 @@ func TestDoAlterDatabaseConfig(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -8771,6 +8806,7 @@ func TestDoAlterDatabaseConfig(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -8829,6 +8865,7 @@ func TestDoAlterAccountConfig(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -8886,6 +8923,7 @@ func TestInsertRecordToMoMysqlCompatibilityMode(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -8937,6 +8975,7 @@ func TestDeleteRecordToMoMysqlCompatbilityMode(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -8988,6 +9027,7 @@ func TestGetVersionCompatibility(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -9035,6 +9075,7 @@ func TestCheckStageExistOrNot(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -9081,6 +9122,7 @@ func TestCheckStageExistOrNot(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -9158,6 +9200,7 @@ func TestDoDropStage(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -9212,6 +9255,7 @@ func TestDoDropStage(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -9266,6 +9310,7 @@ func TestDoDropStage(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -9318,6 +9363,7 @@ func TestDoDropStage(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -9374,6 +9420,7 @@ func TestDoCreateStage(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -9432,6 +9479,7 @@ func TestDoCreateStage(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -9492,6 +9540,7 @@ func TestDoCreateStage(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -9550,6 +9599,7 @@ func TestDoCreateStage(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -9610,6 +9660,7 @@ func TestDoCreateStage(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -9670,6 +9721,7 @@ func TestDoAlterStage(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -9733,6 +9785,7 @@ func TestDoAlterStage(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -9796,6 +9849,7 @@ func TestDoAlterStage(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -9857,6 +9911,7 @@ func TestDoAlterStage(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -9918,6 +9973,7 @@ func TestDoAlterStage(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -9980,6 +10036,7 @@ func TestDoAlterStage(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -10123,6 +10180,7 @@ func TestUpload(t *testing.T) { _, err = toml.DecodeFile("test/system_vars_config.toml", pu.SV) assert.Nil(t, err) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 pu.SV.SaveQueryResult = "on" //file service pu.FileService = fs @@ -10174,6 +10232,7 @@ func TestCheckSnapshotExistOrNot(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) setPu("", pu) @@ -10221,6 +10280,7 @@ func TestCheckSnapshotExistOrNot(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -10267,6 +10327,7 @@ func TestDoDropSnapshot(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -10321,6 +10382,7 @@ func TestDoDropSnapshot(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -10375,6 +10437,7 @@ func TestDoDropSnapshot(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -10427,6 +10490,7 @@ func TestDoDropSnapshot(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -10483,6 +10547,7 @@ func TestDoCreateSnapshot(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -10544,6 +10609,7 @@ func TestDoCreateSnapshot(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -10605,6 +10671,7 @@ func TestDoCreateSnapshot(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -10670,6 +10737,7 @@ func TestDoCreateSnapshot(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -10735,6 +10803,7 @@ func TestDoCreateSnapshot(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -10801,6 +10870,7 @@ func TestDoCreateSnapshot(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -10867,6 +10937,7 @@ func TestDoCreateSnapshot(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -10933,6 +11004,7 @@ func TestDoResolveSnapshotTsWithSnapShotName(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -10979,6 +11051,7 @@ func TestCheckTimeStampValid(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -11023,6 +11096,7 @@ func TestCheckTimeStampValid(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -11074,6 +11148,7 @@ func Test_checkPitrDup(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -11117,6 +11192,7 @@ func Test_checkPitrDup(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") diff --git a/pkg/frontend/cdc.go b/pkg/frontend/cdc.go index f440a6d68d40d..1e590fb9819ac 100644 --- a/pkg/frontend/cdc.go +++ b/pkg/frontend/cdc.go @@ -1330,16 +1330,25 @@ func (cdc *CdcTask) startWatermarkAndPipeline(ctx context.Context, dbTableInfos // start watermark updater cdc.sunkWatermarkUpdater = cdc2.NewWatermarkUpdater(cdc.cdcTask.Accounts[0].GetId(), cdc.cdcTask.TaskId, cdc.ie) - count, err := cdc.sunkWatermarkUpdater.GetCountFromDb() + mp, err := cdc.sunkWatermarkUpdater.GetAllFromDb() if err != nil { return err - } else if count == 0 { - for _, info = range dbTableInfos { + } + for _, info = range dbTableInfos { + // insert if not exists + if _, ok := mp[info.SourceTblIdStr]; !ok { // use startTs as watermark if err = cdc.sunkWatermarkUpdater.InsertIntoDb(info, cdc.startTs); err != nil { - return err + return } } + delete(mp, info.SourceTblIdStr) + } + // delete outdated watermark + for tableIdStr := range mp { + if err = cdc.sunkWatermarkUpdater.DeleteFromDb(tableIdStr); err != nil { + return err + } } go cdc.sunkWatermarkUpdater.Run(ctx, cdc.activeRoutine) diff --git a/pkg/frontend/cdc_test.go b/pkg/frontend/cdc_test.go index c6e1090f156a0..04fecd579b879 100644 --- a/pkg/frontend/cdc_test.go +++ b/pkg/frontend/cdc_test.go @@ -935,14 +935,16 @@ func (tie *testIE) Query(ctx context.Context, s string, options ie.SessionOverri rowValues = append(rowValues, dbId) rowValues = append(rowValues, tableId) } else if idx == mSqlIdx3 { - count := uint64(0) + tableIdStr := "" + watermark := "" err = rows.Scan( - &count, + &tableIdStr, + &watermark, ) if err != nil { panic(err) } - rowValues = append(rowValues, count) + rowValues = append(rowValues, tableIdStr, watermark) } else if idx == mSqlIdx5 { watermark := "" err = rows.Scan( @@ -1171,18 +1173,17 @@ func TestRegisterCdcExecutor(t *testing.T) { ), ) - sql3 := "select count.*1.* from mo_catalog.mo_cdc_watermark where account_id = 0 and task_id = '00000000-0000-0000-0000-000000000000'" - mock.ExpectQuery(sql3).WillReturnRows(sqlmock.NewRows( - []string{ - "count", - }, - ).AddRow( - uint64(0), - )) + sql3 := "select table_id, watermark from mo_catalog.mo_cdc_watermark where account_id = 0 and task_id = '00000000-0000-0000-0000-000000000000'" + mock.ExpectQuery(sql3).WillReturnRows( + sqlmock.NewRows([]string{"table_id", "watermark"}). + AddRow("1001_1", "0-0")) sql4 := "insert into mo_catalog.mo_cdc_watermark values .*0, '00000000-0000-0000-0000-000000000000', '1001_0', 'db1', 't1', '0-0'.*" mock.ExpectExec(sql4).WillReturnResult(sqlmock.NewResult(1, 1)) + sql41 := "delete from mo_catalog.mo_cdc_watermark where account_id = 0 and task_id = '00000000-0000-0000-0000-000000000000' and table_id = '1001_1'" + mock.ExpectExec(sql41).WillReturnResult(sqlmock.NewResult(1, 1)) + sql5 := "select watermark from mo_catalog.mo_cdc_watermark where account_id = 0 and task_id = '00000000-0000-0000-0000-000000000000' and table_id = '1001_0'" mock.ExpectQuery(sql5).WillReturnRows(sqlmock.NewRows( []string{ @@ -1207,6 +1208,8 @@ func TestRegisterCdcExecutor(t *testing.T) { assert.NoError(t, err) mSql4, err := regexp.MatchString(sql4, sql) assert.NoError(t, err) + mSql41, err := regexp.MatchString(sql41, sql) + assert.NoError(t, err) mSql5, err := regexp.MatchString(sql5, sql) assert.NoError(t, err) mSql6, err := regexp.MatchString(sql6, sql) @@ -1220,6 +1223,8 @@ func TestRegisterCdcExecutor(t *testing.T) { return mSqlIdx3 } else if mSql4 { return mSqlIdx4 + } else if mSql41 { + return mSqlIdx41 } else if mSql5 { return mSqlIdx5 } else if mSql6 { diff --git a/pkg/frontend/mysql_protocol_test.go b/pkg/frontend/mysql_protocol_test.go index 2851fe4e4b2d2..d00dd480fee57 100644 --- a/pkg/frontend/mysql_protocol_test.go +++ b/pkg/frontend/mysql_protocol_test.go @@ -100,6 +100,7 @@ func TestMysqlClientProtocol_Handshake(t *testing.T) { _, err = toml.DecodeFile("test/system_vars_config.toml", pu.SV) require.NoError(t, err) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setSessionAlloc("", NewLeakCheckAllocator()) setPu("", pu) @@ -200,6 +201,7 @@ func TestKill(t *testing.T) { pu, err := getParameterUnit("test/system_vars_config.toml", eng, txnClient) require.NoError(t, err) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setPu("", pu) setSessionAlloc("", NewLeakCheckAllocator()) sql1 := "select connection_id();" @@ -1310,6 +1312,7 @@ func TestMysqlResultSet(t *testing.T) { pu, err := getParameterUnit("test/system_vars_config.toml", eng, txnClient) require.NoError(t, err) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setPu("", pu) noResultSet := make(map[string]bool) @@ -1760,6 +1763,7 @@ func Test_writePackets(t *testing.T) { pu := config.NewParameterUnit(sv, nil, nil, nil) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setPu("", pu) ioses, err := NewIOSession(&testConn{}, pu, "") if err != nil { @@ -1815,6 +1819,7 @@ func Test_beginPacket(t *testing.T) { } pu := config.NewParameterUnit(sv, nil, nil, nil) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setPu("", pu) ioses, err := NewIOSession(&testConn{}, pu, "") convey.ShouldBeNil(err) @@ -1833,6 +1838,7 @@ func Test_beginPacket(t *testing.T) { } pu := config.NewParameterUnit(sv, nil, nil, nil) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setPu("", pu) ioses, err := NewIOSession(&testConn{}, pu, "") convey.ShouldBeNil(err) @@ -1857,6 +1863,7 @@ func Test_beginPacket(t *testing.T) { } pu := config.NewParameterUnit(sv, nil, nil, nil) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setPu("", pu) ioses, err := NewIOSession(&testConn{}, pu, "") convey.ShouldBeNil(err) @@ -1880,6 +1887,7 @@ func Test_beginPacket(t *testing.T) { } pu := config.NewParameterUnit(sv, nil, nil, nil) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setPu("", pu) ioses, err := NewIOSession(&testConn{}, pu, "") convey.ShouldBeNil(err) @@ -1982,6 +1990,7 @@ func TestSendPrepareResponse(t *testing.T) { } pu := config.NewParameterUnit(sv, nil, nil, nil) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setPu("", pu) ioses, err := NewIOSession(&testConn{}, pu, "") convey.ShouldBeNil(err) @@ -2019,6 +2028,7 @@ func TestSendPrepareResponse(t *testing.T) { } pu := config.NewParameterUnit(sv, nil, nil, nil) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setPu("", pu) ioses, err := NewIOSession(&testConn{}, pu, "") convey.ShouldBeNil(err) @@ -2054,6 +2064,7 @@ func FuzzParseExecuteData(f *testing.F) { } pu := config.NewParameterUnit(sv, nil, nil, nil) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setPu("", pu) ioses, err := NewIOSession(&testConn{}, pu, "") if err != nil { @@ -2180,6 +2191,7 @@ func Test_resultset(t *testing.T) { } pu := config.NewParameterUnit(sv, nil, nil, nil) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setPu("", pu) ioses, err := NewIOSession(&testConn{}, pu, "") convey.ShouldBeNil(err) @@ -2201,6 +2213,7 @@ func Test_resultset(t *testing.T) { } pu := config.NewParameterUnit(sv, nil, nil, nil) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setPu("", pu) ioses, err := NewIOSession(&testConn{}, pu, "") convey.ShouldBeNil(err) @@ -2222,6 +2235,7 @@ func Test_resultset(t *testing.T) { } pu := config.NewParameterUnit(sv, nil, nil, nil) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setPu("", pu) ioses, err := NewIOSession(&testConn{}, pu, "") convey.ShouldBeNil(err) @@ -2246,6 +2260,7 @@ func Test_resultset(t *testing.T) { } pu := config.NewParameterUnit(sv, nil, nil, nil) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setPu("", pu) ioses, err := NewIOSession(&testConn{}, pu, "") convey.ShouldBeNil(err) @@ -2270,6 +2285,7 @@ func Test_send_packet(t *testing.T) { } pu := config.NewParameterUnit(sv, nil, nil, nil) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setPu("", pu) ioses, err := NewIOSession(&testConn{}, pu, "") convey.ShouldBeNil(err) @@ -2285,6 +2301,7 @@ func Test_send_packet(t *testing.T) { } pu := config.NewParameterUnit(sv, nil, nil, nil) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setPu("", pu) ioses, err := NewIOSession(&testConn{}, pu, "") convey.ShouldBeNil(err) @@ -2310,6 +2327,7 @@ func Test_analyse320resp(t *testing.T) { } pu := config.NewParameterUnit(sv, nil, nil, nil) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setPu("", pu) ioses, err := NewIOSession(&testConn{}, pu, "") convey.ShouldBeNil(err) @@ -2353,6 +2371,7 @@ func Test_analyse320resp(t *testing.T) { } pu := config.NewParameterUnit(sv, nil, nil, nil) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setPu("", pu) ioses, err := NewIOSession(&testConn{}, pu, "") convey.ShouldBeNil(err) @@ -2396,6 +2415,7 @@ func Test_analyse41resp(t *testing.T) { } pu := config.NewParameterUnit(sv, nil, nil, nil) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setPu("", pu) ioses, err := NewIOSession(tConn, pu, "") convey.ShouldBeNil(err) @@ -2443,6 +2463,7 @@ func Test_analyse41resp(t *testing.T) { } pu := config.NewParameterUnit(sv, nil, nil, nil) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setPu("", pu) ioses, err := NewIOSession(tConn, pu, "") convey.ShouldBeNil(err) @@ -2543,6 +2564,7 @@ func Test_handleHandshake(t *testing.T) { } pu := config.NewParameterUnit(sv, nil, nil, nil) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setPu("", pu) ioses, err := NewIOSession(&testConn{}, pu, "") convey.ShouldBeNil(err) @@ -2578,6 +2600,7 @@ func Test_handleHandshake_Recover(t *testing.T) { } pu := config.NewParameterUnit(sv, nil, nil, nil) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setPu("", pu) ioses, err := NewIOSession(&testConn{}, pu, "") if err != nil { @@ -2613,6 +2636,7 @@ func TestMysqlProtocolImpl_Close(t *testing.T) { } pu := config.NewParameterUnit(sv, nil, nil, nil) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setPu("", pu) ioses, err := NewIOSession(&testConn{}, pu, "") convey.ShouldBeNil(err) diff --git a/pkg/frontend/password_management_test.go b/pkg/frontend/password_management_test.go index f2a6bc727907c..ba29db8873c32 100644 --- a/pkg/frontend/password_management_test.go +++ b/pkg/frontend/password_management_test.go @@ -22,11 +22,12 @@ import ( "time" "github.com/golang/mock/gomock" + "github.com/prashantv/gostub" + "github.com/stretchr/testify/assert" + "github.com/matrixorigin/matrixone/pkg/config" "github.com/matrixorigin/matrixone/pkg/container/types" "github.com/matrixorigin/matrixone/pkg/defines" - "github.com/prashantv/gostub" - "github.com/stretchr/testify/assert" ) func TestReverseBytes(t *testing.T) { @@ -64,6 +65,7 @@ func Test_GetUserPassword(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -102,6 +104,7 @@ func Test_CheckPasswordHistoryRule(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -143,6 +146,7 @@ func Test_CheckPasswordIntervalRule(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -184,6 +188,7 @@ func Test_PasswordVerification(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -346,6 +351,7 @@ func Test_checkPasswordReusePolicy(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") diff --git a/pkg/frontend/pitr_test.go b/pkg/frontend/pitr_test.go index b078e1dfeb395..97e30e2003095 100644 --- a/pkg/frontend/pitr_test.go +++ b/pkg/frontend/pitr_test.go @@ -130,6 +130,7 @@ func Test_createPubByPitr(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -169,6 +170,7 @@ func Test_createPubByPitr(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -210,6 +212,7 @@ func Test_createPubByPitr(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -253,6 +256,7 @@ func Test_doRestorePitr(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -330,6 +334,7 @@ func Test_doRestorePitr(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -411,6 +416,7 @@ func Test_doRestorePitr(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -493,6 +499,7 @@ func Test_doRestorePitr(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -574,6 +581,7 @@ func Test_doRestorePitr(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -670,6 +678,7 @@ func Test_doRestorePitr(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -767,6 +776,7 @@ func Test_doRestorePitr(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -863,6 +873,7 @@ func Test_doRestorePitr(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -960,6 +971,7 @@ func Test_doRestorePitr(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -1040,6 +1052,7 @@ func Test_doRestorePitr(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -1124,6 +1137,7 @@ func Test_doRestorePitrValid(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -1204,6 +1218,7 @@ func Test_doRestorePitrValid(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -1376,6 +1391,7 @@ func Test_doRestorePitr_Account(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -1501,6 +1517,7 @@ func Test_doRestorePitr_Account_Sys_Restore_Normal(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -1619,6 +1636,7 @@ func Test_doRestorePitr_Account_Sys_Restore_Normal_To_new(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -1739,6 +1757,7 @@ func Test_doRestorePitr_Account_Sys_Restore_Normal_To_new(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -1857,6 +1876,7 @@ func Test_doRestorePitr_Account_Sys_Restore_Normal_Using_cluster(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -1978,6 +1998,7 @@ func Test_doRestorePitr_Account_Sys_Restore_Normal_Using_cluster(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -2097,6 +2118,7 @@ func Test_doRestorePitr_Account_Sys_Restore_Normal_To_new_Using_cluster(t *testi pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -2222,6 +2244,7 @@ func Test_doRestorePitr_Account_Sys_Restore_Normal_To_new_Using_cluster(t *testi pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -2343,6 +2366,7 @@ func Test_doRestorePitr_Account_Sys_Restore_Normal_To_new_Using_cluster(t *testi pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -2484,6 +2508,7 @@ func Test_doCreatePitr(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -2615,6 +2640,7 @@ func Test_RestorePitrBadTimeStamp(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -2668,6 +2694,7 @@ func Test_RestorePitrFaultTolerance(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -2720,6 +2747,7 @@ func Test_RestorePitrFaultTolerance(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -2769,6 +2797,7 @@ func Test_RestorePitrFaultTolerance(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -2820,6 +2849,7 @@ func Test_RestorePitrFaultTolerance(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -2886,6 +2916,7 @@ func Test_RestorePitrFaultTolerance(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") diff --git a/pkg/frontend/routine_manager.go b/pkg/frontend/routine_manager.go index d39ac1e9a387d..bcb69d2a9a538 100644 --- a/pkg/frontend/routine_manager.go +++ b/pkg/frontend/routine_manager.go @@ -409,9 +409,10 @@ func (rm *RoutineManager) cleanKillQueue() { ar.killQueueMu.Lock() defer ar.killQueueMu.Unlock() pu := getPu(rm.service) - if pu != nil { + if pu != nil && pu.SV != nil { + tout := pu.SV.CleanKillQueueInterval for toKillAccount, killRecord := range ar.killIdQueue { - if time.Since(killRecord.killTime) > time.Duration(pu.SV.CleanKillQueueInterval)*time.Minute { + if time.Since(killRecord.killTime) > time.Duration(tout)*time.Minute { delete(ar.killIdQueue, toKillAccount) } } @@ -507,30 +508,34 @@ func NewRoutineManager(ctx context.Context, service string) (*RoutineManager, er cancel: cancel, service: service, } - if getPu(rm.service).SV.EnableTls { - err := initTlsConfig(rm, getPu(rm.service).SV) + pu := getPu(rm.service) + sv := pu.SV + if sv != nil && sv.EnableTls { + err := initTlsConfig(rm, sv) if err != nil { return nil, err } } // add kill connect routine - go func() { - for { - select { - case <-rm.ctx.Done(): - return - default: - } - rm.KillRoutineConnections() - pu := getPu(rm.service) - if pu != nil { - time.Sleep(time.Duration(pu.SV.KillRountinesInterval) * time.Second) - } else { - break + tout := pu.SV.KillRountinesInterval + if tout != 0 { + go func() { + for { + select { + case <-rm.ctx.Done(): + return + default: + } + rm.KillRoutineConnections() + if tout != 0 { + time.Sleep(time.Duration(tout) * time.Second) + } else { + break + } } - } - }() + }() + } return rm, nil } diff --git a/pkg/frontend/routine_manager_test.go b/pkg/frontend/routine_manager_test.go index 98ee546252366..4cec64570775f 100644 --- a/pkg/frontend/routine_manager_test.go +++ b/pkg/frontend/routine_manager_test.go @@ -38,6 +38,7 @@ func Test_Closed(t *testing.T) { registerConn(clientConn) pu, _ := getParameterUnit("test/system_vars_config.toml", nil, nil) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setSessionAlloc("", NewLeakCheckAllocator()) setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) diff --git a/pkg/frontend/routine_test.go b/pkg/frontend/routine_test.go index 14f5dff679ef9..d36c85910987f 100644 --- a/pkg/frontend/routine_test.go +++ b/pkg/frontend/routine_test.go @@ -164,6 +164,7 @@ func Test_ConnectionCount(t *testing.T) { pu, err := getParameterUnit("test/system_vars_config.toml", eng, txnClient) require.NoError(t, err) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setSessionAlloc("", NewLeakCheckAllocator()) setPu("", pu) diff --git a/pkg/frontend/server_test.go b/pkg/frontend/server_test.go index 7a024daaf8f66..8bc733560a7ca 100644 --- a/pkg/frontend/server_test.go +++ b/pkg/frontend/server_test.go @@ -34,6 +34,7 @@ func Test_handshake(t *testing.T) { _, err := toml.DecodeFile("test/system_vars_config.toml", pu.SV) require.NoError(t, err) pu.SV.SkipCheckUser = true + pu.SV.KillRountinesInterval = 0 setSessionAlloc("", NewLeakCheckAllocator()) setPu("", pu) diff --git a/pkg/frontend/session_test.go b/pkg/frontend/session_test.go index 1304b03890cd4..60d24511628e0 100644 --- a/pkg/frontend/session_test.go +++ b/pkg/frontend/session_test.go @@ -602,6 +602,7 @@ func TestCheckPasswordExpired(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -673,6 +674,7 @@ func Test_CheckLockTimeExpired(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") @@ -717,6 +719,7 @@ func Test_OperatorLock(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) rm, _ := NewRoutineManager(ctx, "") diff --git a/pkg/frontend/test/engine_mock.go b/pkg/frontend/test/engine_mock.go index e81848266833a..5c7820c4b49ec 100644 --- a/pkg/frontend/test/engine_mock.go +++ b/pkg/frontend/test/engine_mock.go @@ -1733,6 +1733,21 @@ func (mr *MockDatabaseMockRecorder) Relation(arg0, arg1, arg2 interface{}) *gomo return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Relation", reflect.TypeOf((*MockDatabase)(nil).Relation), arg0, arg1, arg2) } +// RelationExists mocks base method. +func (m *MockDatabase) RelationExists(arg0 context.Context, arg1 string, arg2 any) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RelationExists", arg0, arg1, arg2) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RelationExists indicates an expected call of RelationExists. +func (mr *MockDatabaseMockRecorder) RelationExists(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RelationExists", reflect.TypeOf((*MockDatabase)(nil).RelationExists), arg0, arg1, arg2) +} + // Relations mocks base method. func (m *MockDatabase) Relations(arg0 context.Context) ([]string, error) { m.ctrl.T.Helper() diff --git a/pkg/frontend/util_test.go b/pkg/frontend/util_test.go index 8a7942e1b87b0..98ed6e9ba8102 100644 --- a/pkg/frontend/util_test.go +++ b/pkg/frontend/util_test.go @@ -1501,6 +1501,7 @@ func Test_BuildTableDefFromMoColumns(t *testing.T) { pu := config.NewParameterUnit(&config.FrontendParameters{}, nil, nil, nil) pu.SV.SetDefaultValues() + pu.SV.KillRountinesInterval = 0 setPu("", pu) ctx := context.WithValue(context.TODO(), config.ParameterUnitKey, pu) ctx = context.WithValue(ctx, defines.TenantIDKey{}, uint32(0)) diff --git a/pkg/lockservice/lock.go b/pkg/lockservice/lock.go index ba1f0a2fb32bf..c634f26af2e87 100644 --- a/pkg/lockservice/lock.go +++ b/pkg/lockservice/lock.go @@ -156,10 +156,6 @@ func (l Lock) release() { func (l Lock) closeWaiter(w *waiter, logger *log.MOLogger) bool { canRemove := func() bool { - if !l.isLockRow() { - panic("BUG: range lock cannot call closeWaiter") - } - if l.holders.size() > 0 { return false } diff --git a/pkg/lockservice/lock_table_local.go b/pkg/lockservice/lock_table_local.go index 915e11b25f608..812e92da601aa 100644 --- a/pkg/lockservice/lock_table_local.go +++ b/pkg/lockservice/lock_table_local.go @@ -53,6 +53,8 @@ type localLockTable struct { options struct { beforeCloseFirstWaiter func(c *lockContext) + beforeWait func(c *lockContext) func() + afterWait func(c *lockContext) func() } } @@ -97,6 +99,7 @@ func (l *localLockTable) doLock( c *lockContext, blocked bool) { var old *waiter + var oldOffset int var err error table := l.bind.Table for { @@ -129,6 +132,14 @@ func (l *localLockTable) doLock( return } + if oldOffset != c.offset { + if old != nil { + old.disableNotify() + old.close("doLock, lock next row", l.logger) + } + c.txn.clearBlocked(old, l.logger) + } + // we handle remote lock on current rpc io read goroutine, so we can not wait here, otherwise // the rpc will be blocked. if c.opts.async { @@ -139,10 +150,21 @@ func (l *localLockTable) doLock( // txn is locked by service.lock or service_remote.lock. We must unlock here. And lock again after // wait result. Because during wait, deadlock detection may be triggered, and need call txn.fetchWhoWaitingMe, // or other concurrent txn method. + oldOffset = c.offset oldTxnID := c.txn.txnID old = c.w c.txn.Unlock() + + if l.options.beforeWait != nil { + l.options.beforeWait(c)() + } + v := c.w.wait(c.ctx, l.logger) + + if l.options.afterWait != nil { + l.options.afterWait(c)() + } + c.txn.Lock() logLocalLockWaitOnResult(l.logger, c.txn, table, c.rows[c.idx], c.opts, c.w, v) @@ -474,7 +496,8 @@ func (l *localLockTable) addRowLockLocked( func (l *localLockTable) handleLockConflictLocked( c *lockContext, key []byte, - conflictWith Lock) error { + conflictWith Lock, +) error { if c.opts.Policy == pb.WaitPolicy_FastFail { return ErrLockConflict } @@ -502,6 +525,21 @@ func (l *localLockTable) handleLockConflictLocked( // waiter added, we need to active deadlock check. c.txn.setBlocked(c.w, l.logger) logLocalLockWaitOn(l.logger, c.txn, l.bind.Table, c.w, key, conflictWith) + + if c.opts.Granularity != pb.Granularity_Range { + return nil + } + + if len(c.rangeLastWaitKey) > 0 { + v, ok := l.mu.store.Get(c.rangeLastWaitKey) + if !ok { + panic("BUG: missing range last wait key") + } + if ok && v.closeWaiter(c.w, l.logger) { + l.mu.store.Delete(c.rangeLastWaitKey) + } + } + c.rangeLastWaitKey = key return nil } diff --git a/pkg/lockservice/lock_table_local_test.go b/pkg/lockservice/lock_table_local_test.go index b52c6cf914b22..e269fc54725e9 100644 --- a/pkg/lockservice/lock_table_local_test.go +++ b/pkg/lockservice/lock_table_local_test.go @@ -937,6 +937,214 @@ func TestLocalNeedUpgrade(t *testing.T) { ) } +func TestCannotHungIfRangeConflictWithRowMultiTimes(t *testing.T) { + runLockServiceTests( + t, + []string{"s1"}, + func(_ *lockTableAllocator, s []*service) { + l := s[0] + ctx, cancel := context.WithTimeout( + context.Background(), + time.Second*10, + ) + defer cancel() + + tableID := uint64(10) + add := func( + txn []byte, + rows [][]byte, + g pb.Granularity, + ) { + mustAddTestLock( + t, + ctx, + l, + tableID, + txn, + rows, + g, + ) + } + + // workflow + // + // txn1 lock k4 + // k4: holder(txn1) waiters() + // + // txn3 lock [k1, k4], wait at k4 + // k4: holder(txn1) waiters(txn3) + // + // txn1 unlock, notify txn3 ------------------| + // k4: holder() waiters(txn3) | + // | + // txn2 lock range k2, k3 | + // k2: holder(txn2) waiters() | + // k3: holder(txn2) waiters() | + // k4: holder() waiters(txn3) | + // | + // txn3 lock [k1, k4] retry, wait at k2 <-----| + // k2: holder(txn2) waiters(txn3) + // k3: holder(txn2) waiters() + // k4: holder() waiters(txn3) + // + // txn4 lock k2, wait at k2 --------------------------------| + // k2: holder(txn2) waiters(txn3, txn4) | + // k3: holder(txn2) waiters() | + // k4: holder() waiters(txn3) | + // | + // | + // txn2 unlock, notify txn3, txn4 | + // k2: holder(txn2) waiters(txn3, txn4) -> deleted | + // k3: holder(txn2) waiters() -> deleted | + // k4: holder() waiters(txn3) | + // | + // txn4 lock k2 retry <-------------------------------------| + // k2: holder(txn4) waiters(txn3) + // k4: holder() waiters(txn3) + // + // txn3 lock [k1, k4] retry, wait at k2 + // k2: holder(txn4) waiters(txn3) + // k4: holder() waiters(txn3) + // + // txn4 lock k4, wait txn3 + // k2: holder(txn4) waiters() + // k4: holder() waiters(txn3, txn4) + + // txn1 hold row1 + txn1 := []byte{1} + txn2 := []byte{2} + txn3 := []byte{3} + txn4 := []byte{4} + + key2 := newTestRows(2) + key4 := newTestRows(4) + range23 := newTestRows(2, 3) + range14 := newTestRows(1, 4) + + txn2Locked := make(chan struct{}) + txn4WaitAt2 := make(chan struct{}) + txn4GetLockAt1 := make(chan struct{}) + startTxn3 := make(chan struct{}) + txn3WaitAt2 := make(chan struct{}) + txn3WaitAt2Again := make(chan struct{}) + txn3WaitAt4 := make(chan struct{}) + txn3NotifiedAt4 := make(chan struct{}) + var once sync.Once + + // txn1 lock k4 + add(txn1, key4, pb.Granularity_Row) + close(startTxn3) + + v, err := l.getLockTable(0, tableID) + require.NoError(t, err) + lt := v.(*localLockTable) + txn3WaitTimes := 0 + lt.options.beforeWait = func(c *lockContext) func() { + if bytes.Equal(c.txn.txnID, txn3) { + return func() { + if txn3WaitTimes == 0 { + // txn3 wait at key4 + close(txn3WaitAt4) + txn3WaitTimes++ + return + } + + if txn3WaitTimes == 1 { + close(txn3WaitAt2) + txn3WaitTimes++ + return + } + + if txn3WaitTimes == 2 { + // step10: txn4 retry lock and wait at key2 again + close(txn3WaitAt2Again) + txn3WaitTimes++ + return + } + } + } + + if bytes.Equal(c.txn.txnID, txn4) { + return func() { + once.Do(func() { + close(txn4WaitAt2) + }) + } + } + + return func() {} + } + + txn3NotifiedTimes := 0 + lt.options.afterWait = func(c *lockContext) func() { + if bytes.Equal(c.txn.txnID, txn3) { + return func() { + if txn3NotifiedTimes == 0 { + // txn1 closed and txn3 get notified + close(txn3NotifiedAt4) + txn3NotifiedTimes++ + <-txn2Locked + return + } + + if txn3NotifiedTimes == 1 { + <-txn4GetLockAt1 + } + } + } + return func() {} + } + + var wg sync.WaitGroup + wg.Add(5) + + go func() { + defer wg.Done() + <-startTxn3 + // txn3 lock range [k1, k4] + add(txn3, range14, pb.Granularity_Range) + }() + + go func() { + defer wg.Done() + <-txn3WaitAt4 + // txn1 unlock + require.NoError(t, l.Unlock(ctx, txn1, timestamp.Timestamp{})) + }() + + go func() { + defer wg.Done() + <-txn3NotifiedAt4 + // txn2 lock range [k3, k3] + add(txn2, range23, pb.Granularity_Range) + close(txn2Locked) + }() + + go func() { + defer wg.Done() + <-txn3WaitAt2 + // txn4 lock k2 + add(txn4, key2, pb.Granularity_Row) + close(txn4GetLockAt1) + <-txn3WaitAt2Again + + // txn4 lock k4 + add(txn4, key4, pb.Granularity_Row) + + require.NoError(t, l.Unlock(ctx, txn4, timestamp.Timestamp{})) + }() + + go func() { + defer wg.Done() + <-txn4WaitAt2 + require.NoError(t, l.Unlock(ctx, txn2, timestamp.Timestamp{})) + }() + + wg.Wait() + }, + ) +} + type target struct { Start string `json:"start"` End string `json:"end"` diff --git a/pkg/lockservice/service_test.go b/pkg/lockservice/service_test.go index eee0ae2e2baa8..a303ab0a47b07 100644 --- a/pkg/lockservice/service_test.go +++ b/pkg/lockservice/service_test.go @@ -3468,6 +3468,82 @@ func TestLockResultWithConflictAndTxnAborted(t *testing.T) { ) } +func TestIssue19913(t *testing.T) { + runLockServiceTests( + t, + []string{"s1"}, + func(alloc *lockTableAllocator, s []*service) { + err := os.Setenv("mo_reuse_enable_checker", "true") + require.NoError(t, err) + l1 := s[0] + + ctx, cancel := context.WithTimeout( + context.Background(), + time.Second*10) + defer cancel() + option := pb.LockOptions{ + Granularity: pb.Granularity_Row, + Mode: pb.LockMode_Exclusive, + Policy: pb.WaitPolicy_Wait, + } + + _, err = l1.Lock( + ctx, + 0, + [][]byte{{1}}, + []byte("txn1"), + option) + require.NoError(t, err) + + _, err = l1.Lock( + ctx, + 0, + [][]byte{{2}}, + []byte("txn2"), + option) + require.NoError(t, err) + + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + // blocked by txn1 + _, err := l1.Lock( + ctx, + 0, + newTestRows(1, 2), + []byte("txn3"), + option) + require.NoError(t, err) + }() + + waitWaiters(t, l1, 0, []byte{1}, 1) + + w := l1.activeTxnHolder.getActiveTxn([]byte("txn3"), false, "").blockedWaiters[0] + + require.NoError(t, l1.Unlock( + ctx, + []byte("txn1"), + timestamp.Timestamp{})) + + waitWaiters(t, l1, 0, []byte{2}, 1) + + require.NoError(t, l1.Unlock( + ctx, + []byte("txn2"), + timestamp.Timestamp{})) + wg.Wait() + + require.NoError(t, l1.Unlock( + ctx, + []byte("txn3"), + timestamp.Timestamp{})) + + require.Less(t, w.refCount.Load(), int32(2)) + }, + ) +} + func TestRowLockWithConflictAndUnlock(t *testing.T) { table := uint64(0) getRunner(false)( diff --git a/pkg/lockservice/waiter_events.go b/pkg/lockservice/waiter_events.go index 66fbd08fec3d8..a0e58361fc8cb 100644 --- a/pkg/lockservice/waiter_events.go +++ b/pkg/lockservice/waiter_events.go @@ -39,20 +39,21 @@ func init() { } type lockContext struct { - ctx context.Context - txn *activeTxn - waitTxn pb.WaitTxn - rows [][]byte - opts LockOptions - offset int - idx int - lockedTS timestamp.Timestamp - result pb.Result - cb func(pb.Result, error) - lockFunc func(*lockContext, bool) - w *waiter - createAt time.Time - closed bool + ctx context.Context + txn *activeTxn + waitTxn pb.WaitTxn + rows [][]byte + opts LockOptions + offset int + idx int + lockedTS timestamp.Timestamp + result pb.Result + cb func(pb.Result, error) + lockFunc func(*lockContext, bool) + w *waiter + createAt time.Time + closed bool + rangeLastWaitKey []byte } func (l *localLockTable) newLockContext( diff --git a/pkg/pb/pipeline/pipeline.pb.go b/pkg/pb/pipeline/pipeline.pb.go index c37d91f569b84..389fb9a69e0a4 100644 --- a/pkg/pb/pipeline/pipeline.pb.go +++ b/pkg/pb/pipeline/pipeline.pb.go @@ -3117,19 +3117,21 @@ func (m *MarkJoin) GetShuffleIdx() int32 { } type DedupJoin struct { - LeftCond []*plan.Expr `protobuf:"bytes,1,rep,name=left_cond,json=leftCond,proto3" json:"left_cond,omitempty"` - RightCond []*plan.Expr `protobuf:"bytes,2,rep,name=right_cond,json=rightCond,proto3" json:"right_cond,omitempty"` - RuntimeFilterBuildList []*plan.RuntimeFilterSpec `protobuf:"bytes,3,rep,name=runtime_filter_build_list,json=runtimeFilterBuildList,proto3" json:"runtime_filter_build_list,omitempty"` - IsShuffle bool `protobuf:"varint,4,opt,name=is_shuffle,json=isShuffle,proto3" json:"is_shuffle,omitempty"` - JoinMapTag int32 `protobuf:"varint,5,opt,name=join_map_tag,json=joinMapTag,proto3" json:"join_map_tag,omitempty"` - ShuffleIdx int32 `protobuf:"varint,6,opt,name=shuffle_idx,json=shuffleIdx,proto3" json:"shuffle_idx,omitempty"` - OnDuplicateAction plan.Node_OnDuplicateAction `protobuf:"varint,7,opt,name=on_duplicate_action,json=onDuplicateAction,proto3,enum=plan.Node_OnDuplicateAction" json:"on_duplicate_action,omitempty"` - DedupColName string `protobuf:"bytes,8,opt,name=dedup_col_name,json=dedupColName,proto3" json:"dedup_col_name,omitempty"` - DedupColTypes []plan.Type `protobuf:"bytes,9,rep,name=dedup_col_types,json=dedupColTypes,proto3" json:"dedup_col_types"` - LeftTypes []plan.Type `protobuf:"bytes,10,rep,name=left_types,json=leftTypes,proto3" json:"left_types"` - RightTypes []plan.Type `protobuf:"bytes,11,rep,name=right_types,json=rightTypes,proto3" json:"right_types"` - UpdateColIdxList []int32 `protobuf:"varint,12,rep,packed,name=update_col_idx_list,json=updateColIdxList,proto3" json:"update_col_idx_list,omitempty"` - UpdateColExprList []*plan.Expr `protobuf:"bytes,13,rep,name=update_col_expr_list,json=updateColExprList,proto3" json:"update_col_expr_list,omitempty"` + RelList []int32 `protobuf:"varint,1,rep,packed,name=rel_list,json=relList,proto3" json:"rel_list,omitempty"` + ColList []int32 `protobuf:"varint,2,rep,packed,name=col_list,json=colList,proto3" json:"col_list,omitempty"` + LeftCond []*plan.Expr `protobuf:"bytes,3,rep,name=left_cond,json=leftCond,proto3" json:"left_cond,omitempty"` + RightCond []*plan.Expr `protobuf:"bytes,4,rep,name=right_cond,json=rightCond,proto3" json:"right_cond,omitempty"` + RuntimeFilterBuildList []*plan.RuntimeFilterSpec `protobuf:"bytes,5,rep,name=runtime_filter_build_list,json=runtimeFilterBuildList,proto3" json:"runtime_filter_build_list,omitempty"` + IsShuffle bool `protobuf:"varint,6,opt,name=is_shuffle,json=isShuffle,proto3" json:"is_shuffle,omitempty"` + JoinMapTag int32 `protobuf:"varint,7,opt,name=join_map_tag,json=joinMapTag,proto3" json:"join_map_tag,omitempty"` + ShuffleIdx int32 `protobuf:"varint,8,opt,name=shuffle_idx,json=shuffleIdx,proto3" json:"shuffle_idx,omitempty"` + OnDuplicateAction plan.Node_OnDuplicateAction `protobuf:"varint,9,opt,name=on_duplicate_action,json=onDuplicateAction,proto3,enum=plan.Node_OnDuplicateAction" json:"on_duplicate_action,omitempty"` + DedupColName string `protobuf:"bytes,10,opt,name=dedup_col_name,json=dedupColName,proto3" json:"dedup_col_name,omitempty"` + DedupColTypes []plan.Type `protobuf:"bytes,11,rep,name=dedup_col_types,json=dedupColTypes,proto3" json:"dedup_col_types"` + LeftTypes []plan.Type `protobuf:"bytes,12,rep,name=left_types,json=leftTypes,proto3" json:"left_types"` + RightTypes []plan.Type `protobuf:"bytes,13,rep,name=right_types,json=rightTypes,proto3" json:"right_types"` + UpdateColIdxList []int32 `protobuf:"varint,14,rep,packed,name=update_col_idx_list,json=updateColIdxList,proto3" json:"update_col_idx_list,omitempty"` + UpdateColExprList []*plan.Expr `protobuf:"bytes,15,rep,name=update_col_expr_list,json=updateColExprList,proto3" json:"update_col_expr_list,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -3168,6 +3170,20 @@ func (m *DedupJoin) XXX_DiscardUnknown() { var xxx_messageInfo_DedupJoin proto.InternalMessageInfo +func (m *DedupJoin) GetRelList() []int32 { + if m != nil { + return m.RelList + } + return nil +} + +func (m *DedupJoin) GetColList() []int32 { + if m != nil { + return m.ColList + } + return nil +} + func (m *DedupJoin) GetLeftCond() []*plan.Expr { if m != nil { return m.LeftCond @@ -5902,371 +5918,371 @@ func init() { func init() { proto.RegisterFile("pipeline.proto", fileDescriptor_7ac67a7adf3df9c7) } var fileDescriptor_7ac67a7adf3df9c7 = []byte{ - // 5824 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7c, 0x4d, 0x6c, 0x1d, 0x47, - 0x72, 0xb0, 0xde, 0xff, 0x4c, 0xbd, 0x1f, 0x3e, 0xb6, 0xfe, 0x9e, 0x25, 0x59, 0xa2, 0xc6, 0x96, - 0xcc, 0x95, 0x2d, 0xca, 0xa6, 0x57, 0xdf, 0xfa, 0x8b, 0xb3, 0xeb, 0xa5, 0x48, 0x69, 0x97, 0xb6, - 0x28, 0x33, 0x4d, 0x2a, 0x46, 0x16, 0x41, 0x06, 0xc3, 0x99, 0x7e, 0xef, 0xcd, 0x72, 0xde, 0xcc, - 0x68, 0x7e, 0x24, 0x52, 0xa7, 0x00, 0xc9, 0x35, 0xa7, 0x3d, 0x05, 0xb9, 0x04, 0x7b, 0x48, 0x90, - 0x43, 0x7e, 0x90, 0x20, 0xa7, 0x60, 0xef, 0x9b, 0x5b, 0x4e, 0x39, 0x06, 0xc1, 0xe6, 0x96, 0x9f, - 0xdb, 0x26, 0xc8, 0x25, 0x40, 0x50, 0xd5, 0x3d, 0x3f, 0xef, 0x47, 0x14, 0x25, 0xdb, 0xc1, 0x2e, - 0xb0, 0xb7, 0xee, 0xaa, 0xea, 0x9e, 0xee, 0xaa, 0xea, 0xea, 0xea, 0xea, 0xea, 0x81, 0x5e, 0xe8, - 0x86, 0xc2, 0x73, 0x7d, 0xb1, 0x16, 0x46, 0x41, 0x12, 0x30, 0x2d, 0xab, 0x5f, 0xba, 0x3d, 0x72, - 0x93, 0x71, 0x7a, 0xb0, 0x66, 0x07, 0x93, 0x3b, 0xa3, 0x60, 0x14, 0xdc, 0x21, 0x82, 0x83, 0x74, - 0x48, 0x35, 0xaa, 0x50, 0x49, 0x36, 0xbc, 0x04, 0xa1, 0x67, 0xf9, 0xaa, 0xbc, 0x94, 0xb8, 0x13, - 0x11, 0x27, 0xd6, 0x24, 0xcc, 0x90, 0x5e, 0x60, 0x1f, 0xaa, 0xb2, 0x9e, 0x1c, 0x29, 0x3a, 0xe3, - 0x8f, 0xaa, 0xd0, 0xda, 0x11, 0x71, 0x6c, 0x8d, 0x04, 0x33, 0xa0, 0x16, 0xbb, 0xce, 0xa0, 0xb2, - 0x52, 0x59, 0xed, 0xad, 0xf7, 0xd7, 0xf2, 0x61, 0xed, 0x25, 0x56, 0x92, 0xc6, 0x1c, 0x91, 0x48, - 0x63, 0x4f, 0x9c, 0x41, 0x75, 0x96, 0x66, 0x47, 0x24, 0xe3, 0xc0, 0xe1, 0x88, 0x64, 0x7d, 0xa8, - 0x89, 0x28, 0x1a, 0xd4, 0x56, 0x2a, 0xab, 0x1d, 0x8e, 0x45, 0xc6, 0xa0, 0xee, 0x58, 0x89, 0x35, - 0xa8, 0x13, 0x88, 0xca, 0xec, 0x6d, 0xe8, 0x85, 0x51, 0x60, 0x9b, 0xae, 0x3f, 0x0c, 0x4c, 0xc2, - 0x36, 0x08, 0xdb, 0x41, 0xe8, 0xb6, 0x3f, 0x0c, 0xb6, 0x90, 0x6a, 0x00, 0x2d, 0xcb, 0xb7, 0xbc, - 0xe3, 0x58, 0x0c, 0x9a, 0x84, 0xce, 0xaa, 0xac, 0x07, 0x55, 0xd7, 0x19, 0xb4, 0x56, 0x2a, 0xab, - 0x75, 0x5e, 0x75, 0x1d, 0xfc, 0x46, 0x9a, 0xba, 0xce, 0x40, 0x93, 0xdf, 0xc0, 0x32, 0x33, 0xa0, - 0xe3, 0x0b, 0xe1, 0x3c, 0x0a, 0x12, 0x2e, 0x42, 0xef, 0x78, 0xa0, 0xaf, 0x54, 0x56, 0x35, 0x3e, - 0x05, 0x63, 0x97, 0x40, 0x73, 0xc4, 0x41, 0x3a, 0xda, 0x89, 0x47, 0x03, 0x58, 0xa9, 0xac, 0xea, - 0x3c, 0xaf, 0x1b, 0x8f, 0x41, 0xdf, 0x0c, 0x7c, 0x5f, 0xd8, 0x49, 0x10, 0xb1, 0x6b, 0xd0, 0xce, - 0xa6, 0x6b, 0x2a, 0x36, 0x35, 0x38, 0x64, 0xa0, 0x6d, 0x87, 0xbd, 0x03, 0x4b, 0x76, 0x46, 0x6d, - 0xba, 0xbe, 0x23, 0x8e, 0x88, 0x4f, 0x0d, 0xde, 0xcb, 0xc1, 0xdb, 0x08, 0x35, 0xfe, 0xbd, 0x0a, - 0xad, 0xbd, 0x71, 0x3a, 0x1c, 0x7a, 0x82, 0xbd, 0x0d, 0x5d, 0x55, 0xdc, 0x0c, 0xbc, 0x6d, 0xe7, - 0x48, 0xf5, 0x3b, 0x0d, 0x64, 0x2b, 0xd0, 0x56, 0x80, 0xfd, 0xe3, 0x50, 0xa8, 0x6e, 0xcb, 0xa0, - 0xe9, 0x7e, 0x76, 0x5c, 0x9f, 0xd8, 0x5f, 0xe3, 0xd3, 0xc0, 0x19, 0x2a, 0xeb, 0x88, 0x24, 0x32, - 0x4d, 0x65, 0xd1, 0xd7, 0x36, 0x3c, 0xf7, 0xa9, 0xe0, 0x62, 0xb4, 0xe9, 0x27, 0x24, 0x97, 0x06, - 0x2f, 0x83, 0xd8, 0x3a, 0x9c, 0x8f, 0x65, 0x13, 0x33, 0xb2, 0xfc, 0x91, 0x88, 0xcd, 0xd4, 0xf5, - 0x93, 0xff, 0xf7, 0xcd, 0x41, 0x73, 0xa5, 0xb6, 0x5a, 0xe7, 0x67, 0x15, 0x92, 0x13, 0xee, 0x31, - 0xa1, 0xd8, 0xfb, 0x70, 0x6e, 0xa6, 0x8d, 0x6c, 0xd2, 0x5a, 0xa9, 0xad, 0xd6, 0x38, 0x9b, 0x6a, - 0xb2, 0x4d, 0x2d, 0xee, 0xc3, 0x72, 0x94, 0xfa, 0xa8, 0xc9, 0x0f, 0x5c, 0x2f, 0x11, 0xd1, 0x5e, - 0x28, 0x6c, 0x92, 0x6f, 0x7b, 0xfd, 0xe2, 0x1a, 0x29, 0x3b, 0x9f, 0x45, 0xf3, 0xf9, 0x16, 0xc6, - 0x7f, 0x57, 0x41, 0xdb, 0x72, 0xe3, 0xd0, 0x4a, 0xec, 0x31, 0xbb, 0x08, 0xad, 0x61, 0xea, 0xdb, - 0x85, 0x04, 0x9b, 0x58, 0xdd, 0x76, 0xd8, 0xaf, 0xc3, 0x92, 0x17, 0xd8, 0x96, 0x67, 0xe6, 0xc2, - 0x1a, 0x54, 0x57, 0x6a, 0xab, 0xed, 0xf5, 0xb3, 0x85, 0x96, 0xe7, 0xca, 0xc0, 0x7b, 0x44, 0x5b, - 0x28, 0xc7, 0xb7, 0xa1, 0x1f, 0x89, 0x49, 0x90, 0x88, 0x52, 0xf3, 0x1a, 0x35, 0x67, 0x45, 0xf3, - 0x2f, 0x22, 0x2b, 0x7c, 0x14, 0x38, 0x82, 0x2f, 0x49, 0xda, 0xa2, 0xf9, 0x07, 0x25, 0x7e, 0x8a, - 0x91, 0xe9, 0x3a, 0x47, 0x26, 0x7d, 0x60, 0x50, 0x5f, 0xa9, 0xad, 0x36, 0x0a, 0xe6, 0x88, 0xd1, - 0xb6, 0x73, 0xf4, 0x10, 0x31, 0xec, 0x43, 0xb8, 0x30, 0xdb, 0x44, 0xf6, 0x3a, 0x68, 0x50, 0x9b, - 0xb3, 0x53, 0x6d, 0x38, 0xa1, 0xd8, 0x75, 0xe8, 0x64, 0x8d, 0x12, 0x54, 0xa4, 0xa6, 0x14, 0x6d, - 0x5c, 0x52, 0xa4, 0x8b, 0xd0, 0x72, 0x63, 0x33, 0x76, 0xfd, 0x43, 0x5a, 0x5c, 0x1a, 0x6f, 0xba, - 0xf1, 0x9e, 0xeb, 0x1f, 0xb2, 0x37, 0x40, 0x8b, 0x84, 0x2d, 0x31, 0x1a, 0x61, 0x5a, 0x91, 0xb0, - 0x09, 0x75, 0x11, 0xb0, 0x68, 0xda, 0x89, 0x50, 0x4b, 0xac, 0x19, 0x09, 0x7b, 0x33, 0x11, 0x46, - 0x0c, 0x8d, 0x1d, 0x11, 0x8d, 0x04, 0xae, 0x32, 0x6c, 0xb8, 0x67, 0x5b, 0x3e, 0xf1, 0x5d, 0xe3, - 0x79, 0x1d, 0xd7, 0x78, 0x68, 0x45, 0x89, 0x6b, 0x79, 0xa4, 0xd8, 0x1a, 0xcf, 0xaa, 0xec, 0x32, - 0xe8, 0x71, 0x62, 0x45, 0x09, 0xce, 0x8e, 0x14, 0xba, 0xc1, 0x35, 0x02, 0xe0, 0x9a, 0xb8, 0x08, - 0x2d, 0xe1, 0x3b, 0x84, 0xaa, 0x4b, 0x49, 0x0a, 0xdf, 0xd9, 0x76, 0x8e, 0x8c, 0xbf, 0xa9, 0x40, - 0x77, 0x27, 0xf5, 0x12, 0x77, 0x23, 0x1a, 0xa5, 0x62, 0xe2, 0x27, 0x68, 0x1b, 0xb6, 0xdc, 0x38, - 0x51, 0x5f, 0xa6, 0x32, 0x5b, 0x05, 0xfd, 0x7b, 0x51, 0x90, 0x86, 0xf7, 0x8f, 0xc2, 0x4c, 0xd2, - 0x20, 0x95, 0x0a, 0x21, 0xbc, 0x40, 0xb2, 0xf7, 0xa0, 0xfd, 0x79, 0xe4, 0x88, 0xe8, 0xde, 0x31, - 0xd1, 0xd6, 0xe6, 0x68, 0xcb, 0x68, 0x76, 0x05, 0xf4, 0x3d, 0x11, 0x5a, 0x91, 0x85, 0x2a, 0x50, - 0x27, 0x83, 0x52, 0x00, 0x70, 0xae, 0x44, 0xbc, 0xed, 0xa8, 0x65, 0x95, 0x55, 0x8d, 0x11, 0xe8, - 0x1b, 0xa3, 0x51, 0x24, 0x46, 0x56, 0x42, 0xc6, 0x2d, 0x08, 0x69, 0xb8, 0x35, 0x5e, 0x0d, 0x42, - 0x32, 0xa0, 0x38, 0x01, 0xc9, 0x1f, 0x2a, 0xb3, 0xab, 0x50, 0x17, 0x8b, 0xc7, 0x43, 0x70, 0x76, - 0x01, 0x9a, 0x76, 0xe0, 0x0f, 0xdd, 0x91, 0x32, 0xbb, 0xaa, 0x66, 0xfc, 0x41, 0x0d, 0x1a, 0x34, - 0x39, 0x64, 0x2f, 0x9a, 0x42, 0x53, 0x3c, 0xb5, 0xbc, 0x4c, 0x2a, 0x08, 0xb8, 0xff, 0xd4, 0xf2, - 0xd8, 0x0a, 0x34, 0xb0, 0x9b, 0x78, 0x01, 0x6f, 0x24, 0x82, 0xdd, 0x84, 0x06, 0x2a, 0x51, 0x3c, - 0x3d, 0x02, 0x54, 0xa2, 0x7b, 0xf5, 0x9f, 0xfe, 0xd3, 0xb5, 0x33, 0x5c, 0xa2, 0xd9, 0x3b, 0x50, - 0xb7, 0x46, 0xa3, 0x98, 0x74, 0x79, 0x6a, 0x39, 0xe5, 0xf3, 0xe5, 0x44, 0xc0, 0xee, 0x82, 0x2e, - 0xe5, 0x86, 0xd4, 0x0d, 0xa2, 0xbe, 0x58, 0xda, 0x62, 0xca, 0x22, 0xe5, 0x05, 0x25, 0x72, 0xdc, - 0x8d, 0x95, 0x05, 0x23, 0x8d, 0xd6, 0x78, 0x01, 0xc0, 0x3d, 0x20, 0x8c, 0xc4, 0x86, 0xe7, 0x05, - 0xf6, 0x9e, 0xfb, 0x5c, 0xa8, 0x1d, 0x63, 0x0a, 0xc6, 0x6e, 0x42, 0x6f, 0x57, 0xaa, 0x1c, 0x17, - 0x71, 0xea, 0x25, 0xb1, 0xda, 0x45, 0x66, 0xa0, 0x6c, 0x0d, 0xd8, 0x14, 0x64, 0x9f, 0xa6, 0xaf, - 0xaf, 0xd4, 0x56, 0xbb, 0x7c, 0x01, 0x86, 0xbd, 0x05, 0xdd, 0x11, 0x72, 0xda, 0xf5, 0x47, 0xe6, - 0xd0, 0xb3, 0x70, 0x83, 0xa9, 0xe1, 0x06, 0x94, 0x01, 0x1f, 0x78, 0xd6, 0xc8, 0xf8, 0x79, 0x15, - 0x9a, 0xdb, 0x7e, 0x2c, 0xa2, 0x04, 0x57, 0x89, 0x35, 0x1c, 0x0a, 0x3b, 0x11, 0xd2, 0x3a, 0xd5, - 0x79, 0x5e, 0xc7, 0x59, 0xee, 0x07, 0x5f, 0x44, 0x6e, 0x22, 0xf6, 0x3e, 0x54, 0x7a, 0x50, 0x00, - 0xd8, 0x2d, 0x58, 0xb6, 0x1c, 0xc7, 0xcc, 0xa8, 0xcd, 0x28, 0x78, 0x16, 0xd3, 0x8a, 0xd1, 0xf8, - 0x92, 0xe5, 0x38, 0x1b, 0x0a, 0xce, 0x83, 0x67, 0x31, 0xbb, 0x0e, 0xb5, 0x48, 0x0c, 0x49, 0x2b, - 0xda, 0xeb, 0x4b, 0x52, 0x6a, 0x9f, 0x1f, 0xfc, 0x50, 0xd8, 0x09, 0x17, 0x43, 0x8e, 0x38, 0x76, - 0x0e, 0x1a, 0x56, 0x92, 0x44, 0x52, 0x0a, 0x3a, 0x97, 0x15, 0xb6, 0x06, 0x67, 0x69, 0x65, 0x26, - 0x6e, 0xe0, 0x9b, 0x89, 0x75, 0xe0, 0xe1, 0x46, 0x18, 0x2b, 0x9b, 0xbf, 0x9c, 0xa3, 0xf6, 0x11, - 0xb3, 0xed, 0xc4, 0xb8, 0x4b, 0xcc, 0xd2, 0xfb, 0xd6, 0x44, 0xc4, 0x64, 0xf2, 0x75, 0x7e, 0x76, - 0xba, 0xc5, 0x23, 0x44, 0x21, 0xcb, 0x8a, 0x36, 0xb8, 0xb6, 0x35, 0x5a, 0x26, 0x9d, 0x1c, 0x88, - 0x4b, 0xff, 0x3c, 0x34, 0xdd, 0xd8, 0x14, 0xbe, 0xa3, 0xcc, 0x4d, 0xc3, 0x8d, 0xef, 0xfb, 0x0e, - 0x7b, 0x17, 0x74, 0xf9, 0x15, 0x47, 0x0c, 0x69, 0x2f, 0x6f, 0xaf, 0xf7, 0x94, 0x52, 0x22, 0x78, - 0x4b, 0x0c, 0xb9, 0x96, 0xa8, 0x92, 0xf1, 0x93, 0x2a, 0xb4, 0x49, 0x87, 0x1e, 0x87, 0x0e, 0x2e, - 0xb9, 0xb7, 0xa0, 0x3b, 0xcd, 0x3d, 0x29, 0x80, 0x8e, 0x55, 0x66, 0xdd, 0x05, 0x68, 0x6e, 0xd8, - 0x38, 0x0a, 0x92, 0x40, 0x97, 0xab, 0x1a, 0x2e, 0xeb, 0xed, 0x7b, 0xa9, 0x7d, 0x28, 0x12, 0x62, - 0x7a, 0x97, 0x67, 0x55, 0xc4, 0x3c, 0x52, 0x98, 0xba, 0xc4, 0xa8, 0x2a, 0xbb, 0x0f, 0xb0, 0x27, - 0x46, 0x13, 0xe1, 0x27, 0x3b, 0x56, 0xa8, 0xd4, 0xfd, 0xc6, 0x8c, 0xba, 0xcb, 0xb1, 0xad, 0x15, - 0x74, 0xf7, 0xfd, 0x24, 0x3a, 0xe6, 0xa5, 0x86, 0xec, 0x5b, 0xb0, 0x94, 0x12, 0x95, 0x69, 0x27, - 0x47, 0xa6, 0x87, 0x56, 0xa2, 0x49, 0x7d, 0x29, 0xc9, 0xca, 0x2e, 0x36, 0x93, 0x23, 0xde, 0x4d, - 0xb3, 0xe2, 0x43, 0x37, 0x4e, 0x2e, 0x7d, 0x1b, 0x96, 0x66, 0xfa, 0x45, 0xcf, 0xed, 0x50, 0x1c, - 0xd3, 0xcc, 0x75, 0x8e, 0x45, 0x54, 0x84, 0xa7, 0x96, 0x97, 0x66, 0x2e, 0x87, 0xac, 0xfc, 0x5a, - 0xf5, 0xa3, 0x8a, 0xf1, 0x26, 0x34, 0x36, 0xa2, 0xc8, 0x22, 0x12, 0x0b, 0x0b, 0x83, 0x0a, 0xed, - 0x3b, 0xb2, 0x62, 0xd8, 0x50, 0xc3, 0xd1, 0xdd, 0x80, 0xea, 0x24, 0x24, 0x4c, 0x7b, 0xfd, 0x7c, - 0x69, 0x72, 0x56, 0xb8, 0xb6, 0xa3, 0x26, 0x53, 0x9d, 0x84, 0x97, 0xee, 0x42, 0x6b, 0xe7, 0x35, - 0xc6, 0xf0, 0x9f, 0x75, 0xd0, 0xb6, 0x84, 0x27, 0x48, 0x06, 0x06, 0x74, 0xca, 0x6a, 0x9e, 0xc9, - 0x6f, 0x4a, 0xf5, 0x0d, 0xe8, 0xc8, 0x9d, 0x90, 0x5a, 0x09, 0xb5, 0x8e, 0xa6, 0x60, 0xaf, 0x25, - 0xcb, 0x2b, 0x00, 0x51, 0xf0, 0xcc, 0x74, 0xe5, 0x76, 0x24, 0x2d, 0xbb, 0x16, 0x05, 0xcf, 0xb6, - 0x71, 0x43, 0xfa, 0x3f, 0x59, 0x37, 0xdf, 0x82, 0x41, 0x69, 0xdd, 0xa0, 0x9b, 0x69, 0xba, 0xbe, - 0x79, 0x80, 0x3e, 0x8f, 0x5a, 0x42, 0x45, 0x9f, 0xe4, 0x85, 0x6e, 0xfb, 0xf7, 0xc8, 0x21, 0x52, - 0xd6, 0x40, 0x3f, 0xc1, 0x1a, 0x2c, 0x34, 0x2e, 0xb0, 0xd8, 0xb8, 0xdc, 0x9b, 0xd2, 0xea, 0x36, - 0x09, 0xde, 0x28, 0x04, 0x9f, 0x49, 0xeb, 0x44, 0x95, 0xbe, 0x0e, 0x1d, 0xdb, 0xf2, 0xcd, 0x24, - 0x4a, 0x7d, 0xdb, 0x4a, 0xc4, 0xa0, 0x43, 0x9f, 0x6a, 0xdb, 0x96, 0xbf, 0xaf, 0x40, 0x25, 0x0b, - 0xd0, 0x2d, 0x5b, 0x80, 0x9b, 0xb0, 0x14, 0x46, 0xee, 0xc4, 0x8a, 0x8e, 0xcd, 0x43, 0x71, 0x4c, - 0xc2, 0xe8, 0x49, 0x7f, 0x5a, 0x81, 0x3f, 0x13, 0xc7, 0xdb, 0xce, 0xd1, 0x97, 0xd5, 0xfd, 0x7f, - 0xac, 0x82, 0xbe, 0x1b, 0x09, 0x65, 0xb5, 0xaf, 0x41, 0x3b, 0xb6, 0xc7, 0x62, 0x62, 0x91, 0x94, - 0x54, 0x0f, 0x20, 0x41, 0x28, 0x9c, 0x69, 0xbb, 0x54, 0x3d, 0xd9, 0x2e, 0xe1, 0x38, 0xa4, 0xb7, - 0x83, 0x8b, 0x09, 0x8b, 0x85, 0x31, 0xae, 0x97, 0x8d, 0xf1, 0x0a, 0x74, 0xc6, 0x56, 0x6c, 0x5a, - 0x69, 0x12, 0x98, 0x76, 0xe0, 0x91, 0xd2, 0x69, 0x1c, 0xc6, 0x56, 0xbc, 0x91, 0x26, 0xc1, 0x66, - 0x40, 0xde, 0x93, 0x1b, 0x9b, 0x72, 0xd1, 0xab, 0x7d, 0x51, 0x73, 0x63, 0x65, 0xee, 0xd6, 0xe0, - 0xac, 0x88, 0x13, 0x77, 0x62, 0x29, 0x81, 0x9a, 0x76, 0x90, 0xfa, 0x09, 0xed, 0x8e, 0x35, 0xbe, - 0x9c, 0xa3, 0x78, 0xf0, 0x6c, 0x13, 0x11, 0xec, 0x7d, 0xe8, 0xd9, 0xc1, 0x24, 0x34, 0x43, 0xe4, - 0x2b, 0xf9, 0x1d, 0xd2, 0x11, 0x2f, 0xfb, 0x05, 0x1d, 0xa4, 0xd8, 0x3d, 0x14, 0xd2, 0x11, 0x5a, - 0x87, 0x25, 0xdb, 0x4b, 0xe3, 0x44, 0x44, 0xe6, 0x81, 0x6a, 0xa2, 0xcf, 0x35, 0xe9, 0x2a, 0x12, - 0xe9, 0x3c, 0x21, 0x63, 0x5b, 0xbb, 0x41, 0x9c, 0x6c, 0x4d, 0xbc, 0x4c, 0x31, 0x2b, 0xaf, 0xaa, - 0x98, 0xd5, 0xc5, 0x8a, 0xb9, 0x40, 0x35, 0x6a, 0x0b, 0x54, 0x83, 0xad, 0x42, 0xbf, 0x4c, 0x47, - 0x22, 0x95, 0x6e, 0x5c, 0xaf, 0x20, 0x24, 0xb1, 0x4a, 0xfe, 0x3a, 0xd2, 0x92, 0x34, 0x32, 0xfe, - 0x2a, 0x2b, 0x22, 0x91, 0x2e, 0x69, 0x48, 0xc1, 0x7c, 0xa5, 0x31, 0xff, 0x1f, 0xde, 0xc8, 0x5b, - 0x9a, 0xcf, 0xdc, 0x64, 0x1c, 0xa4, 0x89, 0x39, 0xa4, 0x13, 0x4b, 0xac, 0xbc, 0xee, 0x0b, 0x59, - 0x4f, 0x5f, 0x48, 0xb4, 0x3c, 0xcf, 0x90, 0x8f, 0x34, 0x4c, 0x3d, 0xcf, 0x4c, 0xc4, 0x51, 0xa2, - 0x44, 0x30, 0x90, 0xbc, 0x51, 0x7c, 0x7b, 0x90, 0x7a, 0xde, 0xbe, 0x38, 0x4a, 0xd0, 0xe2, 0x6b, - 0x43, 0x55, 0x31, 0xfe, 0xb6, 0x06, 0xf0, 0x30, 0xb0, 0x0f, 0xf7, 0xad, 0x68, 0x24, 0x12, 0xf4, - 0xe5, 0x33, 0x3b, 0xa4, 0xec, 0x64, 0x2b, 0x91, 0xd6, 0x87, 0xad, 0xc3, 0x85, 0x6c, 0xfe, 0x76, - 0xe0, 0xd1, 0xb9, 0x42, 0x1a, 0x12, 0xb5, 0x0c, 0x98, 0xc2, 0xca, 0x93, 0x29, 0x59, 0x11, 0xf6, - 0x51, 0xc1, 0x5b, 0x6c, 0x93, 0x1c, 0x87, 0xc4, 0xdb, 0x45, 0x3e, 0x61, 0xb7, 0x68, 0xbe, 0x7f, - 0x1c, 0xb2, 0xf7, 0xe1, 0x7c, 0x24, 0x86, 0x91, 0x88, 0xc7, 0x66, 0x12, 0x97, 0x3f, 0x26, 0x5d, - 0xfa, 0x65, 0x85, 0xdc, 0x8f, 0xf3, 0x6f, 0xbd, 0x0f, 0xe7, 0x25, 0xa7, 0x66, 0x87, 0x27, 0xad, - 0xee, 0xb2, 0x44, 0x96, 0x47, 0xf7, 0x26, 0x50, 0xf0, 0x43, 0x5a, 0xd2, 0xcc, 0x41, 0xf4, 0x88, - 0x19, 0x07, 0x9e, 0x40, 0xc7, 0x6a, 0x73, 0x8c, 0xa7, 0xce, 0x2d, 0x31, 0x54, 0xcc, 0x2f, 0x00, - 0xcc, 0x80, 0xfa, 0x4e, 0xe0, 0x08, 0x62, 0x75, 0x6f, 0xbd, 0xb7, 0x46, 0x61, 0x14, 0xe4, 0x24, - 0x42, 0x39, 0xe1, 0xd8, 0x3b, 0x40, 0xdd, 0x49, 0xf5, 0x9b, 0xd7, 0x71, 0x0d, 0x91, 0xa4, 0x83, - 0xef, 0xc3, 0xf9, 0x62, 0x24, 0xa6, 0x95, 0x98, 0xc9, 0x58, 0x90, 0x11, 0x93, 0xc6, 0x74, 0x39, - 0x1f, 0xd4, 0x46, 0xb2, 0x3f, 0x16, 0xf7, 0x7d, 0xc7, 0xf8, 0x08, 0x9a, 0xf8, 0xb1, 0xcf, 0x43, - 0xb6, 0x06, 0xad, 0x84, 0x84, 0x17, 0xab, 0xed, 0xf4, 0x5c, 0x61, 0x55, 0x0b, 0xc9, 0xf2, 0x8c, - 0xc8, 0xe0, 0xb0, 0x94, 0x9b, 0xa8, 0xc7, 0xbe, 0xfb, 0x24, 0x15, 0xec, 0x13, 0x58, 0x0e, 0x23, - 0xa1, 0x94, 0xd2, 0x4c, 0x0f, 0xd1, 0x63, 0x50, 0xeb, 0xeb, 0x9c, 0xd2, 0xa1, 0xbc, 0xc5, 0x21, - 0xea, 0x4f, 0x2f, 0x9c, 0xaa, 0x1b, 0x3f, 0x80, 0x8b, 0x39, 0xc5, 0x9e, 0xb0, 0x03, 0xdf, 0xb1, - 0xa2, 0x63, 0xda, 0x4d, 0x66, 0xfa, 0x8e, 0x5f, 0xa5, 0xef, 0x3d, 0xea, 0xfb, 0xc7, 0x35, 0xe8, - 0x7d, 0xee, 0x6f, 0xa5, 0xa1, 0xe7, 0xa2, 0x85, 0xff, 0x4c, 0x1a, 0x60, 0x69, 0xf8, 0x2a, 0x65, - 0xc3, 0xb7, 0x0a, 0x7d, 0xf5, 0x15, 0x54, 0x00, 0x69, 0xb6, 0x54, 0x9c, 0x45, 0xc2, 0x37, 0x03, - 0x4f, 0xda, 0xac, 0x6f, 0xc3, 0xf9, 0x94, 0x66, 0x2e, 0x29, 0xc7, 0xc2, 0x3e, 0x34, 0x5f, 0x70, - 0x64, 0x62, 0x92, 0x10, 0x9b, 0x22, 0x19, 0x19, 0xb0, 0x6b, 0xd0, 0x2e, 0x9a, 0x67, 0xd6, 0x17, - 0x72, 0x42, 0x1a, 0x49, 0xe0, 0x9b, 0x4e, 0x36, 0x64, 0xb5, 0xf7, 0xa3, 0xdd, 0xee, 0x05, 0xc5, - 0x4c, 0xd0, 0xa8, 0xfc, 0x16, 0x2c, 0x4f, 0x51, 0xd2, 0x28, 0xa4, 0x9b, 0x76, 0xbb, 0x10, 0xe3, - 0xf4, 0xf4, 0xcb, 0x55, 0x1c, 0x8f, 0xdc, 0x27, 0x97, 0x82, 0x69, 0x68, 0x66, 0x68, 0x46, 0x7e, - 0x10, 0x09, 0xa5, 0xbe, 0x68, 0x68, 0xa8, 0x7e, 0xe9, 0x11, 0x9c, 0x5b, 0xd4, 0xcb, 0x82, 0xcd, - 0x6e, 0xa5, 0xbc, 0xd9, 0xcd, 0x1c, 0xf7, 0x8a, 0x8d, 0xef, 0x4f, 0x2b, 0xd0, 0x7e, 0x90, 0x3e, - 0x7f, 0x7e, 0x2c, 0xcd, 0x11, 0xeb, 0x40, 0xe5, 0x11, 0xf5, 0x52, 0xe5, 0x95, 0x47, 0xe8, 0x1d, - 0xef, 0x1e, 0xa2, 0x69, 0xa4, 0x4e, 0x74, 0xae, 0x6a, 0x78, 0x50, 0xdc, 0x3d, 0xdc, 0x3f, 0xc1, - 0x28, 0x48, 0x34, 0x1e, 0x7f, 0xee, 0xa5, 0xae, 0x87, 0x3e, 0x93, 0x5a, 0xff, 0x79, 0x1d, 0x8f, - 0x5e, 0xdb, 0x43, 0xa9, 0x2f, 0x0f, 0xa2, 0x60, 0x22, 0x35, 0x5a, 0x59, 0xdd, 0x05, 0x18, 0xe3, - 0xef, 0x6b, 0x50, 0xff, 0x34, 0x70, 0x7d, 0x19, 0xb6, 0xf0, 0xa4, 0x63, 0x2c, 0x3d, 0xd4, 0x56, - 0x24, 0x3c, 0xf4, 0x80, 0x11, 0x85, 0x8a, 0xe1, 0xc9, 0x93, 0x35, 0xa1, 0xec, 0x40, 0xa2, 0x8a, - 0xc3, 0x75, 0x65, 0xe1, 0xe1, 0x3a, 0x3f, 0xfb, 0xd6, 0x5f, 0x76, 0xf6, 0xd5, 0x3d, 0x31, 0x44, - 0x55, 0xf5, 0x1d, 0xe5, 0xe3, 0x4f, 0x9b, 0x06, 0x31, 0x4c, 0x36, 0x03, 0xdf, 0x61, 0xdf, 0x00, - 0x88, 0xdc, 0xd1, 0x58, 0x51, 0x36, 0xe7, 0xe3, 0x11, 0x84, 0x25, 0x52, 0x0e, 0x6f, 0xa8, 0x20, - 0x97, 0xda, 0x33, 0xcc, 0x03, 0xe4, 0x92, 0x9c, 0x47, 0x2b, 0x3b, 0x36, 0x2f, 0x0e, 0x8f, 0x5d, - 0x98, 0x0a, 0x8f, 0x11, 0x77, 0x69, 0xbe, 0x57, 0x00, 0x3d, 0x87, 0xb1, 0x19, 0xf8, 0x66, 0x98, - 0x85, 0x77, 0x34, 0x84, 0x7c, 0xee, 0xef, 0x1e, 0xa2, 0x05, 0x75, 0x63, 0x53, 0x45, 0x89, 0xd4, - 0x99, 0xab, 0x74, 0xc4, 0x5e, 0x81, 0xce, 0x0f, 0x03, 0xd7, 0x37, 0x27, 0x56, 0x68, 0x26, 0x96, - 0x0c, 0xa3, 0x36, 0x38, 0x20, 0x6c, 0xc7, 0x0a, 0xf7, 0xad, 0x11, 0xb9, 0x48, 0x2a, 0xee, 0x84, - 0x8b, 0xa4, 0x2d, 0x09, 0x14, 0x08, 0xc5, 0x7b, 0x19, 0x74, 0xea, 0x82, 0xa2, 0x52, 0x1d, 0x29, - 0x7b, 0x04, 0x20, 0x47, 0x8d, 0x7f, 0xad, 0x82, 0xb6, 0xe1, 0x27, 0x2e, 0xc9, 0xf3, 0x02, 0x34, - 0x23, 0x3a, 0x62, 0x2b, 0x69, 0xaa, 0x5a, 0x2e, 0xb1, 0xea, 0x0b, 0x24, 0x36, 0x25, 0x89, 0xda, - 0xa9, 0x25, 0x51, 0x3f, 0x49, 0x12, 0xd3, 0x5c, 0x6b, 0x9c, 0xc8, 0xb5, 0xb9, 0xc0, 0xc4, 0xd7, - 0x21, 0xc6, 0x59, 0x49, 0x68, 0x2f, 0x93, 0x84, 0x3e, 0x2b, 0x09, 0xe3, 0xaf, 0x6a, 0xa0, 0x3d, - 0x14, 0xc3, 0xe4, 0x57, 0x8b, 0xe7, 0x97, 0x65, 0xf1, 0x18, 0xff, 0x51, 0x03, 0x9d, 0xe3, 0x0c, - 0xbf, 0x46, 0x99, 0xdd, 0x01, 0x20, 0x59, 0x9c, 0x2c, 0x38, 0x92, 0x97, 0x8c, 0x7d, 0x7d, 0x00, - 0x6d, 0x29, 0x13, 0xd9, 0xa2, 0xf1, 0x82, 0x16, 0x52, 0x70, 0xfb, 0xf3, 0xf2, 0x6e, 0x9e, 0x5a, - 0xde, 0xad, 0xd7, 0x96, 0xb7, 0xf6, 0x55, 0xc8, 0x5b, 0x3f, 0x51, 0xde, 0xf0, 0x32, 0x79, 0xb7, - 0x5f, 0x26, 0xef, 0xce, 0x9c, 0xbc, 0x7f, 0x5c, 0x83, 0x2e, 0xc9, 0x7b, 0x4f, 0x4c, 0xbe, 0x9c, - 0x51, 0x9c, 0x11, 0x52, 0xed, 0x55, 0x85, 0x54, 0x3f, 0xb5, 0x90, 0x1a, 0xaf, 0x2d, 0xa4, 0xe6, - 0x57, 0x21, 0xa4, 0xd6, 0x89, 0x42, 0xd2, 0x5e, 0x26, 0x24, 0xfd, 0xd5, 0x17, 0x65, 0x2e, 0xa4, - 0x2f, 0xbd, 0x73, 0xfd, 0x4a, 0x48, 0x5f, 0x91, 0x90, 0x60, 0x4e, 0x48, 0xe8, 0x59, 0x7c, 0xe9, - 0x45, 0xf4, 0x75, 0x78, 0x16, 0x27, 0x32, 0xbb, 0xf1, 0x55, 0x30, 0xbb, 0x79, 0x22, 0xb3, 0x5b, - 0x2f, 0x63, 0xf6, 0x6b, 0x78, 0x16, 0x7f, 0x5d, 0x03, 0xd8, 0x73, 0xfd, 0x91, 0x27, 0x7e, 0xe5, - 0x5b, 0xfc, 0xd2, 0xf8, 0x16, 0x7f, 0x57, 0x05, 0x6d, 0xc7, 0x8a, 0x0e, 0x7f, 0xe1, 0x56, 0xc8, - 0x5b, 0xd0, 0x0a, 0xfc, 0xf2, 0x7a, 0x28, 0xd3, 0x35, 0x03, 0xff, 0x17, 0x42, 0xe5, 0x7f, 0xd4, - 0x00, 0x7d, 0x4b, 0x38, 0x69, 0x48, 0xec, 0x9b, 0x62, 0x43, 0xe5, 0xd4, 0x6c, 0xa8, 0xbe, 0xb6, - 0xce, 0xd5, 0x5e, 0x4f, 0xe7, 0xa6, 0xf9, 0x52, 0x7f, 0x19, 0x5f, 0x1a, 0x2f, 0xe3, 0x4b, 0x73, - 0xee, 0xb8, 0xf7, 0x10, 0xce, 0x4e, 0xc5, 0x43, 0x2c, 0x79, 0xa9, 0xd6, 0xa2, 0x20, 0xdb, 0x15, - 0x39, 0xde, 0x47, 0x81, 0x33, 0x15, 0x12, 0x91, 0x57, 0x6d, 0x7c, 0x39, 0x98, 0x05, 0xb1, 0xb7, - 0xa1, 0xe7, 0x20, 0x93, 0x29, 0xcc, 0x43, 0x01, 0x5b, 0x8d, 0xe2, 0x0f, 0x1d, 0x82, 0x6e, 0x06, - 0x1e, 0x45, 0x21, 0x3e, 0x82, 0xa5, 0x82, 0x2a, 0xc9, 0x6f, 0x6e, 0x17, 0x06, 0x29, 0xb3, 0x86, - 0x72, 0x37, 0x9d, 0xf6, 0x7d, 0xe1, 0x95, 0x7d, 0xdf, 0xf6, 0x29, 0x76, 0xec, 0xdb, 0x70, 0x36, - 0xbb, 0xc6, 0x53, 0x61, 0x4d, 0x92, 0x60, 0x87, 0xd6, 0x59, 0x5f, 0xdd, 0xdc, 0x51, 0x50, 0x93, - 0x44, 0xf4, 0x31, 0x9c, 0x2b, 0x91, 0xe3, 0x22, 0x93, 0xf4, 0xdd, 0x39, 0x5d, 0x59, 0xce, 0xdb, - 0x62, 0x15, 0x1b, 0x1b, 0xbf, 0x5b, 0x81, 0xd6, 0x6e, 0x14, 0x38, 0xa9, 0x9d, 0xbc, 0xa6, 0x15, - 0x9e, 0xd6, 0x90, 0xda, 0xcb, 0x34, 0xa4, 0x3e, 0xab, 0x21, 0xc6, 0xef, 0x55, 0x40, 0x57, 0x43, - 0x78, 0xb8, 0xfe, 0x35, 0x6d, 0x05, 0x2f, 0x1f, 0xc5, 0x33, 0xd0, 0x29, 0x7a, 0x79, 0xa2, 0x71, - 0x3b, 0x71, 0x85, 0x55, 0x5f, 0x6b, 0x85, 0x19, 0x3f, 0xaa, 0x40, 0x97, 0x02, 0xbd, 0x0f, 0x52, - 0x5f, 0xea, 0xf0, 0xe2, 0x58, 0xe7, 0x0a, 0xd4, 0x23, 0x91, 0x64, 0x39, 0x18, 0x1d, 0xf9, 0x99, - 0xcd, 0xc0, 0xdb, 0x12, 0x43, 0x4e, 0x18, 0x64, 0x82, 0x15, 0x8d, 0xe2, 0x45, 0x59, 0x20, 0x08, - 0xc7, 0x59, 0x85, 0x56, 0x64, 0x4d, 0xe2, 0x2c, 0x0b, 0x44, 0xd6, 0x18, 0x83, 0x3a, 0xad, 0x94, - 0x06, 0xad, 0x14, 0x2a, 0x1b, 0x1b, 0x70, 0xfe, 0xfe, 0x51, 0x22, 0x22, 0xdf, 0xa2, 0x15, 0xb3, - 0x8e, 0xfa, 0x46, 0xc1, 0xdd, 0x8c, 0xb8, 0x52, 0x10, 0xe3, 0x80, 0xcb, 0x39, 0x6e, 0xb2, 0x62, - 0xdc, 0x80, 0xf6, 0xd0, 0xf5, 0x84, 0x19, 0x0c, 0x87, 0xb1, 0x48, 0xf0, 0xeb, 0xb2, 0x44, 0xd3, - 0xaa, 0x71, 0x55, 0x33, 0x7e, 0x52, 0x87, 0x4e, 0xf6, 0x29, 0xca, 0x01, 0x5a, 0x3c, 0xfd, 0xcb, - 0xa0, 0x53, 0x6f, 0xb1, 0xfb, 0x5c, 0x10, 0x0f, 0x6a, 0x5c, 0x43, 0x00, 0x25, 0x6d, 0x6c, 0xc0, - 0x72, 0xe9, 0x53, 0x66, 0x12, 0x24, 0x96, 0xa7, 0xd8, 0x50, 0xba, 0x69, 0x2e, 0x91, 0xf0, 0x25, - 0xac, 0x7c, 0x4e, 0xe5, 0x7d, 0xa4, 0x46, 0xf6, 0xe6, 0xa1, 0xdd, 0x39, 0xf6, 0x22, 0x86, 0x7d, - 0x0f, 0x96, 0x70, 0xb6, 0xeb, 0x72, 0x55, 0xd2, 0x7c, 0xe5, 0x6e, 0x73, 0xad, 0xf8, 0xc4, 0x42, - 0x9e, 0xf1, 0xae, 0x3f, 0xc5, 0xc2, 0x37, 0x01, 0xec, 0x48, 0xe0, 0x82, 0x8d, 0x9f, 0x78, 0x64, - 0x11, 0x75, 0xae, 0x4b, 0xc8, 0xde, 0x13, 0x2f, 0x9f, 0x69, 0xee, 0x2a, 0xe8, 0x72, 0xa6, 0xa4, - 0xe8, 0xb7, 0xa1, 0x1d, 0x44, 0xee, 0xc8, 0xf5, 0x65, 0x20, 0x5a, 0x5b, 0x30, 0x5a, 0x90, 0x04, - 0x14, 0x96, 0x36, 0xa0, 0x29, 0x15, 0x75, 0xc1, 0x5d, 0x84, 0xc2, 0x30, 0x0e, 0xbd, 0xfd, 0x03, - 0x34, 0x70, 0x94, 0x66, 0xb9, 0x19, 0x78, 0xca, 0xac, 0xdd, 0x9a, 0x9f, 0x16, 0xca, 0x67, 0x6d, - 0x9a, 0x58, 0x86, 0xa2, 0x67, 0x7a, 0x60, 0x37, 0x61, 0x29, 0x4e, 0x22, 0xd7, 0x4e, 0x70, 0x8a, - 0xe6, 0x24, 0x70, 0x04, 0xf9, 0x13, 0x1a, 0xef, 0x4a, 0xf0, 0xde, 0x13, 0x6f, 0x27, 0x70, 0xc4, - 0xa5, 0x0d, 0x38, 0xbb, 0xa0, 0xbb, 0x57, 0xba, 0x80, 0xb5, 0x01, 0xf6, 0x92, 0x48, 0x58, 0x13, - 0x52, 0x9e, 0x77, 0xa0, 0x95, 0x1c, 0x78, 0x74, 0xbb, 0x5a, 0x59, 0x78, 0xbb, 0xda, 0x4c, 0x0e, - 0x90, 0x4b, 0x25, 0x75, 0xac, 0xd2, 0x3d, 0xa7, 0xaa, 0xe1, 0x87, 0x3c, 0x77, 0xe2, 0x26, 0x2a, - 0x69, 0x52, 0x56, 0x8c, 0x0f, 0x41, 0xa7, 0x1e, 0xe8, 0x1b, 0xb9, 0x5f, 0x59, 0x39, 0xd1, 0xaf, - 0x34, 0xde, 0x03, 0xfd, 0x37, 0x71, 0x98, 0xd4, 0xe8, 0x1a, 0xb4, 0xe9, 0x06, 0xde, 0x3c, 0xf0, - 0x02, 0xfb, 0x30, 0xbb, 0x19, 0x26, 0xd0, 0x3d, 0x84, 0x18, 0x00, 0xda, 0x63, 0xdf, 0x0d, 0xfc, - 0x0d, 0xcf, 0x33, 0xfe, 0xb0, 0x0e, 0xfa, 0xf7, 0xad, 0x78, 0x4c, 0x56, 0x82, 0xad, 0x40, 0xfb, - 0x91, 0x10, 0x0e, 0x02, 0x76, 0xac, 0x50, 0x65, 0x67, 0x95, 0x41, 0xec, 0x12, 0x68, 0xdf, 0x97, - 0x9e, 0xcc, 0x67, 0xea, 0xce, 0x33, 0xaf, 0x67, 0xad, 0xe9, 0x86, 0x5f, 0x64, 0x89, 0x40, 0x65, - 0x10, 0xbb, 0x05, 0x7d, 0xac, 0x52, 0x0e, 0x14, 0xea, 0xa0, 0xf0, 0x62, 0xb5, 0xd3, 0xcf, 0xc1, - 0xd9, 0x2d, 0x00, 0xf4, 0x35, 0x28, 0x77, 0x20, 0x5e, 0xe0, 0x6d, 0x95, 0xb0, 0xec, 0x2a, 0xc0, - 0xa7, 0xb9, 0x81, 0xcd, 0x76, 0xfe, 0x02, 0xc2, 0xde, 0x86, 0xae, 0xaa, 0x71, 0x31, 0xdc, 0x54, - 0x37, 0xce, 0x0d, 0x3e, 0x0d, 0x64, 0xf7, 0x61, 0x99, 0xbf, 0x72, 0xe6, 0xe7, 0x1c, 0x08, 0x37, - 0x0f, 0xba, 0x67, 0x75, 0xd2, 0x50, 0x39, 0xc7, 0x2d, 0x37, 0x26, 0x7f, 0xec, 0x45, 0x1e, 0x08, - 0x7c, 0x55, 0x1e, 0x48, 0xfb, 0x74, 0x1e, 0x48, 0xe7, 0x54, 0x1e, 0x88, 0xf1, 0xf3, 0x1a, 0x74, - 0xd4, 0xe6, 0x4a, 0x9b, 0xcf, 0x94, 0xf0, 0x2b, 0x27, 0x0b, 0xbf, 0x7a, 0x3a, 0xe1, 0xd7, 0x4e, - 0x25, 0xfc, 0xfa, 0x89, 0xc2, 0x5f, 0x28, 0xb6, 0xc6, 0x2b, 0x8b, 0xed, 0x65, 0x3a, 0x74, 0x15, - 0x60, 0x2f, 0xf7, 0x25, 0x95, 0x02, 0x95, 0x20, 0x53, 0x62, 0xd7, 0x4e, 0x25, 0x76, 0xfd, 0xab, - 0x12, 0x3b, 0x9c, 0x4e, 0xec, 0xed, 0xd3, 0x89, 0x7d, 0x0f, 0x80, 0x76, 0x0f, 0x29, 0xf3, 0x85, - 0xdc, 0xad, 0xbc, 0x2a, 0x77, 0x8d, 0xff, 0xa9, 0x00, 0xec, 0x59, 0x93, 0x50, 0x3a, 0x1f, 0xec, - 0xbb, 0xd0, 0x8e, 0xa9, 0x26, 0xef, 0x5e, 0x64, 0xf6, 0x7f, 0x69, 0x77, 0x2b, 0x48, 0x55, 0x11, - 0x87, 0xc6, 0x21, 0xce, 0xcb, 0xe4, 0xed, 0xcb, 0x1e, 0xf2, 0xfc, 0x8b, 0x46, 0x46, 0x40, 0xd7, - 0xde, 0x37, 0xa0, 0xa7, 0x08, 0x42, 0x11, 0xd9, 0xc2, 0x97, 0x76, 0xb6, 0xc2, 0xbb, 0x12, 0xba, - 0x2b, 0x81, 0xec, 0x83, 0x9c, 0xcc, 0x0e, 0xbc, 0x74, 0xb2, 0x50, 0xdb, 0x54, 0x93, 0x4d, 0x49, - 0x60, 0xac, 0x67, 0x53, 0xa1, 0x81, 0x68, 0x50, 0xc7, 0xef, 0xf5, 0xcf, 0xb0, 0x36, 0xb4, 0x54, - 0xaf, 0xfd, 0x0a, 0xeb, 0x82, 0x4e, 0x49, 0xc8, 0x84, 0xab, 0x1a, 0x7f, 0x72, 0x16, 0xda, 0xdb, - 0x7e, 0x9c, 0x44, 0xa9, 0x14, 0x62, 0x91, 0x6b, 0xdb, 0xa0, 0x5c, 0x5b, 0x95, 0x80, 0x23, 0xa7, - 0x41, 0x09, 0x38, 0x37, 0xa1, 0x6e, 0xf9, 0x89, 0xab, 0x1c, 0xcd, 0x52, 0x42, 0x77, 0x16, 0xda, - 0xe3, 0x84, 0x67, 0xb7, 0xa1, 0xa5, 0xb2, 0xbf, 0x55, 0x72, 0xe5, 0xc2, 0xd4, 0xf1, 0x8c, 0x86, - 0xad, 0x81, 0xe6, 0xa8, 0xb4, 0x74, 0xb5, 0x48, 0x4a, 0x5d, 0x67, 0x09, 0xeb, 0x3c, 0xa7, 0x61, - 0xd7, 0xa1, 0x66, 0x8d, 0xe4, 0x7a, 0xa0, 0x84, 0x98, 0x8c, 0x94, 0x92, 0x79, 0x39, 0xe2, 0x98, - 0x01, 0x75, 0x74, 0x6f, 0x69, 0x4d, 0xd0, 0x36, 0x98, 0xd1, 0xc8, 0x51, 0x22, 0x8e, 0xdd, 0x51, - 0xa7, 0x50, 0x22, 0xd4, 0x66, 0xbf, 0x9b, 0x5d, 0xfd, 0xc8, 0xd3, 0xe8, 0xa7, 0xaa, 0x41, 0x2c, - 0x26, 0xae, 0x6c, 0xa0, 0xcf, 0x36, 0xc8, 0xc2, 0x67, 0x5c, 0x8b, 0xb3, 0x40, 0xda, 0x5d, 0x68, - 0xc7, 0x14, 0xe7, 0x91, 0x4d, 0x20, 0xcb, 0x02, 0xc8, 0x9b, 0xe4, 0x41, 0x20, 0x0e, 0x71, 0x11, - 0x10, 0xba, 0x03, 0xfa, 0xc4, 0x8a, 0x0e, 0x65, 0xa3, 0xf6, 0xec, 0x77, 0xb2, 0x20, 0x04, 0xd7, - 0x26, 0x59, 0x38, 0x62, 0x1d, 0x40, 0x2e, 0x2c, 0x6a, 0xd1, 0x99, 0x65, 0x79, 0x7e, 0xf0, 0xe6, - 0xba, 0x93, 0x9f, 0xc1, 0xdf, 0x85, 0x56, 0x28, 0xcf, 0x1d, 0x94, 0x39, 0xd6, 0x5e, 0x5f, 0x2e, - 0x1a, 0xa8, 0x03, 0x09, 0xcf, 0x28, 0xd8, 0x77, 0xa0, 0x27, 0x53, 0x35, 0x86, 0xca, 0x4d, 0xa7, - 0x6c, 0xb2, 0xa9, 0xac, 0xe4, 0x29, 0x2f, 0x9e, 0x77, 0x93, 0x29, 0xa7, 0xfe, 0x63, 0xe8, 0x0a, - 0xe5, 0x45, 0x99, 0xb1, 0x6d, 0xf9, 0x83, 0x3e, 0x35, 0xbf, 0xb0, 0xd8, 0xc9, 0xe2, 0x1d, 0x51, - 0x76, 0x89, 0x57, 0xa1, 0xa9, 0xd2, 0x87, 0x96, 0xa9, 0x55, 0xe9, 0xb5, 0x8d, 0xbc, 0xed, 0xe6, - 0x0a, 0xcf, 0xee, 0xcd, 0xe4, 0x21, 0xa0, 0x1b, 0xc5, 0xb2, 0xd4, 0xa0, 0xc5, 0xc9, 0x05, 0x53, - 0x19, 0x0a, 0x9f, 0x89, 0x63, 0xe4, 0x65, 0x91, 0xbf, 0x31, 0x38, 0x3b, 0xcb, 0xcb, 0x3c, 0x79, - 0x83, 0xeb, 0x79, 0xde, 0x06, 0x1a, 0xa4, 0x72, 0x3e, 0x89, 0xbc, 0x92, 0x3f, 0x47, 0x4d, 0xdf, - 0x58, 0xd0, 0x54, 0xde, 0xcc, 0xf3, 0xa5, 0x70, 0x26, 0x2d, 0xe5, 0x3d, 0xd0, 0x82, 0xc8, 0xa1, - 0x34, 0xb1, 0xc1, 0x79, 0x5a, 0xf1, 0xcb, 0x2a, 0xdb, 0x4b, 0xa6, 0xd5, 0x93, 0x21, 0x6b, 0x05, - 0xb2, 0xc2, 0x6e, 0x43, 0x27, 0x8c, 0x82, 0x1f, 0x0a, 0x3b, 0x91, 0xce, 0xf2, 0x85, 0xf9, 0x74, - 0x7c, 0x85, 0x27, 0xdf, 0xb9, 0x70, 0x86, 0x2f, 0xbe, 0xd0, 0x19, 0x5e, 0xc9, 0xdc, 0xbf, 0xc1, - 0x7c, 0xee, 0x03, 0x21, 0xb0, 0x17, 0xe5, 0x38, 0xbe, 0x31, 0xdf, 0x8b, 0x72, 0x22, 0x07, 0xd0, - 0x72, 0xe3, 0x07, 0x6e, 0x14, 0x27, 0x83, 0x4b, 0xd9, 0xa6, 0x43, 0x55, 0x74, 0x3b, 0xdd, 0xf8, - 0xa1, 0x15, 0x27, 0x83, 0xcb, 0xd9, 0x8b, 0x0a, 0xac, 0x21, 0xcf, 0x65, 0x98, 0x80, 0xf4, 0xf7, - 0xca, 0x2c, 0xcf, 0xf3, 0x2b, 0x3d, 0x15, 0xef, 0x21, 0xfd, 0xfd, 0x04, 0x96, 0x64, 0x9b, 0x62, - 0x49, 0xbe, 0x39, 0xab, 0x93, 0x53, 0x77, 0x43, 0xbc, 0x1b, 0x4d, 0x5d, 0x15, 0xe5, 0x1d, 0xa0, - 0xc9, 0x92, 0x1d, 0x5c, 0x5d, 0xd8, 0x41, 0x6e, 0xdc, 0x64, 0x07, 0xf9, 0x35, 0xc6, 0x2d, 0x68, - 0xaa, 0x9c, 0xb7, 0x6b, 0x73, 0x46, 0x4b, 0x65, 0x77, 0x72, 0x45, 0xc1, 0xbe, 0x01, 0x2d, 0x4a, - 0x78, 0x0a, 0xc2, 0xc1, 0xca, 0xac, 0x12, 0xcb, 0xbc, 0x26, 0xde, 0xf4, 0x64, 0x7e, 0xd3, 0xbb, - 0xd0, 0xca, 0xe2, 0x09, 0xd7, 0x67, 0x17, 0xa6, 0xda, 0xdb, 0x79, 0x46, 0xc1, 0x6e, 0x40, 0x63, - 0x82, 0x26, 0x7d, 0x60, 0xcc, 0x1a, 0x43, 0x69, 0xe9, 0x25, 0x96, 0x0c, 0x11, 0x1d, 0x13, 0xe4, - 0xea, 0x7b, 0x6b, 0xce, 0x10, 0xe5, 0x67, 0x08, 0x0e, 0x71, 0x71, 0x9e, 0xf8, 0x1d, 0xb8, 0x54, - 0xce, 0x65, 0xca, 0x12, 0x9d, 0xd4, 0xf9, 0xef, 0x6d, 0xea, 0xe5, 0xfa, 0x02, 0x05, 0x9f, 0x4e, - 0x89, 0xe2, 0x17, 0xc3, 0x17, 0xe4, 0x4a, 0xdd, 0xcd, 0x37, 0x4c, 0xb4, 0x2b, 0x83, 0x1b, 0x73, - 0xc3, 0xca, 0xb7, 0xdc, 0x6c, 0x1b, 0xa5, 0x9d, 0xfa, 0x23, 0xe8, 0x0c, 0xd3, 0xe7, 0xcf, 0x8f, - 0x55, 0x18, 0x62, 0x70, 0x93, 0xda, 0x95, 0xce, 0xba, 0xa5, 0xcc, 0x1c, 0xde, 0x1e, 0x96, 0xd2, - 0x74, 0x2e, 0x42, 0xcb, 0xf6, 0x4d, 0xcb, 0x71, 0xa2, 0xc1, 0x3b, 0x32, 0x33, 0xc7, 0xf6, 0x37, - 0x1c, 0x87, 0x52, 0x9c, 0x82, 0x50, 0xd0, 0xd3, 0x14, 0xd3, 0x75, 0x06, 0xab, 0x72, 0xeb, 0xce, - 0x40, 0xdb, 0x0e, 0x3d, 0x7a, 0xb3, 0x22, 0xcb, 0xf3, 0x84, 0x87, 0x04, 0xdf, 0x50, 0x8f, 0xde, - 0x14, 0x68, 0xdb, 0x61, 0xd7, 0xa1, 0x33, 0xb1, 0x8e, 0xcc, 0x0c, 0x32, 0xb8, 0x25, 0x5f, 0x14, - 0x4d, 0xac, 0xa3, 0x5d, 0x05, 0x42, 0x35, 0x97, 0x09, 0xc9, 0xa4, 0x6c, 0xef, 0xce, 0xaa, 0x79, - 0x1e, 0x81, 0xe1, 0xba, 0x9b, 0x07, 0x63, 0xc8, 0x1c, 0x91, 0x11, 0x36, 0xbd, 0xf5, 0xc1, 0x7b, - 0xf3, 0xe6, 0x48, 0x85, 0x8e, 0xd0, 0x1c, 0x65, 0x51, 0xa4, 0x75, 0x00, 0x69, 0xad, 0x49, 0xd8, - 0xb7, 0x67, 0xdb, 0xe4, 0x67, 0x39, 0x2e, 0xb3, 0x71, 0x49, 0xd4, 0xeb, 0x00, 0x74, 0xaa, 0x94, - 0x6d, 0xd6, 0x66, 0xdb, 0xe4, 0x47, 0x39, 0xae, 0x3f, 0xcd, 0x4f, 0x75, 0x77, 0x40, 0x4f, 0xf1, - 0xd0, 0x66, 0x5a, 0x9e, 0x37, 0xb8, 0x33, 0xbb, 0x06, 0xb2, 0xf3, 0x1c, 0xd7, 0x52, 0x55, 0xc2, - 0x8f, 0x50, 0x14, 0x9a, 0xdc, 0xb8, 0xc1, 0xfb, 0xb3, 0x1f, 0xc9, 0x0f, 0x7d, 0x5c, 0x1f, 0xe7, - 0xe7, 0xbf, 0x8f, 0xa1, 0x9b, 0x85, 0x50, 0x65, 0xb3, 0x0f, 0x66, 0xb7, 0x8e, 0xf2, 0x79, 0x80, - 0x67, 0xcf, 0xba, 0x64, 0xe3, 0xbb, 0xd0, 0x96, 0x1c, 0x97, 0x4d, 0xd7, 0x67, 0x15, 0xac, 0x70, - 0x2a, 0xb9, 0x14, 0x8d, 0x6c, 0x76, 0x03, 0x1a, 0x56, 0x18, 0x7a, 0xc7, 0x83, 0x0f, 0x67, 0x57, - 0xd5, 0x06, 0x82, 0xb9, 0xc4, 0xa2, 0x1e, 0x4e, 0x52, 0x2f, 0x71, 0xb3, 0xd4, 0xe2, 0x6f, 0xce, - 0xea, 0x61, 0xe9, 0xe9, 0x02, 0x6f, 0x4f, 0x4a, 0x6f, 0x2c, 0xde, 0x03, 0x2d, 0x0c, 0xe2, 0xc4, - 0x74, 0x26, 0xde, 0xe0, 0xee, 0xdc, 0xee, 0x2b, 0xf3, 0x57, 0x79, 0x2b, 0x94, 0x05, 0xe3, 0x2e, - 0x74, 0x36, 0xe8, 0xb1, 0xa7, 0x1b, 0x93, 0x29, 0xbf, 0x01, 0xf5, 0x3c, 0x42, 0x98, 0xef, 0x11, - 0x44, 0xf1, 0x5c, 0x6c, 0xfb, 0xc3, 0x80, 0x13, 0xda, 0xf8, 0x8b, 0x1a, 0x34, 0xf7, 0x82, 0x34, - 0xb2, 0xc5, 0xcb, 0x33, 0xb3, 0xdf, 0xcc, 0x54, 0xc6, 0x2f, 0xb2, 0xd6, 0xa4, 0x76, 0x10, 0xba, - 0x1c, 0x7c, 0xac, 0x51, 0x50, 0x26, 0x0f, 0x3e, 0x9e, 0x83, 0x86, 0x3c, 0xd4, 0xcb, 0xdc, 0x60, - 0x59, 0xa1, 0xe5, 0x92, 0xc6, 0x63, 0x27, 0x78, 0xe6, 0xe3, 0x72, 0x69, 0x50, 0x6a, 0x2d, 0x64, - 0xa0, 0x6d, 0x87, 0x9e, 0xb7, 0x64, 0x04, 0xb4, 0x1e, 0x65, 0x24, 0xa8, 0x93, 0x01, 0x69, 0x55, - 0x66, 0x81, 0xcd, 0xd6, 0x0b, 0x02, 0x9b, 0xb7, 0x20, 0x4f, 0x17, 0x57, 0x0e, 0xdc, 0x8b, 0xd3, - 0xc9, 0xd7, 0x41, 0xcf, 0x9f, 0x02, 0x2b, 0xe7, 0xed, 0xdc, 0x5a, 0xf1, 0x38, 0x78, 0x3f, 0x2b, - 0xf1, 0x82, 0x6c, 0x41, 0xc4, 0x33, 0x8c, 0x82, 0x03, 0x15, 0x9c, 0x82, 0x57, 0x89, 0x78, 0xee, - 0x62, 0xbb, 0x2c, 0x8e, 0xeb, 0xc6, 0xa6, 0x1d, 0xf8, 0x71, 0xa2, 0xa2, 0x42, 0x2d, 0x37, 0xde, - 0xc4, 0xaa, 0xf1, 0xdb, 0xa0, 0xe1, 0x91, 0x0b, 0x45, 0xc8, 0x18, 0xd4, 0x27, 0x76, 0x98, 0x2a, - 0x77, 0x9c, 0xca, 0xea, 0xa5, 0xaf, 0x14, 0x8e, 0x7a, 0xe9, 0x4b, 0xac, 0xab, 0xc9, 0x68, 0x24, - 0x96, 0xe5, 0x1b, 0xc2, 0x63, 0x2f, 0xb0, 0x1c, 0x25, 0x90, 0xac, 0x6a, 0xfc, 0x79, 0x05, 0x96, - 0x77, 0xa3, 0xc0, 0x16, 0x71, 0xfc, 0x10, 0xf7, 0x72, 0x8b, 0x3c, 0x33, 0x06, 0x75, 0x0a, 0x2a, - 0xca, 0x27, 0x76, 0x54, 0x46, 0x65, 0x90, 0xd1, 0x9a, 0xfc, 0x18, 0x53, 0xe3, 0x3a, 0x41, 0xe8, - 0x14, 0x93, 0xa3, 0xa9, 0x61, 0xad, 0x84, 0xa6, 0x70, 0xe4, 0x0d, 0xe8, 0x15, 0x0f, 0x30, 0xa8, - 0x07, 0xf5, 0xb6, 0x36, 0x87, 0x52, 0x2f, 0xd7, 0xa0, 0x1d, 0x09, 0x0b, 0xbd, 0x1d, 0xea, 0xa6, - 0x41, 0x34, 0x20, 0x41, 0xd8, 0x8f, 0x31, 0x86, 0xfe, 0x6e, 0x24, 0x42, 0x2b, 0x12, 0x68, 0x40, - 0x27, 0xc4, 0x95, 0x0b, 0xd0, 0xf4, 0x84, 0x3f, 0x4a, 0xc6, 0x6a, 0xbc, 0xaa, 0x96, 0xbf, 0xab, - 0xae, 0x96, 0xde, 0x55, 0x23, 0x77, 0x22, 0x61, 0xa9, 0xe7, 0xd7, 0x54, 0x46, 0x65, 0xf5, 0x53, - 0x4f, 0x05, 0x3a, 0x35, 0x2e, 0x2b, 0xc6, 0x9f, 0xd5, 0xa0, 0xad, 0x38, 0x43, 0x5f, 0x91, 0x7c, - 0xae, 0xe4, 0x7c, 0xee, 0x43, 0x2d, 0x7e, 0xe2, 0x29, 0xc6, 0x63, 0x91, 0x7d, 0x08, 0x35, 0xcf, - 0x9d, 0xa8, 0x73, 0xd0, 0xe5, 0x29, 0x73, 0x3c, 0xcd, 0x5f, 0x75, 0x9c, 0x45, 0x6a, 0x76, 0x99, - 0xcc, 0xe5, 0x91, 0x89, 0x5a, 0xa1, 0x78, 0x82, 0xa6, 0xf1, 0x08, 0x55, 0x0f, 0x99, 0x6a, 0xd9, - 0x94, 0xc3, 0x9b, 0xad, 0x97, 0x2e, 0xd7, 0x15, 0x64, 0xdb, 0x61, 0xdf, 0x04, 0x2d, 0xf6, 0xad, - 0x30, 0x1e, 0x07, 0x89, 0x3a, 0xf7, 0xb0, 0xb5, 0xe4, 0xc8, 0x5f, 0xdb, 0x7c, 0xb4, 0x7f, 0xe4, - 0xef, 0x29, 0x8c, 0xfa, 0x58, 0x4e, 0xc9, 0xbe, 0x03, 0x9d, 0x58, 0xc4, 0xb1, 0x7c, 0x09, 0x33, - 0x0c, 0xd4, 0x3a, 0x3a, 0x5f, 0x3e, 0xb3, 0x10, 0x16, 0x67, 0xad, 0x1a, 0xb7, 0xe3, 0x02, 0xc4, - 0xbe, 0x0f, 0xbd, 0xac, 0xbd, 0x17, 0x8c, 0x46, 0x22, 0x7b, 0xeb, 0x70, 0x79, 0xae, 0x87, 0x87, - 0x84, 0x2e, 0xf5, 0xd3, 0x8d, 0xcb, 0x08, 0xf6, 0x3d, 0xe8, 0x85, 0x52, 0x98, 0xa6, 0x8a, 0xc2, - 0xcb, 0x25, 0x78, 0x69, 0xca, 0x7b, 0x98, 0x12, 0x76, 0x91, 0x27, 0x5f, 0xc0, 0x63, 0xe3, 0xbf, - 0x2a, 0xd0, 0x2e, 0x8d, 0x9a, 0x5e, 0xbb, 0xc7, 0x22, 0xca, 0x22, 0xf2, 0x58, 0x46, 0xd8, 0x38, - 0x50, 0x8f, 0x44, 0x75, 0x4e, 0x65, 0x84, 0x45, 0x81, 0xba, 0xa2, 0xd1, 0x39, 0x95, 0xd1, 0x06, - 0xa9, 0x23, 0xa8, 0x7c, 0x63, 0x47, 0x42, 0xa9, 0xf3, 0x4e, 0x01, 0xdc, 0xa6, 0x00, 0x13, 0xaa, - 0xd3, 0x81, 0x15, 0x67, 0x77, 0x04, 0x79, 0x1d, 0x17, 0xdb, 0x53, 0x11, 0xe1, 0x58, 0x94, 0xf9, - 0xca, 0xaa, 0x28, 0x6b, 0x32, 0x1b, 0xcf, 0x03, 0x5f, 0x5e, 0xa8, 0x76, 0xb8, 0x86, 0x80, 0x1f, - 0x04, 0x3e, 0x35, 0x53, 0x92, 0x55, 0xf7, 0x73, 0x59, 0x15, 0x8d, 0xc3, 0x93, 0x54, 0xa0, 0x87, - 0xe5, 0xd0, 0x9d, 0x9c, 0xce, 0x5b, 0x54, 0xdf, 0x76, 0x8c, 0x7f, 0xab, 0xc0, 0xf2, 0x1c, 0xb3, - 0xd1, 0xa1, 0x41, 0x46, 0x67, 0xcf, 0x17, 0x3a, 0xbc, 0x89, 0xd5, 0x6d, 0x87, 0x10, 0xc9, 0x84, - 0x94, 0xa9, 0xaa, 0x10, 0xc9, 0x04, 0x35, 0xe9, 0x3c, 0x34, 0x93, 0x23, 0x9a, 0xad, 0x5c, 0x18, - 0x8d, 0xe4, 0x08, 0xa7, 0xb9, 0x01, 0xba, 0x17, 0x8c, 0x4c, 0x4f, 0x3c, 0x15, 0x1e, 0xf1, 0xa1, - 0xb7, 0xfe, 0xf6, 0x09, 0x52, 0x5e, 0x7b, 0x18, 0x8c, 0x1e, 0x22, 0x2d, 0xd7, 0x3c, 0x55, 0x32, - 0x3e, 0x05, 0x2d, 0x83, 0x32, 0x1d, 0x1a, 0x5b, 0xe2, 0x20, 0x1d, 0xf5, 0xcf, 0x30, 0x0d, 0xea, - 0xd8, 0xa2, 0x5f, 0xc1, 0xd2, 0x17, 0x56, 0xe4, 0xf7, 0xab, 0x88, 0xbe, 0x1f, 0x45, 0x41, 0xd4, - 0xaf, 0x61, 0x71, 0xd7, 0xf2, 0x5d, 0xbb, 0x5f, 0xc7, 0xe2, 0x03, 0x2b, 0xb1, 0xbc, 0x7e, 0xc3, - 0xf8, 0xcb, 0x06, 0x68, 0xbb, 0xea, 0xeb, 0x6c, 0x0b, 0xba, 0xf9, 0x0f, 0x07, 0x16, 0xc7, 0x66, - 0x76, 0x67, 0x0b, 0x14, 0x9b, 0xe9, 0x84, 0xa5, 0xda, 0xec, 0x6f, 0x0b, 0xaa, 0x73, 0xbf, 0x2d, - 0xb8, 0x02, 0xb5, 0x27, 0xd1, 0xf1, 0xf4, 0x2d, 0xda, 0xae, 0x67, 0xf9, 0x1c, 0xc1, 0xec, 0x03, - 0x68, 0xa3, 0xdc, 0xcd, 0x98, 0x76, 0x54, 0x15, 0xd7, 0x28, 0xff, 0x1c, 0x82, 0xe0, 0x1c, 0x90, - 0x48, 0xed, 0xba, 0x6b, 0xa0, 0xd9, 0x63, 0xd7, 0x73, 0x22, 0xe1, 0xab, 0x60, 0x31, 0x9b, 0x1f, - 0x32, 0xcf, 0x69, 0xd8, 0x77, 0x29, 0xa1, 0x3f, 0x8b, 0xc7, 0x94, 0xf3, 0x89, 0xce, 0x4f, 0x1d, - 0x79, 0x33, 0x0a, 0xbe, 0x54, 0x22, 0xa7, 0xcd, 0xa5, 0x78, 0x0d, 0xd6, 0x2a, 0xbf, 0x06, 0x93, - 0x4f, 0xd9, 0x69, 0x53, 0xd0, 0xf2, 0x83, 0x57, 0x60, 0x39, 0xec, 0x26, 0xd4, 0xfd, 0xc0, 0x11, - 0xf3, 0xc1, 0x8c, 0x6c, 0x1f, 0xe2, 0x84, 0xa7, 0x7f, 0x54, 0xa4, 0xf1, 0xd8, 0x94, 0xfb, 0x39, - 0x9a, 0x12, 0x50, 0xaf, 0x51, 0xd3, 0x78, 0xbc, 0x85, 0x3b, 0x3a, 0x2a, 0xe3, 0x0d, 0xe8, 0x65, - 0x73, 0x51, 0xcf, 0x11, 0x64, 0x1a, 0x45, 0x37, 0x83, 0xca, 0xd7, 0x08, 0x6b, 0x70, 0xd6, 0x1e, - 0x5b, 0xbe, 0x2f, 0x3c, 0xf3, 0x20, 0x1d, 0x0e, 0xb3, 0x1d, 0x40, 0xde, 0xf0, 0x2e, 0x2b, 0xd4, - 0x3d, 0xc2, 0xd0, 0x86, 0x62, 0x40, 0xd7, 0x77, 0x3d, 0xf9, 0x84, 0xcf, 0xb4, 0x7d, 0x79, 0xb7, - 0xdb, 0xe0, 0x6d, 0xdf, 0xf5, 0x28, 0x8e, 0xbb, 0xe9, 0x27, 0xec, 0x13, 0xe8, 0xa7, 0xa9, 0xeb, - 0xc4, 0x66, 0x12, 0x64, 0x7f, 0x01, 0x18, 0xf4, 0x88, 0x75, 0x25, 0x47, 0xf1, 0x71, 0xea, 0x3a, - 0xfb, 0x81, 0xfa, 0x0f, 0x40, 0x97, 0xe8, 0xb3, 0xaa, 0xf1, 0x09, 0x74, 0xca, 0xba, 0x83, 0xba, - 0x48, 0x27, 0xa8, 0xfe, 0x19, 0x06, 0xd0, 0x7c, 0x14, 0x44, 0x13, 0xcb, 0xeb, 0x57, 0xb0, 0x2c, - 0xdf, 0x48, 0xf6, 0xab, 0xac, 0x03, 0x5a, 0xe6, 0xda, 0xf7, 0x6b, 0xc6, 0xc7, 0xa0, 0x65, 0xbf, - 0x35, 0xa0, 0xf7, 0xe4, 0x81, 0x23, 0xa4, 0x63, 0x23, 0x2d, 0x93, 0x86, 0x00, 0x72, 0x6a, 0xb2, - 0xff, 0x73, 0x54, 0x8b, 0xff, 0x73, 0x18, 0xbf, 0x01, 0x9d, 0xf2, 0xe0, 0xb2, 0xd0, 0x5b, 0xa5, - 0x08, 0xbd, 0x2d, 0x68, 0x45, 0x77, 0x65, 0x51, 0x30, 0x31, 0x4b, 0x4e, 0x80, 0x86, 0x00, 0xfc, - 0x8c, 0xf1, 0xfb, 0x15, 0x68, 0x90, 0xb7, 0x4a, 0x5b, 0x0b, 0x16, 0x8a, 0xb5, 0xd3, 0xe0, 0x3a, - 0x41, 0x68, 0xa6, 0xe5, 0x3b, 0xe7, 0xea, 0x8b, 0xef, 0x9c, 0x6b, 0xd3, 0x77, 0xce, 0xa7, 0x4c, - 0x2f, 0xba, 0xf5, 0x04, 0x9a, 0xf2, 0x97, 0x28, 0x6c, 0x19, 0xba, 0x8f, 0xfd, 0x43, 0x3f, 0x78, - 0xe6, 0x4b, 0x40, 0xff, 0x0c, 0x3b, 0x0b, 0x4b, 0x19, 0xd3, 0xd5, 0xbf, 0x57, 0xfa, 0x15, 0xd6, - 0x87, 0x0e, 0x89, 0x35, 0x83, 0x54, 0xd9, 0x15, 0x18, 0xa8, 0xcd, 0x61, 0x2b, 0xf0, 0xc5, 0xa3, - 0x20, 0x71, 0x87, 0xc7, 0x19, 0xb6, 0xc6, 0x96, 0xa0, 0xbd, 0x97, 0x04, 0xe1, 0x9e, 0xf0, 0x1d, - 0xd7, 0x1f, 0xf5, 0xeb, 0xb7, 0x1e, 0x40, 0x53, 0xfe, 0xa9, 0xa5, 0xf4, 0x49, 0x09, 0xe8, 0x9f, - 0x41, 0xea, 0x2f, 0x2c, 0x37, 0x71, 0xfd, 0xd1, 0x23, 0x71, 0x94, 0x48, 0xa3, 0xf4, 0xd0, 0x8a, - 0x93, 0x7e, 0x95, 0xf5, 0x00, 0x54, 0xaf, 0xf7, 0x7d, 0xa7, 0x5f, 0xbb, 0xb7, 0xf9, 0xd3, 0x9f, - 0x5d, 0xad, 0xfc, 0xc3, 0xcf, 0xae, 0x56, 0xfe, 0xf9, 0x67, 0x57, 0xcf, 0xfc, 0xf1, 0xbf, 0x5c, - 0xad, 0xfc, 0xe0, 0x83, 0xd2, 0x7f, 0x68, 0x26, 0x56, 0x12, 0xb9, 0x47, 0xf2, 0xb6, 0x31, 0xab, - 0xf8, 0xe2, 0x4e, 0x78, 0x38, 0xba, 0x13, 0x1e, 0xdc, 0xc9, 0x74, 0xee, 0xa0, 0x49, 0xbf, 0x97, - 0xf9, 0xf0, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xc6, 0xdd, 0x8d, 0xbc, 0xdd, 0x46, 0x00, 0x00, + // 5812 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7c, 0x4b, 0x6c, 0x1e, 0x47, + 0x72, 0xb0, 0xbe, 0xf7, 0x4c, 0x7d, 0x0f, 0x7e, 0x6c, 0xbd, 0x3e, 0x4b, 0xb2, 0x44, 0x8d, 0x2d, + 0x99, 0x2b, 0x5b, 0x94, 0x4d, 0xaf, 0xfe, 0xf5, 0x1f, 0x67, 0xd7, 0x4b, 0x91, 0xd2, 0x2e, 0x6d, + 0x91, 0x66, 0x9a, 0x54, 0x8c, 0x2c, 0x82, 0x0c, 0x86, 0x33, 0xfd, 0x7d, 0xdf, 0x2c, 0xe7, 0x9b, + 0x19, 0xcd, 0x43, 0x22, 0x75, 0x0a, 0x90, 0x5c, 0x73, 0xca, 0x29, 0xc8, 0x25, 0xd8, 0x43, 0x82, + 0x1c, 0xf2, 0x40, 0x82, 0x9c, 0x82, 0xbd, 0xef, 0xde, 0x72, 0xca, 0x31, 0x08, 0x36, 0xb7, 0x3c, + 0x6e, 0x9b, 0x20, 0x97, 0x00, 0x41, 0x55, 0xf7, 0x3c, 0xbe, 0x87, 0xa8, 0x87, 0xed, 0x60, 0x17, + 0xd8, 0x5b, 0x77, 0x55, 0x75, 0x4f, 0x77, 0x55, 0x75, 0x75, 0x75, 0x75, 0xf5, 0x40, 0x2f, 0x74, + 0x43, 0xe1, 0xb9, 0xbe, 0x58, 0x0b, 0xa3, 0x20, 0x09, 0x98, 0x96, 0xd5, 0x2f, 0xdd, 0x1e, 0xb9, + 0xc9, 0x38, 0x3d, 0x5c, 0xb3, 0x83, 0xc9, 0x9d, 0x51, 0x30, 0x0a, 0xee, 0x10, 0xc1, 0x61, 0x3a, + 0xa4, 0x1a, 0x55, 0xa8, 0x24, 0x1b, 0x5e, 0x82, 0xd0, 0xb3, 0x7c, 0x55, 0x5e, 0x4a, 0xdc, 0x89, + 0x88, 0x13, 0x6b, 0x12, 0x66, 0x48, 0x2f, 0xb0, 0x8f, 0x54, 0x59, 0x4f, 0x8e, 0x15, 0x9d, 0xf1, + 0xc7, 0x55, 0x68, 0xed, 0x88, 0x38, 0xb6, 0x46, 0x82, 0x19, 0x50, 0x8b, 0x5d, 0x67, 0x50, 0x59, + 0xa9, 0xac, 0xf6, 0xd6, 0xfb, 0x6b, 0xf9, 0xb0, 0xf6, 0x13, 0x2b, 0x49, 0x63, 0x8e, 0x48, 0xa4, + 0xb1, 0x27, 0xce, 0xa0, 0x3a, 0x4b, 0xb3, 0x23, 0x92, 0x71, 0xe0, 0x70, 0x44, 0xb2, 0x3e, 0xd4, + 0x44, 0x14, 0x0d, 0x6a, 0x2b, 0x95, 0xd5, 0x0e, 0xc7, 0x22, 0x63, 0x50, 0x77, 0xac, 0xc4, 0x1a, + 0xd4, 0x09, 0x44, 0x65, 0xf6, 0x36, 0xf4, 0xc2, 0x28, 0xb0, 0x4d, 0xd7, 0x1f, 0x06, 0x26, 0x61, + 0x1b, 0x84, 0xed, 0x20, 0x74, 0xdb, 0x1f, 0x06, 0x5b, 0x48, 0x35, 0x80, 0x96, 0xe5, 0x5b, 0xde, + 0x49, 0x2c, 0x06, 0x4d, 0x42, 0x67, 0x55, 0xd6, 0x83, 0xaa, 0xeb, 0x0c, 0x5a, 0x2b, 0x95, 0xd5, + 0x3a, 0xaf, 0xba, 0x0e, 0x7e, 0x23, 0x4d, 0x5d, 0x67, 0xa0, 0xc9, 0x6f, 0x60, 0x99, 0x19, 0xd0, + 0xf1, 0x85, 0x70, 0x76, 0x83, 0x84, 0x8b, 0xd0, 0x3b, 0x19, 0xe8, 0x2b, 0x95, 0x55, 0x8d, 0x4f, + 0xc1, 0xd8, 0x25, 0xd0, 0x1c, 0x71, 0x98, 0x8e, 0x76, 0xe2, 0xd1, 0x00, 0x56, 0x2a, 0xab, 0x3a, + 0xcf, 0xeb, 0xc6, 0x23, 0xd0, 0x37, 0x03, 0xdf, 0x17, 0x76, 0x12, 0x44, 0xec, 0x1a, 0xb4, 0xb3, + 0xe9, 0x9a, 0x8a, 0x4d, 0x0d, 0x0e, 0x19, 0x68, 0xdb, 0x61, 0xef, 0xc0, 0x92, 0x9d, 0x51, 0x9b, + 0xae, 0xef, 0x88, 0x63, 0xe2, 0x53, 0x83, 0xf7, 0x72, 0xf0, 0x36, 0x42, 0x8d, 0x7f, 0xaf, 0x42, + 0x6b, 0x7f, 0x9c, 0x0e, 0x87, 0x9e, 0x60, 0x6f, 0x43, 0x57, 0x15, 0x37, 0x03, 0x6f, 0xdb, 0x39, + 0x56, 0xfd, 0x4e, 0x03, 0xd9, 0x0a, 0xb4, 0x15, 0xe0, 0xe0, 0x24, 0x14, 0xaa, 0xdb, 0x32, 0x68, + 0xba, 0x9f, 0x1d, 0xd7, 0x27, 0xf6, 0xd7, 0xf8, 0x34, 0x70, 0x86, 0xca, 0x3a, 0x26, 0x89, 0x4c, + 0x53, 0x59, 0xf4, 0xb5, 0x0d, 0xcf, 0x7d, 0x22, 0xb8, 0x18, 0x6d, 0xfa, 0x09, 0xc9, 0xa5, 0xc1, + 0xcb, 0x20, 0xb6, 0x0e, 0xe7, 0x63, 0xd9, 0xc4, 0x8c, 0x2c, 0x7f, 0x24, 0x62, 0x33, 0x75, 0xfd, + 0xe4, 0xff, 0x7d, 0x73, 0xd0, 0x5c, 0xa9, 0xad, 0xd6, 0xf9, 0x59, 0x85, 0xe4, 0x84, 0x7b, 0x44, + 0x28, 0xf6, 0x3e, 0x9c, 0x9b, 0x69, 0x23, 0x9b, 0xb4, 0x56, 0x6a, 0xab, 0x35, 0xce, 0xa6, 0x9a, + 0x6c, 0x53, 0x8b, 0xfb, 0xb0, 0x1c, 0xa5, 0x3e, 0x6a, 0xf2, 0x03, 0xd7, 0x4b, 0x44, 0xb4, 0x1f, + 0x0a, 0x9b, 0xe4, 0xdb, 0x5e, 0xbf, 0xb8, 0x46, 0xca, 0xce, 0x67, 0xd1, 0x7c, 0xbe, 0x85, 0xf1, + 0xdf, 0x55, 0xd0, 0xb6, 0xdc, 0x38, 0xb4, 0x12, 0x7b, 0xcc, 0x2e, 0x42, 0x6b, 0x98, 0xfa, 0x76, + 0x21, 0xc1, 0x26, 0x56, 0xb7, 0x1d, 0xf6, 0xeb, 0xb0, 0xe4, 0x05, 0xb6, 0xe5, 0x99, 0xb9, 0xb0, + 0x06, 0xd5, 0x95, 0xda, 0x6a, 0x7b, 0xfd, 0x6c, 0xa1, 0xe5, 0xb9, 0x32, 0xf0, 0x1e, 0xd1, 0x16, + 0xca, 0xf1, 0x6d, 0xe8, 0x47, 0x62, 0x12, 0x24, 0xa2, 0xd4, 0xbc, 0x46, 0xcd, 0x59, 0xd1, 0xfc, + 0x8b, 0xc8, 0x0a, 0x77, 0x03, 0x47, 0xf0, 0x25, 0x49, 0x5b, 0x34, 0xff, 0xa0, 0xc4, 0x4f, 0x31, + 0x32, 0x5d, 0xe7, 0xd8, 0xa4, 0x0f, 0x0c, 0xea, 0x2b, 0xb5, 0xd5, 0x46, 0xc1, 0x1c, 0x31, 0xda, + 0x76, 0x8e, 0x1f, 0x22, 0x86, 0x7d, 0x08, 0x17, 0x66, 0x9b, 0xc8, 0x5e, 0x07, 0x0d, 0x6a, 0x73, + 0x76, 0xaa, 0x0d, 0x27, 0x14, 0xbb, 0x0e, 0x9d, 0xac, 0x51, 0x82, 0x8a, 0xd4, 0x94, 0xa2, 0x8d, + 0x4b, 0x8a, 0x74, 0x11, 0x5a, 0x6e, 0x6c, 0xc6, 0xae, 0x7f, 0x44, 0x8b, 0x4b, 0xe3, 0x4d, 0x37, + 0xde, 0x77, 0xfd, 0x23, 0xf6, 0x06, 0x68, 0x91, 0xb0, 0x25, 0x46, 0x23, 0x4c, 0x2b, 0x12, 0x36, + 0xa1, 0x2e, 0x02, 0x16, 0x4d, 0x3b, 0x11, 0x6a, 0x89, 0x35, 0x23, 0x61, 0x6f, 0x26, 0xc2, 0x88, + 0xa1, 0xb1, 0x23, 0xa2, 0x91, 0xc0, 0x55, 0x86, 0x0d, 0xf7, 0x6d, 0xcb, 0x27, 0xbe, 0x6b, 0x3c, + 0xaf, 0xe3, 0x1a, 0x0f, 0xad, 0x28, 0x71, 0x2d, 0x8f, 0x14, 0x5b, 0xe3, 0x59, 0x95, 0x5d, 0x06, + 0x3d, 0x4e, 0xac, 0x28, 0xc1, 0xd9, 0x91, 0x42, 0x37, 0xb8, 0x46, 0x00, 0x5c, 0x13, 0x17, 0xa1, + 0x25, 0x7c, 0x87, 0x50, 0x75, 0x29, 0x49, 0xe1, 0x3b, 0xdb, 0xce, 0xb1, 0xf1, 0xb7, 0x15, 0xe8, + 0xee, 0xa4, 0x5e, 0xe2, 0x6e, 0x44, 0xa3, 0x54, 0x4c, 0xfc, 0x04, 0x6d, 0xc3, 0x96, 0x1b, 0x27, + 0xea, 0xcb, 0x54, 0x66, 0xab, 0xa0, 0x7f, 0x2f, 0x0a, 0xd2, 0xf0, 0xfe, 0x71, 0x98, 0x49, 0x1a, + 0xa4, 0x52, 0x21, 0x84, 0x17, 0x48, 0xf6, 0x1e, 0xb4, 0x3f, 0x8f, 0x1c, 0x11, 0xdd, 0x3b, 0x21, + 0xda, 0xda, 0x1c, 0x6d, 0x19, 0xcd, 0xae, 0x80, 0xbe, 0x2f, 0x42, 0x2b, 0xb2, 0x50, 0x05, 0xea, + 0x64, 0x50, 0x0a, 0x00, 0xce, 0x95, 0x88, 0xb7, 0x1d, 0xb5, 0xac, 0xb2, 0xaa, 0x31, 0x02, 0x7d, + 0x63, 0x34, 0x8a, 0xc4, 0xc8, 0x4a, 0xc8, 0xb8, 0x05, 0x21, 0x0d, 0xb7, 0xc6, 0xab, 0x41, 0x48, + 0x06, 0x14, 0x27, 0x20, 0xf9, 0x43, 0x65, 0x76, 0x15, 0xea, 0x62, 0xf1, 0x78, 0x08, 0xce, 0x2e, + 0x40, 0xd3, 0x0e, 0xfc, 0xa1, 0x3b, 0x52, 0x66, 0x57, 0xd5, 0x8c, 0x3f, 0xa8, 0x41, 0x83, 0x26, + 0x87, 0xec, 0x45, 0x53, 0x68, 0x8a, 0x27, 0x96, 0x97, 0x49, 0x05, 0x01, 0xf7, 0x9f, 0x58, 0x1e, + 0x5b, 0x81, 0x06, 0x76, 0x13, 0x2f, 0xe0, 0x8d, 0x44, 0xb0, 0x9b, 0xd0, 0x40, 0x25, 0x8a, 0xa7, + 0x47, 0x80, 0x4a, 0x74, 0xaf, 0xfe, 0x93, 0x7f, 0xba, 0x76, 0x86, 0x4b, 0x34, 0x7b, 0x07, 0xea, + 0xd6, 0x68, 0x14, 0x93, 0x2e, 0x4f, 0x2d, 0xa7, 0x7c, 0xbe, 0x9c, 0x08, 0xd8, 0x5d, 0xd0, 0xa5, + 0xdc, 0x90, 0xba, 0x41, 0xd4, 0x17, 0x4b, 0x5b, 0x4c, 0x59, 0xa4, 0xbc, 0xa0, 0x44, 0x8e, 0xbb, + 0xb1, 0xb2, 0x60, 0xa4, 0xd1, 0x1a, 0x2f, 0x00, 0xb8, 0x07, 0x84, 0x91, 0xd8, 0xf0, 0xbc, 0xc0, + 0xde, 0x77, 0x9f, 0x09, 0xb5, 0x63, 0x4c, 0xc1, 0xd8, 0x4d, 0xe8, 0xed, 0x49, 0x95, 0xe3, 0x22, + 0x4e, 0xbd, 0x24, 0x56, 0xbb, 0xc8, 0x0c, 0x94, 0xad, 0x01, 0x9b, 0x82, 0x1c, 0xd0, 0xf4, 0xf5, + 0x95, 0xda, 0x6a, 0x97, 0x2f, 0xc0, 0xb0, 0xb7, 0xa0, 0x3b, 0x42, 0x4e, 0xbb, 0xfe, 0xc8, 0x1c, + 0x7a, 0x16, 0x6e, 0x30, 0x35, 0xdc, 0x80, 0x32, 0xe0, 0x03, 0xcf, 0x1a, 0x19, 0x3f, 0xaf, 0x42, + 0x73, 0xdb, 0x8f, 0x45, 0x94, 0xe0, 0x2a, 0xb1, 0x86, 0x43, 0x61, 0x27, 0x42, 0x5a, 0xa7, 0x3a, + 0xcf, 0xeb, 0x38, 0xcb, 0x83, 0xe0, 0x8b, 0xc8, 0x4d, 0xc4, 0xfe, 0x87, 0x4a, 0x0f, 0x0a, 0x00, + 0xbb, 0x05, 0xcb, 0x96, 0xe3, 0x98, 0x19, 0xb5, 0x19, 0x05, 0x4f, 0x63, 0x5a, 0x31, 0x1a, 0x5f, + 0xb2, 0x1c, 0x67, 0x43, 0xc1, 0x79, 0xf0, 0x34, 0x66, 0xd7, 0xa1, 0x16, 0x89, 0x21, 0x69, 0x45, + 0x7b, 0x7d, 0x49, 0x4a, 0xed, 0xf3, 0xc3, 0x1f, 0x0a, 0x3b, 0xe1, 0x62, 0xc8, 0x11, 0xc7, 0xce, + 0x41, 0xc3, 0x4a, 0x92, 0x48, 0x4a, 0x41, 0xe7, 0xb2, 0xc2, 0xd6, 0xe0, 0x2c, 0xad, 0xcc, 0xc4, + 0x0d, 0x7c, 0x33, 0xb1, 0x0e, 0x3d, 0xdc, 0x08, 0x63, 0x65, 0xf3, 0x97, 0x73, 0xd4, 0x01, 0x62, + 0xb6, 0x9d, 0x18, 0x77, 0x89, 0x59, 0x7a, 0xdf, 0x9a, 0x88, 0x98, 0x4c, 0xbe, 0xce, 0xcf, 0x4e, + 0xb7, 0xd8, 0x45, 0x14, 0xb2, 0xac, 0x68, 0x83, 0x6b, 0x5b, 0xa3, 0x65, 0xd2, 0xc9, 0x81, 0xb8, + 0xf4, 0xcf, 0x43, 0xd3, 0x8d, 0x4d, 0xe1, 0x3b, 0xca, 0xdc, 0x34, 0xdc, 0xf8, 0xbe, 0xef, 0xb0, + 0x77, 0x41, 0x97, 0x5f, 0x71, 0xc4, 0x90, 0xf6, 0xf2, 0xf6, 0x7a, 0x4f, 0x29, 0x25, 0x82, 0xb7, + 0xc4, 0x90, 0x6b, 0x89, 0x2a, 0x19, 0x3f, 0xae, 0x42, 0x9b, 0x74, 0xe8, 0x51, 0xe8, 0xe0, 0x92, + 0x7b, 0x0b, 0xba, 0xd3, 0xdc, 0x93, 0x02, 0xe8, 0x58, 0x65, 0xd6, 0x5d, 0x80, 0xe6, 0x86, 0x8d, + 0xa3, 0x20, 0x09, 0x74, 0xb9, 0xaa, 0xe1, 0xb2, 0xde, 0xbe, 0x97, 0xda, 0x47, 0x22, 0x21, 0xa6, + 0x77, 0x79, 0x56, 0x45, 0xcc, 0xae, 0xc2, 0xd4, 0x25, 0x46, 0x55, 0xd9, 0x7d, 0x80, 0x7d, 0x31, + 0x9a, 0x08, 0x3f, 0xd9, 0xb1, 0x42, 0xa5, 0xee, 0x37, 0x66, 0xd4, 0x5d, 0x8e, 0x6d, 0xad, 0xa0, + 0xbb, 0xef, 0x27, 0xd1, 0x09, 0x2f, 0x35, 0x64, 0xdf, 0x82, 0xa5, 0x94, 0xa8, 0x4c, 0x3b, 0x39, + 0x36, 0x3d, 0xb4, 0x12, 0x4d, 0xea, 0x4b, 0x49, 0x56, 0x76, 0xb1, 0x99, 0x1c, 0xf3, 0x6e, 0x9a, + 0x15, 0x1f, 0xba, 0x71, 0x72, 0xe9, 0xdb, 0xb0, 0x34, 0xd3, 0x2f, 0x7a, 0x6e, 0x47, 0xe2, 0x84, + 0x66, 0xae, 0x73, 0x2c, 0xa2, 0x22, 0x3c, 0xb1, 0xbc, 0x34, 0x73, 0x39, 0x64, 0xe5, 0xd7, 0xaa, + 0x1f, 0x55, 0x8c, 0x37, 0xa1, 0xb1, 0x11, 0x45, 0x16, 0x91, 0x58, 0x58, 0x18, 0x54, 0x68, 0xdf, + 0x91, 0x15, 0xc3, 0x86, 0x1a, 0x8e, 0xee, 0x06, 0x54, 0x27, 0x21, 0x61, 0xda, 0xeb, 0xe7, 0x4b, + 0x93, 0xb3, 0xc2, 0xb5, 0x1d, 0x35, 0x99, 0xea, 0x24, 0xbc, 0x74, 0x17, 0x5a, 0x3b, 0xaf, 0x31, + 0x86, 0xff, 0xac, 0x83, 0xb6, 0x25, 0x3c, 0x41, 0x32, 0x30, 0xa0, 0x53, 0x56, 0xf3, 0x4c, 0x7e, + 0x53, 0xaa, 0x6f, 0x40, 0x47, 0xee, 0x84, 0xd4, 0x4a, 0xa8, 0x75, 0x34, 0x05, 0x7b, 0x2d, 0x59, + 0x5e, 0x01, 0x88, 0x82, 0xa7, 0xa6, 0x2b, 0xb7, 0x23, 0x69, 0xd9, 0xb5, 0x28, 0x78, 0xba, 0x8d, + 0x1b, 0xd2, 0xff, 0xc9, 0xba, 0xf9, 0x16, 0x0c, 0x4a, 0xeb, 0x06, 0xdd, 0x4c, 0xd3, 0xf5, 0xcd, + 0x43, 0xf4, 0x79, 0xd4, 0x12, 0x2a, 0xfa, 0x24, 0x2f, 0x74, 0xdb, 0xbf, 0x47, 0x0e, 0x91, 0xb2, + 0x06, 0xfa, 0x29, 0xd6, 0x60, 0xa1, 0x71, 0x81, 0xc5, 0xc6, 0xe5, 0xde, 0x94, 0x56, 0xb7, 0x49, + 0xf0, 0x46, 0x21, 0xf8, 0x4c, 0x5a, 0xa7, 0xaa, 0xf4, 0x75, 0xe8, 0xd8, 0x96, 0x6f, 0x26, 0x51, + 0xea, 0xdb, 0x56, 0x22, 0x06, 0x1d, 0xfa, 0x54, 0xdb, 0xb6, 0xfc, 0x03, 0x05, 0x2a, 0x59, 0x80, + 0x6e, 0xd9, 0x02, 0xdc, 0x84, 0xa5, 0x30, 0x72, 0x27, 0x56, 0x74, 0x62, 0x1e, 0x89, 0x13, 0x12, + 0x46, 0x4f, 0xfa, 0xd3, 0x0a, 0xfc, 0x99, 0x38, 0xd9, 0x76, 0x8e, 0xbf, 0xac, 0xee, 0xff, 0x63, + 0x15, 0xf4, 0xbd, 0x48, 0x28, 0xab, 0x7d, 0x0d, 0xda, 0xb1, 0x3d, 0x16, 0x13, 0x8b, 0xa4, 0xa4, + 0x7a, 0x00, 0x09, 0x42, 0xe1, 0x4c, 0xdb, 0xa5, 0xea, 0xe9, 0x76, 0x09, 0xc7, 0x21, 0xbd, 0x1d, + 0x5c, 0x4c, 0x58, 0x2c, 0x8c, 0x71, 0xbd, 0x6c, 0x8c, 0x57, 0xa0, 0x33, 0xb6, 0x62, 0xd3, 0x4a, + 0x93, 0xc0, 0xb4, 0x03, 0x8f, 0x94, 0x4e, 0xe3, 0x30, 0xb6, 0xe2, 0x8d, 0x34, 0x09, 0x36, 0x03, + 0xf2, 0x9e, 0xdc, 0xd8, 0x94, 0x8b, 0x5e, 0xed, 0x8b, 0x9a, 0x1b, 0x2b, 0x73, 0xb7, 0x06, 0x67, + 0x45, 0x9c, 0xb8, 0x13, 0x4b, 0x09, 0xd4, 0xb4, 0x83, 0xd4, 0x4f, 0x68, 0x77, 0xac, 0xf1, 0xe5, + 0x1c, 0xc5, 0x83, 0xa7, 0x9b, 0x88, 0x60, 0xef, 0x43, 0xcf, 0x0e, 0x26, 0xa1, 0x19, 0x22, 0x5f, + 0xc9, 0xef, 0x90, 0x8e, 0x78, 0xd9, 0x2f, 0xe8, 0x20, 0xc5, 0xde, 0x91, 0x90, 0x8e, 0xd0, 0x3a, + 0x2c, 0xd9, 0x5e, 0x1a, 0x27, 0x22, 0x32, 0x0f, 0x55, 0x13, 0x7d, 0xae, 0x49, 0x57, 0x91, 0x48, + 0xe7, 0x09, 0x19, 0xdb, 0xda, 0x0b, 0xe2, 0x64, 0x6b, 0xe2, 0x65, 0x8a, 0x59, 0x79, 0x55, 0xc5, + 0xac, 0x2e, 0x56, 0xcc, 0x05, 0xaa, 0x51, 0x5b, 0xa0, 0x1a, 0x6c, 0x15, 0xfa, 0x65, 0x3a, 0x12, + 0xa9, 0x74, 0xe3, 0x7a, 0x05, 0x21, 0x89, 0x55, 0xf2, 0xd7, 0x91, 0x96, 0xa4, 0x91, 0xf1, 0x57, + 0x59, 0x11, 0x89, 0x74, 0x49, 0x43, 0x0a, 0xe6, 0x2b, 0x8d, 0xf9, 0xff, 0xf0, 0x46, 0xde, 0xd2, + 0x7c, 0xea, 0x26, 0xe3, 0x20, 0x4d, 0xcc, 0x21, 0x9d, 0x58, 0x62, 0xe5, 0x75, 0x5f, 0xc8, 0x7a, + 0xfa, 0x42, 0xa2, 0xe5, 0x79, 0x86, 0x7c, 0xa4, 0x61, 0xea, 0x79, 0x66, 0x22, 0x8e, 0x13, 0x25, + 0x82, 0x81, 0xe4, 0x8d, 0xe2, 0xdb, 0x83, 0xd4, 0xf3, 0x0e, 0xc4, 0x71, 0x82, 0x16, 0x5f, 0x1b, + 0xaa, 0x8a, 0xf1, 0x77, 0x35, 0x80, 0x87, 0x81, 0x7d, 0x74, 0x60, 0x45, 0x23, 0x91, 0xa0, 0x2f, + 0x9f, 0xd9, 0x21, 0x65, 0x27, 0x5b, 0x89, 0xb4, 0x3e, 0x6c, 0x1d, 0x2e, 0x64, 0xf3, 0xb7, 0x03, + 0x8f, 0xce, 0x15, 0xd2, 0x90, 0xa8, 0x65, 0xc0, 0x14, 0x56, 0x9e, 0x4c, 0xc9, 0x8a, 0xb0, 0x8f, + 0x0a, 0xde, 0x62, 0x9b, 0xe4, 0x24, 0x24, 0xde, 0x2e, 0xf2, 0x09, 0xbb, 0x45, 0xf3, 0x83, 0x93, + 0x90, 0xbd, 0x0f, 0xe7, 0x23, 0x31, 0x8c, 0x44, 0x3c, 0x36, 0x93, 0xb8, 0xfc, 0x31, 0xe9, 0xd2, + 0x2f, 0x2b, 0xe4, 0x41, 0x9c, 0x7f, 0xeb, 0x7d, 0x38, 0x2f, 0x39, 0x35, 0x3b, 0x3c, 0x69, 0x75, + 0x97, 0x25, 0xb2, 0x3c, 0xba, 0x37, 0x81, 0x82, 0x1f, 0xd2, 0x92, 0x66, 0x0e, 0xa2, 0x47, 0xcc, + 0x38, 0xf4, 0x04, 0x3a, 0x56, 0x9b, 0x63, 0x3c, 0x75, 0x6e, 0x89, 0xa1, 0x62, 0x7e, 0x01, 0x60, + 0x06, 0xd4, 0x77, 0x02, 0x47, 0x10, 0xab, 0x7b, 0xeb, 0xbd, 0x35, 0x0a, 0xa3, 0x20, 0x27, 0x11, + 0xca, 0x09, 0xc7, 0xde, 0x01, 0xea, 0x4e, 0xaa, 0xdf, 0xbc, 0x8e, 0x6b, 0x88, 0x24, 0x1d, 0x7c, + 0x1f, 0xce, 0x17, 0x23, 0x31, 0xad, 0xc4, 0x4c, 0xc6, 0x82, 0x8c, 0x98, 0x34, 0xa6, 0xcb, 0xf9, + 0xa0, 0x36, 0x92, 0x83, 0xb1, 0xb8, 0xef, 0x3b, 0xc6, 0x47, 0xd0, 0xc4, 0x8f, 0x7d, 0x1e, 0xb2, + 0x35, 0x68, 0x25, 0x24, 0xbc, 0x58, 0x6d, 0xa7, 0xe7, 0x0a, 0xab, 0x5a, 0x48, 0x96, 0x67, 0x44, + 0x06, 0x87, 0xa5, 0xdc, 0x44, 0x3d, 0xf2, 0xdd, 0xc7, 0xa9, 0x60, 0x9f, 0xc0, 0x72, 0x18, 0x09, + 0xa5, 0x94, 0x66, 0x7a, 0x84, 0x1e, 0x83, 0x5a, 0x5f, 0xe7, 0x94, 0x0e, 0xe5, 0x2d, 0x8e, 0x50, + 0x7f, 0x7a, 0xe1, 0x54, 0xdd, 0xf8, 0x01, 0x5c, 0xcc, 0x29, 0xf6, 0x85, 0x1d, 0xf8, 0x8e, 0x15, + 0x9d, 0xd0, 0x6e, 0x32, 0xd3, 0x77, 0xfc, 0x2a, 0x7d, 0xef, 0x53, 0xdf, 0x3f, 0xaa, 0x41, 0xef, + 0x73, 0x7f, 0x2b, 0x0d, 0x3d, 0x17, 0x2d, 0xfc, 0x67, 0xd2, 0x00, 0x4b, 0xc3, 0x57, 0x29, 0x1b, + 0xbe, 0x55, 0xe8, 0xab, 0xaf, 0xa0, 0x02, 0x48, 0xb3, 0xa5, 0xe2, 0x2c, 0x12, 0xbe, 0x19, 0x78, + 0xd2, 0x66, 0x7d, 0x1b, 0xce, 0xa7, 0x34, 0x73, 0x49, 0x39, 0x16, 0xf6, 0x91, 0xf9, 0x9c, 0x23, + 0x13, 0x93, 0x84, 0xd8, 0x14, 0xc9, 0xc8, 0x80, 0x5d, 0x83, 0x76, 0xd1, 0x3c, 0xb3, 0xbe, 0x90, + 0x13, 0xd2, 0x48, 0x02, 0xdf, 0x74, 0xb2, 0x21, 0xab, 0xbd, 0x1f, 0xed, 0x76, 0x2f, 0x28, 0x66, + 0x82, 0x46, 0xe5, 0xb7, 0x60, 0x79, 0x8a, 0x92, 0x46, 0x21, 0xdd, 0xb4, 0xdb, 0x85, 0x18, 0xa7, + 0xa7, 0x5f, 0xae, 0xe2, 0x78, 0xe4, 0x3e, 0xb9, 0x14, 0x4c, 0x43, 0x33, 0x43, 0x33, 0xf2, 0x83, + 0x48, 0x28, 0xf5, 0x45, 0x43, 0x43, 0xf5, 0x4b, 0xbb, 0x70, 0x6e, 0x51, 0x2f, 0x0b, 0x36, 0xbb, + 0x95, 0xf2, 0x66, 0x37, 0x73, 0xdc, 0x2b, 0x36, 0xbe, 0x3f, 0xab, 0x40, 0xfb, 0x41, 0xfa, 0xec, + 0xd9, 0x89, 0x34, 0x47, 0xac, 0x03, 0x95, 0x5d, 0xea, 0xa5, 0xca, 0x2b, 0xbb, 0xe8, 0x1d, 0xef, + 0x1d, 0xa1, 0x69, 0xa4, 0x4e, 0x74, 0xae, 0x6a, 0x78, 0x50, 0xdc, 0x3b, 0x3a, 0x38, 0xc5, 0x28, + 0x48, 0x34, 0x1e, 0x7f, 0xee, 0xa5, 0xae, 0x87, 0x3e, 0x93, 0x5a, 0xff, 0x79, 0x1d, 0x8f, 0x5e, + 0xdb, 0x43, 0xa9, 0x2f, 0x0f, 0xa2, 0x60, 0x22, 0x35, 0x5a, 0x59, 0xdd, 0x05, 0x18, 0xe3, 0xa7, + 0x35, 0xa8, 0x7f, 0x1a, 0xb8, 0xbe, 0x0c, 0x5b, 0x78, 0xd2, 0x31, 0x96, 0x1e, 0x6a, 0x2b, 0x12, + 0x1e, 0x7a, 0xc0, 0x88, 0x42, 0xc5, 0xf0, 0xe4, 0xc9, 0x9a, 0x50, 0x76, 0x20, 0x51, 0xc5, 0xe1, + 0xba, 0xb2, 0xf0, 0x70, 0x9d, 0x9f, 0x7d, 0xeb, 0x2f, 0x3a, 0xfb, 0xea, 0x9e, 0x18, 0xa2, 0xaa, + 0xfa, 0x8e, 0xf2, 0xf1, 0xa7, 0x4d, 0x83, 0x18, 0x26, 0x9b, 0x81, 0xef, 0xb0, 0x6f, 0x00, 0x44, + 0xee, 0x68, 0xac, 0x28, 0x9b, 0xf3, 0xf1, 0x08, 0xc2, 0x12, 0x29, 0x87, 0x37, 0x54, 0x90, 0x4b, + 0xed, 0x19, 0xe6, 0x21, 0x72, 0x49, 0xce, 0xa3, 0x95, 0x1d, 0x9b, 0x17, 0x87, 0xc7, 0x2e, 0x4c, + 0x85, 0xc7, 0x88, 0xbb, 0x34, 0xdf, 0x2b, 0x80, 0x9e, 0xc3, 0xd8, 0x0c, 0x7c, 0x33, 0xcc, 0xc2, + 0x3b, 0x1a, 0x42, 0x3e, 0xf7, 0xf7, 0x8e, 0xd0, 0x82, 0xba, 0xb1, 0xa9, 0xa2, 0x44, 0xea, 0xcc, + 0x55, 0x3a, 0x62, 0xaf, 0x40, 0xe7, 0x87, 0x81, 0xeb, 0x9b, 0x13, 0x2b, 0x34, 0x13, 0x4b, 0x86, + 0x51, 0x1b, 0x1c, 0x10, 0xb6, 0x63, 0x85, 0x07, 0xd6, 0x88, 0x5c, 0x24, 0x15, 0x77, 0xc2, 0x45, + 0xd2, 0x96, 0x04, 0x0a, 0x84, 0xe2, 0xbd, 0x0c, 0x3a, 0x75, 0x41, 0x51, 0xa9, 0x8e, 0x94, 0x3d, + 0x02, 0x90, 0xa3, 0xc6, 0xbf, 0x56, 0x41, 0xdb, 0xf0, 0x13, 0x97, 0xe4, 0x79, 0x01, 0x9a, 0x11, + 0x1d, 0xb1, 0x95, 0x34, 0x55, 0x2d, 0x97, 0x58, 0xf5, 0x39, 0x12, 0x9b, 0x92, 0x44, 0xed, 0xa5, + 0x25, 0x51, 0x3f, 0x4d, 0x12, 0xd3, 0x5c, 0x6b, 0x9c, 0xca, 0xb5, 0xb9, 0xc0, 0xc4, 0xd7, 0x21, + 0xc6, 0x59, 0x49, 0x68, 0x2f, 0x92, 0x84, 0x3e, 0x2b, 0x09, 0xe3, 0xaf, 0x6b, 0xa0, 0x3d, 0x14, + 0xc3, 0xe4, 0x57, 0x8b, 0xe7, 0x97, 0x65, 0xf1, 0x18, 0xff, 0x51, 0x03, 0x9d, 0xe3, 0x0c, 0xbf, + 0x46, 0x99, 0xdd, 0x01, 0x20, 0x59, 0x9c, 0x2e, 0x38, 0x92, 0x97, 0x8c, 0x7d, 0x7d, 0x00, 0x6d, + 0x29, 0x13, 0xd9, 0xa2, 0xf1, 0x9c, 0x16, 0x52, 0x70, 0x07, 0xf3, 0xf2, 0x6e, 0xbe, 0xb4, 0xbc, + 0x5b, 0xaf, 0x2d, 0x6f, 0xed, 0xab, 0x90, 0xb7, 0x7e, 0xaa, 0xbc, 0xe1, 0x45, 0xf2, 0x6e, 0xbf, + 0x48, 0xde, 0x9d, 0x39, 0x79, 0xff, 0xa8, 0x06, 0x5d, 0x92, 0xf7, 0xbe, 0x98, 0x7c, 0x39, 0xa3, + 0x38, 0x23, 0xa4, 0xda, 0xab, 0x0a, 0xa9, 0xfe, 0xd2, 0x42, 0x6a, 0xbc, 0xb6, 0x90, 0x9a, 0x5f, + 0x85, 0x90, 0x5a, 0xa7, 0x0a, 0x49, 0x7b, 0x91, 0x90, 0xf4, 0x57, 0x5f, 0x94, 0xb9, 0x90, 0xbe, + 0xf4, 0xce, 0xf5, 0x2b, 0x21, 0x7d, 0x45, 0x42, 0x82, 0x39, 0x21, 0xa1, 0x67, 0xf1, 0xa5, 0x17, + 0xd1, 0xd7, 0xe1, 0x59, 0x9c, 0xca, 0xec, 0xc6, 0x57, 0xc1, 0xec, 0xe6, 0xa9, 0xcc, 0x6e, 0xbd, + 0x88, 0xd9, 0xaf, 0xe1, 0x59, 0xfc, 0x4d, 0x0d, 0x60, 0xdf, 0xf5, 0x47, 0x9e, 0xf8, 0x95, 0x6f, + 0xf1, 0x4b, 0xe3, 0x5b, 0xfc, 0x7d, 0x15, 0xb4, 0x1d, 0x2b, 0x3a, 0xfa, 0x85, 0x5b, 0x21, 0x6f, + 0x41, 0x2b, 0xf0, 0xcb, 0xeb, 0xa1, 0x4c, 0xd7, 0x0c, 0xfc, 0x5f, 0x08, 0x95, 0xff, 0x69, 0x03, + 0xf4, 0x2d, 0xe1, 0xa4, 0xe1, 0x97, 0xd0, 0xf8, 0x5f, 0x16, 0xf3, 0xf2, 0x82, 0xe3, 0xce, 0x2c, + 0x37, 0x5b, 0x2f, 0xe2, 0xa6, 0x36, 0x77, 0x48, 0x7c, 0x08, 0x67, 0xa7, 0xa2, 0x28, 0x96, 0xbc, + 0x8a, 0xd3, 0x29, 0x34, 0x77, 0x45, 0x8e, 0x77, 0x37, 0x70, 0xa6, 0x02, 0x29, 0xf2, 0x82, 0x8e, + 0x2f, 0x07, 0xb3, 0x20, 0xf6, 0x36, 0xf4, 0x1c, 0x14, 0x0d, 0x05, 0x87, 0x28, 0xcc, 0x2b, 0xd3, + 0x7f, 0x3a, 0x04, 0xdd, 0x0c, 0x3c, 0x8a, 0x5d, 0x7c, 0x04, 0x4b, 0x05, 0x95, 0xb4, 0x2c, 0xed, + 0xe7, 0x58, 0x96, 0x6e, 0xd6, 0x50, 0xee, 0xc1, 0xd3, 0x1e, 0x73, 0xe7, 0x95, 0x3d, 0xe6, 0xee, + 0x4b, 0xec, 0xf3, 0xb7, 0xe1, 0x6c, 0x76, 0xf9, 0xa7, 0x82, 0xa1, 0x24, 0xc1, 0x1e, 0x69, 0x50, + 0x5f, 0xdd, 0xf7, 0x51, 0x28, 0x94, 0x44, 0xf4, 0x31, 0x9c, 0x2b, 0x91, 0xe3, 0xd2, 0x94, 0xf4, + 0x4b, 0x73, 0xba, 0xb2, 0x9c, 0xb7, 0xc5, 0x2a, 0x36, 0x36, 0x7e, 0xb7, 0x02, 0xad, 0xbd, 0x28, + 0x70, 0x52, 0x3b, 0x79, 0x4d, 0x4d, 0x9e, 0xd6, 0x90, 0xda, 0x8b, 0x34, 0xa4, 0x3e, 0xab, 0x21, + 0xc6, 0xef, 0x55, 0x40, 0x57, 0x43, 0x78, 0xb8, 0xfe, 0x35, 0x6d, 0x20, 0x2f, 0x1e, 0xc5, 0x53, + 0xd0, 0x29, 0xe6, 0x79, 0xaa, 0x49, 0x3c, 0x75, 0x85, 0x55, 0x5f, 0x6b, 0x85, 0x19, 0x7f, 0x58, + 0x81, 0x2e, 0x85, 0x87, 0x1f, 0xa4, 0xbe, 0xd4, 0xe1, 0xc5, 0x11, 0xd2, 0x15, 0xa8, 0x47, 0x22, + 0xc9, 0x32, 0x37, 0x3a, 0xf2, 0x33, 0x9b, 0x81, 0xb7, 0x25, 0x86, 0x9c, 0x30, 0xc8, 0x04, 0x2b, + 0x1a, 0xc5, 0x8b, 0x72, 0x47, 0x10, 0x8e, 0xb3, 0x0a, 0xad, 0xc8, 0x9a, 0xc4, 0x59, 0xee, 0x88, + 0xac, 0x31, 0x06, 0x75, 0x5a, 0x29, 0x0d, 0x5a, 0x29, 0x54, 0x36, 0x36, 0xe0, 0xfc, 0xfd, 0xe3, + 0x44, 0x44, 0xbe, 0x45, 0x2b, 0x66, 0x1d, 0xf5, 0x8d, 0x42, 0xc2, 0x19, 0x71, 0xa5, 0x20, 0xc6, + 0x01, 0x97, 0x33, 0xe3, 0x64, 0xc5, 0xb8, 0x01, 0xed, 0xa1, 0xeb, 0x09, 0x33, 0x18, 0x0e, 0x63, + 0x91, 0xe0, 0xd7, 0x65, 0x89, 0xa6, 0x55, 0xe3, 0xaa, 0x66, 0xfc, 0xb8, 0x0e, 0x9d, 0xec, 0x53, + 0x94, 0x39, 0xb4, 0x78, 0xfa, 0x97, 0x41, 0xa7, 0xde, 0x62, 0xf7, 0x99, 0x20, 0x1e, 0xd4, 0xb8, + 0x86, 0x00, 0x4a, 0xf5, 0xd8, 0x80, 0xe5, 0xd2, 0xa7, 0xcc, 0x24, 0x48, 0x2c, 0x4f, 0xb1, 0xa1, + 0x74, 0x3f, 0x5d, 0x22, 0xe1, 0x4b, 0x58, 0xf9, 0x9c, 0xca, 0x07, 0x48, 0x8d, 0xec, 0xcd, 0x03, + 0xc2, 0x73, 0xec, 0x45, 0x0c, 0xfb, 0x1e, 0x2c, 0xe1, 0x6c, 0xd7, 0xe5, 0xaa, 0xa4, 0xf9, 0x4a, + 0xa3, 0x7a, 0xad, 0xf8, 0xc4, 0x42, 0x9e, 0xf1, 0xae, 0x3f, 0xc5, 0xc2, 0x37, 0x01, 0xec, 0x48, + 0xe0, 0x82, 0x8d, 0x1f, 0x7b, 0x64, 0x53, 0x75, 0xae, 0x4b, 0xc8, 0xfe, 0x63, 0x2f, 0x9f, 0x69, + 0xee, 0x60, 0xe8, 0x72, 0xa6, 0xa4, 0xe8, 0xb7, 0xa1, 0x1d, 0x44, 0xee, 0xc8, 0xf5, 0x65, 0xf8, + 0x5a, 0x5b, 0x30, 0x5a, 0x90, 0x04, 0x14, 0xcc, 0x36, 0xa0, 0x29, 0x15, 0x75, 0xc1, 0x0d, 0x86, + 0xc2, 0x30, 0x0e, 0xbd, 0x83, 0x43, 0x34, 0x70, 0x94, 0x9c, 0xb9, 0x19, 0x78, 0x94, 0xd0, 0xd2, + 0x5e, 0xbf, 0x35, 0x3f, 0x2d, 0x94, 0xcf, 0xda, 0x34, 0xb1, 0x0c, 0x60, 0xcf, 0xf4, 0xc0, 0x6e, + 0xc2, 0x52, 0x9c, 0x44, 0xae, 0x9d, 0xe0, 0x14, 0xcd, 0x49, 0xe0, 0x08, 0xf2, 0x42, 0x34, 0xde, + 0x95, 0xe0, 0xfd, 0xc7, 0xde, 0x4e, 0xe0, 0x88, 0x4b, 0x1b, 0x70, 0x76, 0x41, 0x77, 0xaf, 0x74, + 0x6d, 0x6b, 0x03, 0xec, 0x27, 0x91, 0xb0, 0x26, 0xa4, 0x3c, 0xef, 0x40, 0x2b, 0x39, 0xf4, 0xe8, + 0x4e, 0xb6, 0xb2, 0xf0, 0x4e, 0xb6, 0x99, 0x1c, 0x22, 0x97, 0x4a, 0xea, 0x58, 0xa5, 0xdb, 0x51, + 0x55, 0xc3, 0x0f, 0x79, 0xee, 0xc4, 0x4d, 0x54, 0xaa, 0xa5, 0xac, 0x18, 0x1f, 0x82, 0x4e, 0x3d, + 0xd0, 0x37, 0x72, 0x6f, 0xb4, 0x72, 0xaa, 0x37, 0x6a, 0xbc, 0x07, 0xfa, 0x6f, 0xe2, 0x30, 0xa9, + 0xd1, 0x35, 0x68, 0xd3, 0xbd, 0xbd, 0x79, 0xe8, 0x05, 0xf6, 0x51, 0x76, 0x9f, 0x4c, 0xa0, 0x7b, + 0x08, 0x31, 0x00, 0xb4, 0x47, 0xbe, 0x1b, 0xf8, 0x1b, 0x9e, 0x67, 0xfc, 0x51, 0x1d, 0xf4, 0xef, + 0x5b, 0xf1, 0x98, 0xac, 0x04, 0x5b, 0x81, 0xf6, 0xae, 0x10, 0x0e, 0x02, 0x76, 0xac, 0x50, 0xe5, + 0x74, 0x95, 0x41, 0xec, 0x12, 0x68, 0xdf, 0x97, 0xfe, 0xcf, 0x67, 0xea, 0xa6, 0x34, 0xaf, 0x67, + 0xad, 0x29, 0x2f, 0x40, 0x64, 0xe9, 0x43, 0x65, 0x10, 0xbb, 0x05, 0x7d, 0xac, 0x52, 0xe6, 0x14, + 0xea, 0xa0, 0xf0, 0xa4, 0x85, 0xd0, 0xf8, 0x1c, 0x9c, 0xdd, 0x02, 0x40, 0x5f, 0x83, 0x32, 0x0e, + 0xe2, 0x05, 0x3e, 0x5a, 0x09, 0xcb, 0xae, 0x02, 0x7c, 0x9a, 0x1b, 0x58, 0x95, 0x95, 0x58, 0x82, + 0xb0, 0xb7, 0xa1, 0xab, 0x6a, 0x5c, 0x0c, 0x37, 0xd5, 0x3d, 0x75, 0x83, 0x4f, 0x03, 0xd9, 0x7d, + 0x58, 0xe6, 0xaf, 0x9c, 0x2f, 0x3a, 0x07, 0xc2, 0xcd, 0x83, 0x6e, 0x67, 0x9d, 0x34, 0x54, 0x2e, + 0x75, 0xcb, 0x8d, 0xc9, 0x8b, 0x7b, 0x9e, 0x07, 0x02, 0x5f, 0x95, 0x07, 0xd2, 0x7e, 0x39, 0x0f, + 0xa4, 0xf3, 0x52, 0x1e, 0x88, 0xf1, 0xf3, 0x1a, 0x74, 0xd4, 0xe6, 0x4a, 0x9b, 0xcf, 0x94, 0xf0, + 0x2b, 0xa7, 0x0b, 0xbf, 0xfa, 0x72, 0xc2, 0xaf, 0xbd, 0x94, 0xf0, 0xeb, 0xa7, 0x0a, 0x7f, 0xa1, + 0xd8, 0x1a, 0xaf, 0x2c, 0xb6, 0x17, 0xe9, 0xd0, 0x55, 0x80, 0xfd, 0xdc, 0x97, 0xcc, 0xdc, 0xcf, + 0x02, 0x32, 0x25, 0x76, 0xed, 0xa5, 0xc4, 0xfe, 0x8b, 0xe9, 0x78, 0x1a, 0xfb, 0x00, 0xb4, 0x7b, + 0x48, 0x99, 0x2f, 0xe4, 0x6e, 0xe5, 0x55, 0xb9, 0x6b, 0xfc, 0x4f, 0x05, 0x60, 0xdf, 0x9a, 0x84, + 0xd2, 0xf9, 0x60, 0xdf, 0x85, 0x76, 0x4c, 0x35, 0x79, 0x63, 0x23, 0xdf, 0x0c, 0x94, 0x76, 0xb7, + 0x82, 0x54, 0x15, 0x71, 0x68, 0x1c, 0xe2, 0xbc, 0x4c, 0xde, 0xbe, 0xec, 0x21, 0xcf, 0xda, 0x68, + 0x64, 0x04, 0x74, 0x59, 0x7e, 0x03, 0x7a, 0x8a, 0x20, 0x14, 0x91, 0x2d, 0x7c, 0x69, 0x67, 0x2b, + 0xbc, 0x2b, 0xa1, 0x7b, 0x12, 0xc8, 0x3e, 0xc8, 0xc9, 0xec, 0xc0, 0x4b, 0x27, 0x0b, 0xb5, 0x4d, + 0x35, 0xd9, 0x94, 0x04, 0xc6, 0x7a, 0x36, 0x15, 0x1a, 0x88, 0x06, 0x75, 0xfc, 0x5e, 0xff, 0x0c, + 0x6b, 0x43, 0x4b, 0xf5, 0xda, 0xaf, 0xb0, 0x2e, 0xe8, 0x94, 0xba, 0x4c, 0xb8, 0xaa, 0xf1, 0xa7, + 0x67, 0xa1, 0xbd, 0xed, 0xc7, 0x49, 0x94, 0x4a, 0x21, 0x16, 0x19, 0xba, 0x0d, 0xca, 0xd0, 0x55, + 0x69, 0x3b, 0x72, 0x1a, 0x94, 0xb6, 0x73, 0x13, 0xea, 0x96, 0x9f, 0xb8, 0xca, 0xd1, 0x2c, 0xa5, + 0x81, 0x67, 0x01, 0x41, 0x4e, 0x78, 0x76, 0x1b, 0x5a, 0x2a, 0x67, 0x5c, 0xa5, 0x64, 0x2e, 0x4c, + 0x38, 0xcf, 0x68, 0xd8, 0x1a, 0x68, 0x8e, 0x4a, 0x66, 0x57, 0x8b, 0xa4, 0xd4, 0x75, 0x96, 0xe6, + 0xce, 0x73, 0x1a, 0x76, 0x1d, 0x6a, 0xd6, 0x48, 0xae, 0x07, 0x4a, 0xa3, 0xc9, 0x48, 0x29, 0x05, + 0x98, 0x23, 0x8e, 0x19, 0x50, 0x47, 0xf7, 0x96, 0xd6, 0x04, 0x6d, 0x83, 0x19, 0x8d, 0x1c, 0x25, + 0xe2, 0xd8, 0x1d, 0x75, 0x0a, 0x25, 0x42, 0x6d, 0xf6, 0xbb, 0xd9, 0x85, 0x91, 0x3c, 0x8d, 0x7e, + 0xaa, 0x1a, 0xc4, 0x62, 0xe2, 0xca, 0x06, 0xfa, 0x6c, 0x83, 0x2c, 0xe8, 0xc6, 0xb5, 0x38, 0x0b, + 0xbf, 0xdd, 0x85, 0x76, 0x4c, 0xd1, 0x21, 0xd9, 0x04, 0xb2, 0xdc, 0x81, 0xbc, 0x49, 0x1e, 0x3a, + 0xe2, 0x10, 0x17, 0x61, 0xa4, 0x3b, 0xa0, 0x4f, 0xac, 0xe8, 0x48, 0x36, 0x6a, 0xcf, 0x7e, 0x27, + 0x0b, 0x5d, 0x70, 0x6d, 0x92, 0x05, 0x31, 0xd6, 0x01, 0xe4, 0xc2, 0xa2, 0x16, 0x9d, 0x59, 0x96, + 0xe7, 0xc7, 0x75, 0xae, 0x3b, 0xf9, 0xc9, 0xfd, 0x5d, 0x68, 0x85, 0xf2, 0xdc, 0x41, 0xf9, 0x66, + 0xed, 0xf5, 0xe5, 0xa2, 0x81, 0x3a, 0x90, 0xf0, 0x8c, 0x82, 0x7d, 0x07, 0x7a, 0x32, 0xc1, 0x63, + 0xa8, 0xdc, 0x74, 0xca, 0x41, 0x9b, 0xca, 0x65, 0x9e, 0xf2, 0xe2, 0x79, 0x37, 0x99, 0x72, 0xea, + 0x3f, 0x86, 0xae, 0x50, 0x5e, 0x94, 0x19, 0xdb, 0x96, 0x3f, 0xe8, 0x53, 0xf3, 0x0b, 0x8b, 0x9d, + 0x2c, 0xde, 0x11, 0x65, 0x97, 0x78, 0x15, 0x9a, 0x2a, 0xe9, 0x68, 0x99, 0x5a, 0x95, 0xde, 0xe8, + 0xc8, 0x3b, 0x72, 0xae, 0xf0, 0xec, 0xde, 0x4c, 0xf6, 0x02, 0xba, 0x51, 0x2c, 0x4b, 0x28, 0x5a, + 0x9c, 0x92, 0x30, 0x95, 0xd7, 0xf0, 0x99, 0x38, 0x41, 0x5e, 0x16, 0x59, 0x1f, 0x83, 0xb3, 0xb3, + 0xbc, 0xcc, 0x53, 0x3e, 0xb8, 0x9e, 0x67, 0x7b, 0xa0, 0x41, 0x2a, 0x67, 0xa1, 0xc8, 0x8b, 0xfc, + 0x73, 0xd4, 0xf4, 0x8d, 0x05, 0x4d, 0xe5, 0x7d, 0x3e, 0x5f, 0x0a, 0x67, 0x92, 0x59, 0xde, 0x03, + 0x2d, 0x88, 0x1c, 0x4a, 0x2e, 0x1b, 0x9c, 0xa7, 0x15, 0xbf, 0xac, 0x72, 0xc4, 0x64, 0x32, 0x3e, + 0x19, 0xb2, 0x56, 0x20, 0x2b, 0xec, 0x36, 0x74, 0xc2, 0x28, 0xf8, 0xa1, 0xb0, 0x13, 0xe9, 0x2c, + 0x5f, 0x98, 0x4f, 0xe2, 0x57, 0x78, 0xf2, 0x9d, 0x0b, 0x67, 0xf8, 0xe2, 0x73, 0x9d, 0xe1, 0x95, + 0xcc, 0xfd, 0x1b, 0xcc, 0x67, 0x4c, 0x10, 0x02, 0x7b, 0x51, 0x8e, 0xe3, 0x1b, 0xf3, 0xbd, 0x28, + 0x27, 0x72, 0x00, 0x2d, 0x37, 0x7e, 0xe0, 0x46, 0x71, 0x32, 0xb8, 0x94, 0x6d, 0x3a, 0x54, 0x45, + 0xb7, 0xd3, 0x8d, 0x1f, 0x5a, 0x71, 0x32, 0xb8, 0x9c, 0xbd, 0xc3, 0xc0, 0x1a, 0xf2, 0x5c, 0x86, + 0x09, 0x48, 0x7f, 0xaf, 0xcc, 0xf2, 0x3c, 0xbf, 0x08, 0x54, 0xf1, 0x1e, 0xd2, 0xdf, 0x4f, 0x60, + 0x49, 0xb6, 0x29, 0x96, 0xe4, 0x9b, 0xb3, 0x3a, 0x39, 0x75, 0xa3, 0xc4, 0xbb, 0xd1, 0xd4, 0x05, + 0x53, 0xde, 0x01, 0x9a, 0x2c, 0xd9, 0xc1, 0xd5, 0x85, 0x1d, 0xe4, 0xc6, 0x4d, 0x76, 0x90, 0x5f, + 0x7e, 0xdc, 0x82, 0xa6, 0xca, 0x94, 0xbb, 0x36, 0x67, 0xb4, 0x54, 0x4e, 0x28, 0x57, 0x14, 0xec, + 0x1b, 0xd0, 0xa2, 0x34, 0xa9, 0x20, 0x1c, 0xac, 0xcc, 0x2a, 0xb1, 0xcc, 0x86, 0xe2, 0x4d, 0x4f, + 0x66, 0x45, 0xbd, 0x0b, 0xad, 0x2c, 0x9e, 0x70, 0x7d, 0x76, 0x61, 0xaa, 0xbd, 0x9d, 0x67, 0x14, + 0xec, 0x06, 0x34, 0x26, 0x68, 0xd2, 0x07, 0xc6, 0xac, 0x31, 0x94, 0x96, 0x5e, 0x62, 0xc9, 0x10, + 0xd1, 0x31, 0x41, 0xae, 0xbe, 0xb7, 0xe6, 0x0c, 0x51, 0x7e, 0x86, 0xe0, 0x10, 0x17, 0xe7, 0x89, + 0xdf, 0x81, 0x4b, 0xe5, 0x0c, 0xa8, 0x2c, 0x3d, 0x4a, 0x9d, 0xff, 0xde, 0xa6, 0x5e, 0xae, 0x2f, + 0x50, 0xf0, 0xe9, 0x44, 0x2a, 0x7e, 0x31, 0x7c, 0x4e, 0x86, 0xd5, 0xdd, 0x7c, 0xc3, 0x44, 0xbb, + 0x32, 0xb8, 0x31, 0x37, 0xac, 0x7c, 0xcb, 0xcd, 0xb6, 0x51, 0xda, 0xa9, 0x3f, 0x82, 0xce, 0x30, + 0x7d, 0xf6, 0xec, 0x44, 0x85, 0x21, 0x06, 0x37, 0xa9, 0x5d, 0xe9, 0xac, 0x5b, 0xca, 0xe7, 0xe1, + 0xed, 0x61, 0x29, 0xb9, 0xe7, 0x22, 0xb4, 0x6c, 0xdf, 0xb4, 0x1c, 0x27, 0x1a, 0xbc, 0x23, 0xf3, + 0x79, 0x6c, 0x7f, 0xc3, 0x71, 0x28, 0x31, 0x2a, 0x08, 0x05, 0x3d, 0x68, 0x31, 0x5d, 0x67, 0xb0, + 0x2a, 0xb7, 0xee, 0x0c, 0xb4, 0xed, 0xd0, 0x53, 0x39, 0x2b, 0xb2, 0x3c, 0x4f, 0x78, 0x48, 0xf0, + 0x0d, 0xf5, 0x54, 0x4e, 0x81, 0xb6, 0x1d, 0x76, 0x1d, 0x3a, 0x13, 0xeb, 0xd8, 0xcc, 0x20, 0x83, + 0x5b, 0xf2, 0x1d, 0xd2, 0xc4, 0x3a, 0xde, 0x53, 0x20, 0x54, 0x73, 0x99, 0xc6, 0x4c, 0xca, 0xf6, + 0xee, 0xac, 0x9a, 0xe7, 0x11, 0x18, 0xae, 0xbb, 0x79, 0x30, 0x86, 0xcc, 0x11, 0x19, 0x61, 0xd3, + 0x5b, 0x1f, 0xbc, 0x37, 0x6f, 0x8e, 0x54, 0xe8, 0x08, 0xcd, 0x51, 0x16, 0x45, 0x5a, 0x07, 0x90, + 0xd6, 0x9a, 0x84, 0x7d, 0x7b, 0xb6, 0x4d, 0x7e, 0x96, 0xe3, 0x32, 0x87, 0x97, 0x44, 0xbd, 0x0e, + 0x40, 0xa7, 0x4a, 0xd9, 0x66, 0x6d, 0xb6, 0x4d, 0x7e, 0x94, 0xe3, 0xfa, 0x93, 0xfc, 0x54, 0x77, + 0x07, 0xf4, 0x14, 0x0f, 0x6d, 0xa6, 0xe5, 0x79, 0x83, 0x3b, 0xb3, 0x6b, 0x20, 0x3b, 0xcf, 0x71, + 0x2d, 0x55, 0x25, 0xfc, 0x08, 0xc5, 0xae, 0xc9, 0x8d, 0x1b, 0xbc, 0x3f, 0xfb, 0x91, 0xfc, 0xd0, + 0xc7, 0xf5, 0x71, 0x7e, 0xfe, 0xfb, 0x18, 0xba, 0x59, 0x08, 0x55, 0x36, 0xfb, 0x60, 0x76, 0xeb, + 0x28, 0x9f, 0x07, 0x78, 0xf6, 0x18, 0x4c, 0x36, 0xbe, 0x0b, 0x6d, 0xc9, 0x71, 0xd9, 0x74, 0x7d, + 0x56, 0xc1, 0x0a, 0xa7, 0x92, 0x4b, 0xd1, 0xc8, 0x66, 0x37, 0xa0, 0x61, 0x85, 0xa1, 0x77, 0x32, + 0xf8, 0x70, 0x76, 0x55, 0x6d, 0x20, 0x98, 0x4b, 0x2c, 0xea, 0xe1, 0x24, 0xf5, 0x12, 0x37, 0x4b, + 0x48, 0xfe, 0xe6, 0xac, 0x1e, 0x96, 0x1e, 0x3c, 0xf0, 0xf6, 0xa4, 0xf4, 0x32, 0xe3, 0x3d, 0xd0, + 0xc2, 0x20, 0x4e, 0x4c, 0x67, 0xe2, 0x0d, 0xee, 0xce, 0xed, 0xbe, 0x32, 0xeb, 0x95, 0xb7, 0x42, + 0x59, 0x30, 0xee, 0x42, 0x67, 0x83, 0x9e, 0x88, 0xba, 0x31, 0x99, 0xf2, 0x1b, 0x50, 0xcf, 0x23, + 0x84, 0xf9, 0x1e, 0x41, 0x14, 0xcf, 0xc4, 0xb6, 0x3f, 0x0c, 0x38, 0xa1, 0x8d, 0xbf, 0xac, 0x41, + 0x73, 0x3f, 0x48, 0x23, 0x5b, 0xbc, 0x38, 0x9f, 0xfb, 0xcd, 0x4c, 0x65, 0xfc, 0x22, 0xd7, 0x4d, + 0x6a, 0x07, 0xa1, 0xcb, 0xc1, 0xc7, 0x1a, 0x05, 0x65, 0xf2, 0xe0, 0xe3, 0x39, 0x68, 0xc8, 0x43, + 0xbd, 0xcc, 0x28, 0x96, 0x15, 0x5a, 0x2e, 0x69, 0x3c, 0x76, 0x82, 0xa7, 0x3e, 0x2e, 0x97, 0x06, + 0x25, 0xe4, 0x42, 0x06, 0xda, 0x76, 0xe8, 0x51, 0x4c, 0x46, 0x40, 0xeb, 0x51, 0x46, 0x82, 0x3a, + 0x19, 0x90, 0x56, 0x65, 0x16, 0xd8, 0x6c, 0x3d, 0x27, 0xb0, 0x79, 0x0b, 0xf2, 0x24, 0x73, 0xe5, + 0xc0, 0x3d, 0x3f, 0x09, 0x7d, 0x1d, 0xf4, 0xfc, 0x01, 0xb1, 0x72, 0xde, 0xce, 0xad, 0x15, 0x4f, + 0x8a, 0x0f, 0xb2, 0x12, 0x2f, 0xc8, 0x16, 0x44, 0x3c, 0xc3, 0x28, 0x38, 0x54, 0xc1, 0x29, 0x78, + 0x95, 0x88, 0xe7, 0x1e, 0xb6, 0xcb, 0xe2, 0xb8, 0x6e, 0x6c, 0xda, 0x81, 0x1f, 0x27, 0x2a, 0x2a, + 0xd4, 0x72, 0xe3, 0x4d, 0xac, 0x1a, 0xbf, 0x0d, 0x1a, 0x1e, 0xb9, 0x50, 0x84, 0x8c, 0x41, 0x7d, + 0x62, 0x87, 0xa9, 0x72, 0xc7, 0xa9, 0xac, 0xde, 0x07, 0x4b, 0xe1, 0xa8, 0xf7, 0xc1, 0xc4, 0xba, + 0x9a, 0x8c, 0x46, 0x62, 0x59, 0xbe, 0x3c, 0x3c, 0xf1, 0x02, 0xcb, 0x51, 0x02, 0xc9, 0xaa, 0xc6, + 0x5f, 0x54, 0x60, 0x79, 0x2f, 0x0a, 0x6c, 0x11, 0xc7, 0x0f, 0x71, 0x2f, 0xb7, 0xc8, 0x33, 0x63, + 0x50, 0xa7, 0xa0, 0xa2, 0x7c, 0x98, 0x47, 0x65, 0x54, 0x06, 0x19, 0xad, 0xc9, 0x8f, 0x31, 0x35, + 0xae, 0x13, 0x84, 0x4e, 0x31, 0x39, 0x9a, 0x1a, 0xd6, 0x4a, 0x68, 0x0a, 0x47, 0xde, 0x80, 0x5e, + 0xf1, 0x6c, 0x83, 0x7a, 0x50, 0x2f, 0x72, 0x73, 0x28, 0xf5, 0x72, 0x0d, 0xda, 0x91, 0xb0, 0xd0, + 0xdb, 0xa1, 0x6e, 0x1a, 0x44, 0x03, 0x12, 0x84, 0xfd, 0x18, 0x63, 0xe8, 0xef, 0x45, 0x22, 0xb4, + 0x22, 0x81, 0x06, 0x74, 0x42, 0x5c, 0xb9, 0x00, 0x4d, 0x4f, 0xf8, 0xa3, 0x64, 0xac, 0xc6, 0xab, + 0x6a, 0xf9, 0x6b, 0xec, 0x6a, 0xe9, 0x35, 0x36, 0x72, 0x27, 0x12, 0x96, 0x7a, 0xb4, 0x4d, 0x65, + 0x54, 0x56, 0x3f, 0xf5, 0x54, 0xa0, 0x53, 0xe3, 0xb2, 0x62, 0xfc, 0x79, 0x0d, 0xda, 0x8a, 0x33, + 0xf4, 0x15, 0xc9, 0xe7, 0x4a, 0xce, 0xe7, 0x3e, 0xd4, 0xe2, 0xc7, 0x9e, 0x62, 0x3c, 0x16, 0xd9, + 0x87, 0x50, 0xf3, 0xdc, 0x89, 0x3a, 0x07, 0x5d, 0x9e, 0x32, 0xc7, 0xd3, 0xfc, 0x55, 0xc7, 0x59, + 0xa4, 0x66, 0x97, 0xc9, 0x5c, 0x1e, 0x9b, 0xa8, 0x15, 0x8a, 0x27, 0x68, 0x1a, 0x8f, 0x51, 0xf5, + 0x90, 0xa9, 0x96, 0x4d, 0x99, 0xbf, 0xd9, 0x7a, 0xe9, 0x72, 0x5d, 0x41, 0xb6, 0x1d, 0xf6, 0x4d, + 0xd0, 0x62, 0xdf, 0x0a, 0xe3, 0x71, 0x90, 0xa8, 0x73, 0x0f, 0x5b, 0x4b, 0x8e, 0xfd, 0xb5, 0xcd, + 0xdd, 0x83, 0x63, 0x7f, 0x5f, 0x61, 0xd4, 0xc7, 0x72, 0x4a, 0xf6, 0x1d, 0xe8, 0xc4, 0x22, 0x8e, + 0xe5, 0xfb, 0x99, 0x61, 0xa0, 0xd6, 0xd1, 0xf9, 0xf2, 0x99, 0x85, 0xb0, 0x38, 0x6b, 0xd5, 0xb8, + 0x1d, 0x17, 0x20, 0xf6, 0x7d, 0xe8, 0x65, 0xed, 0xbd, 0x60, 0x34, 0x12, 0xd9, 0x0b, 0x89, 0xcb, + 0x73, 0x3d, 0x3c, 0x24, 0x74, 0xa9, 0x9f, 0x6e, 0x5c, 0x46, 0xb0, 0xef, 0x41, 0x2f, 0x94, 0xc2, + 0x34, 0x55, 0x14, 0x5e, 0x2e, 0xc1, 0x4b, 0x53, 0xde, 0xc3, 0x94, 0xb0, 0x8b, 0xec, 0xfa, 0x02, + 0x1e, 0x1b, 0xff, 0x55, 0x81, 0x76, 0x69, 0xd4, 0xf4, 0x46, 0x3e, 0x16, 0x51, 0x16, 0x91, 0xc7, + 0x32, 0xc2, 0xc6, 0x81, 0x7a, 0x5a, 0xaa, 0x73, 0x2a, 0x23, 0x2c, 0x0a, 0xd4, 0x15, 0x8d, 0xce, + 0xa9, 0x8c, 0x36, 0x48, 0x1d, 0x41, 0xe5, 0xcb, 0x3c, 0x12, 0x4a, 0x9d, 0x77, 0x0a, 0xe0, 0x36, + 0x05, 0x98, 0x50, 0x9d, 0x0e, 0xad, 0x38, 0xbb, 0x23, 0xc8, 0xeb, 0xb8, 0xd8, 0x9e, 0x88, 0x08, + 0xc7, 0xa2, 0xcc, 0x57, 0x56, 0x45, 0x59, 0x93, 0xd9, 0x78, 0x16, 0xf8, 0xf2, 0x1a, 0xb6, 0xc3, + 0x35, 0x04, 0xfc, 0x20, 0xf0, 0xa9, 0x99, 0x92, 0x2c, 0xf1, 0x53, 0xe7, 0x59, 0x15, 0x8d, 0xc3, + 0xe3, 0x54, 0xa0, 0x87, 0xe5, 0xd0, 0x1b, 0x4c, 0x9d, 0xb7, 0xa8, 0xbe, 0xed, 0x18, 0xff, 0x56, + 0x81, 0xe5, 0x39, 0x66, 0xa3, 0x43, 0x83, 0x8c, 0xce, 0x1e, 0x3d, 0x74, 0x78, 0x13, 0xab, 0xdb, + 0x0e, 0x21, 0x92, 0x09, 0x29, 0x53, 0x55, 0x21, 0x92, 0x09, 0x6a, 0xd2, 0x79, 0x68, 0x26, 0xc7, + 0x34, 0x5b, 0xb9, 0x30, 0x1a, 0xc9, 0x31, 0x4e, 0x73, 0x03, 0x74, 0x2f, 0x18, 0x99, 0x9e, 0x78, + 0x22, 0x3c, 0xe2, 0x43, 0x6f, 0xfd, 0xed, 0x53, 0xa4, 0xbc, 0xf6, 0x30, 0x18, 0x3d, 0x44, 0x5a, + 0xae, 0x79, 0xaa, 0x64, 0x7c, 0x0a, 0x5a, 0x06, 0x65, 0x3a, 0x34, 0xb6, 0xc4, 0x61, 0x3a, 0xea, + 0x9f, 0x61, 0x1a, 0xd4, 0xb1, 0x45, 0xbf, 0x82, 0xa5, 0x2f, 0xac, 0xc8, 0xef, 0x57, 0x11, 0x7d, + 0x3f, 0x8a, 0x82, 0xa8, 0x5f, 0xc3, 0xe2, 0x9e, 0xe5, 0xbb, 0x76, 0xbf, 0x8e, 0xc5, 0x07, 0x56, + 0x62, 0x79, 0xfd, 0x86, 0xf1, 0x57, 0x0d, 0xd0, 0xf6, 0xd4, 0xd7, 0xd9, 0x16, 0x74, 0xf3, 0xdf, + 0x14, 0x2c, 0x8e, 0xcd, 0xec, 0xcd, 0x16, 0x28, 0x36, 0xd3, 0x09, 0x4b, 0xb5, 0xd9, 0x9f, 0x1d, + 0x54, 0xe7, 0x7e, 0x76, 0x70, 0x05, 0x6a, 0x8f, 0xa3, 0x93, 0xe9, 0x5b, 0xb4, 0x3d, 0xcf, 0xf2, + 0x39, 0x82, 0xd9, 0x07, 0xd0, 0x46, 0xb9, 0x9b, 0x31, 0xed, 0xa8, 0x2a, 0xae, 0x51, 0xfe, 0xa5, + 0x04, 0xc1, 0x39, 0x20, 0x91, 0xda, 0x75, 0xd7, 0x40, 0xb3, 0xc7, 0xae, 0xe7, 0x44, 0xc2, 0x57, + 0xc1, 0x62, 0x36, 0x3f, 0x64, 0x9e, 0xd3, 0xb0, 0xef, 0xd2, 0x33, 0x80, 0x2c, 0x1e, 0x53, 0xce, + 0x42, 0x3a, 0x3f, 0x75, 0xe4, 0xcd, 0x28, 0xf8, 0x52, 0x89, 0x9c, 0x36, 0x97, 0xe2, 0x0d, 0x59, + 0xab, 0xfc, 0x86, 0x4c, 0x3e, 0x80, 0xa7, 0x4d, 0x41, 0xcb, 0x0f, 0x5e, 0x81, 0xe5, 0xb0, 0x9b, + 0x50, 0xf7, 0x03, 0x47, 0xcc, 0x07, 0x33, 0xb2, 0x7d, 0x88, 0x13, 0x9e, 0xfe, 0x6c, 0x91, 0xc6, + 0x63, 0x53, 0xee, 0xe7, 0x68, 0x4a, 0x40, 0xbd, 0x61, 0x4d, 0xe3, 0xf1, 0x16, 0xee, 0xe8, 0xa8, + 0x8c, 0x37, 0xa0, 0x97, 0xcd, 0x45, 0x3d, 0x62, 0x90, 0xc9, 0x17, 0xdd, 0x0c, 0x2a, 0xdf, 0x30, + 0xac, 0xc1, 0x59, 0x7b, 0x6c, 0xf9, 0xbe, 0xf0, 0xcc, 0xc3, 0x74, 0x38, 0xcc, 0x76, 0x80, 0x0e, + 0x5d, 0x36, 0x2e, 0x2b, 0xd4, 0x3d, 0xc2, 0xd0, 0x86, 0x62, 0x40, 0xd7, 0x77, 0x3d, 0xf9, 0xf0, + 0xcf, 0xb4, 0xfd, 0x84, 0xae, 0x91, 0x1b, 0xbc, 0xed, 0xbb, 0x1e, 0xc5, 0x71, 0x37, 0xfd, 0x84, + 0x7d, 0x02, 0xfd, 0x34, 0x75, 0x9d, 0xd8, 0x4c, 0x82, 0xec, 0xdf, 0x01, 0x74, 0x65, 0x3c, 0xe5, + 0x28, 0x3e, 0x4a, 0x5d, 0xe7, 0x20, 0x50, 0x7f, 0x0f, 0xe8, 0x12, 0x7d, 0x56, 0x35, 0x3e, 0x81, + 0x4e, 0x59, 0x77, 0x50, 0x17, 0xe9, 0x04, 0xd5, 0x3f, 0xc3, 0x00, 0x9a, 0xbb, 0x41, 0x34, 0xb1, + 0xbc, 0x7e, 0x05, 0xcb, 0xf2, 0x65, 0x65, 0xbf, 0xca, 0x3a, 0xa0, 0x65, 0xae, 0x7d, 0xbf, 0x66, + 0x7c, 0x0c, 0x5a, 0xf6, 0x33, 0x04, 0x7a, 0x85, 0x1e, 0x38, 0x42, 0x3a, 0x36, 0xd2, 0x32, 0x69, + 0x08, 0x20, 0xa7, 0x26, 0xfb, 0xab, 0x47, 0xb5, 0xf8, 0xab, 0x87, 0xf1, 0x1b, 0xd0, 0x29, 0x0f, + 0x2e, 0x0b, 0xbd, 0x55, 0x8a, 0xd0, 0xdb, 0x82, 0x56, 0x74, 0x57, 0x16, 0x05, 0x13, 0xb3, 0xe4, + 0x04, 0x68, 0x08, 0xc0, 0xcf, 0x18, 0xbf, 0x5f, 0x81, 0x06, 0x79, 0xab, 0xb4, 0xb5, 0x60, 0xa1, + 0x58, 0x3b, 0x0d, 0xae, 0x13, 0x84, 0x66, 0x5a, 0xbe, 0x73, 0xae, 0x3e, 0xff, 0xce, 0xb9, 0x36, + 0x7d, 0xe7, 0xfc, 0x92, 0x49, 0x49, 0xb7, 0x1e, 0x43, 0x53, 0xfe, 0x48, 0x85, 0x2d, 0x43, 0xf7, + 0x91, 0x7f, 0xe4, 0x07, 0x4f, 0x7d, 0x09, 0xe8, 0x9f, 0x61, 0x67, 0x61, 0x29, 0x63, 0xba, 0xfa, + 0x63, 0x4b, 0xbf, 0xc2, 0xfa, 0xd0, 0x21, 0xb1, 0x66, 0x90, 0x2a, 0xbb, 0x02, 0x03, 0xb5, 0x39, + 0x6c, 0x05, 0xbe, 0xd8, 0x0d, 0x12, 0x77, 0x78, 0x92, 0x61, 0x6b, 0x6c, 0x09, 0xda, 0xfb, 0x49, + 0x10, 0xee, 0x0b, 0xdf, 0x71, 0xfd, 0x51, 0xbf, 0x7e, 0xeb, 0x01, 0x34, 0xe5, 0xff, 0x5d, 0x4a, + 0x9f, 0x94, 0x80, 0xfe, 0x19, 0xa4, 0xfe, 0xc2, 0x72, 0x13, 0xd7, 0x1f, 0xed, 0x8a, 0xe3, 0x44, + 0x1a, 0xa5, 0x87, 0x56, 0x9c, 0xf4, 0xab, 0xac, 0x07, 0xa0, 0x7a, 0xbd, 0xef, 0x3b, 0xfd, 0xda, + 0xbd, 0xcd, 0x9f, 0xfc, 0xec, 0x6a, 0xe5, 0x1f, 0x7e, 0x76, 0xb5, 0xf2, 0xcf, 0x3f, 0xbb, 0x7a, + 0xe6, 0x4f, 0xfe, 0xe5, 0x6a, 0xe5, 0x07, 0x1f, 0x94, 0xfe, 0x5e, 0x33, 0xb1, 0x92, 0xc8, 0x3d, + 0x96, 0xb7, 0x8d, 0x59, 0xc5, 0x17, 0x77, 0xc2, 0xa3, 0xd1, 0x9d, 0xf0, 0xf0, 0x4e, 0xa6, 0x73, + 0x87, 0x4d, 0xfa, 0x29, 0xcd, 0x87, 0xff, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xf3, 0xc9, 0xbb, 0x56, + 0x13, 0x47, 0x00, 0x00, } func (m *Message) Marshal() (dAtA []byte, err error) { @@ -9442,7 +9458,7 @@ func (m *DedupJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintPipeline(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x6a + dAtA[i] = 0x7a } } if len(m.UpdateColIdxList) > 0 { @@ -9462,7 +9478,7 @@ func (m *DedupJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], dAtA72[:j71]) i = encodeVarintPipeline(dAtA, i, uint64(j71)) i-- - dAtA[i] = 0x62 + dAtA[i] = 0x72 } if len(m.RightTypes) > 0 { for iNdEx := len(m.RightTypes) - 1; iNdEx >= 0; iNdEx-- { @@ -9475,7 +9491,7 @@ func (m *DedupJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintPipeline(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x5a + dAtA[i] = 0x6a } } if len(m.LeftTypes) > 0 { @@ -9489,7 +9505,7 @@ func (m *DedupJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintPipeline(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x52 + dAtA[i] = 0x62 } } if len(m.DedupColTypes) > 0 { @@ -9503,7 +9519,7 @@ func (m *DedupJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintPipeline(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x4a + dAtA[i] = 0x5a } } if len(m.DedupColName) > 0 { @@ -9511,22 +9527,22 @@ func (m *DedupJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.DedupColName) i = encodeVarintPipeline(dAtA, i, uint64(len(m.DedupColName))) i-- - dAtA[i] = 0x42 + dAtA[i] = 0x52 } if m.OnDuplicateAction != 0 { i = encodeVarintPipeline(dAtA, i, uint64(m.OnDuplicateAction)) i-- - dAtA[i] = 0x38 + dAtA[i] = 0x48 } if m.ShuffleIdx != 0 { i = encodeVarintPipeline(dAtA, i, uint64(m.ShuffleIdx)) i-- - dAtA[i] = 0x30 + dAtA[i] = 0x40 } if m.JoinMapTag != 0 { i = encodeVarintPipeline(dAtA, i, uint64(m.JoinMapTag)) i-- - dAtA[i] = 0x28 + dAtA[i] = 0x38 } if m.IsShuffle { i-- @@ -9536,7 +9552,7 @@ func (m *DedupJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0 } i-- - dAtA[i] = 0x20 + dAtA[i] = 0x30 } if len(m.RuntimeFilterBuildList) > 0 { for iNdEx := len(m.RuntimeFilterBuildList) - 1; iNdEx >= 0; iNdEx-- { @@ -9549,7 +9565,7 @@ func (m *DedupJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintPipeline(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x1a + dAtA[i] = 0x2a } } if len(m.RightCond) > 0 { @@ -9563,7 +9579,7 @@ func (m *DedupJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintPipeline(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x12 + dAtA[i] = 0x22 } } if len(m.LeftCond) > 0 { @@ -9577,9 +9593,47 @@ func (m *DedupJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintPipeline(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0xa + dAtA[i] = 0x1a } } + if len(m.ColList) > 0 { + dAtA74 := make([]byte, len(m.ColList)*10) + var j73 int + for _, num1 := range m.ColList { + num := uint64(num1) + for num >= 1<<7 { + dAtA74[j73] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j73++ + } + dAtA74[j73] = uint8(num) + j73++ + } + i -= j73 + copy(dAtA[i:], dAtA74[:j73]) + i = encodeVarintPipeline(dAtA, i, uint64(j73)) + i-- + dAtA[i] = 0x12 + } + if len(m.RelList) > 0 { + dAtA76 := make([]byte, len(m.RelList)*10) + var j75 int + for _, num1 := range m.RelList { + num := uint64(num1) + for num >= 1<<7 { + dAtA76[j75] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j75++ + } + dAtA76[j75] = uint8(num) + j75++ + } + i -= j75 + copy(dAtA[i:], dAtA76[:j75]) + i = encodeVarintPipeline(dAtA, i, uint64(j75)) + i-- + dAtA[i] = 0xa + } return len(dAtA) - i, nil } @@ -9623,40 +9677,40 @@ func (m *Product) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x18 } if len(m.ColList) > 0 { - dAtA74 := make([]byte, len(m.ColList)*10) - var j73 int + dAtA78 := make([]byte, len(m.ColList)*10) + var j77 int for _, num1 := range m.ColList { num := uint64(num1) for num >= 1<<7 { - dAtA74[j73] = uint8(uint64(num)&0x7f | 0x80) + dAtA78[j77] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j73++ + j77++ } - dAtA74[j73] = uint8(num) - j73++ + dAtA78[j77] = uint8(num) + j77++ } - i -= j73 - copy(dAtA[i:], dAtA74[:j73]) - i = encodeVarintPipeline(dAtA, i, uint64(j73)) + i -= j77 + copy(dAtA[i:], dAtA78[:j77]) + i = encodeVarintPipeline(dAtA, i, uint64(j77)) i-- dAtA[i] = 0x12 } if len(m.RelList) > 0 { - dAtA76 := make([]byte, len(m.RelList)*10) - var j75 int + dAtA80 := make([]byte, len(m.RelList)*10) + var j79 int for _, num1 := range m.RelList { num := uint64(num1) for num >= 1<<7 { - dAtA76[j75] = uint8(uint64(num)&0x7f | 0x80) + dAtA80[j79] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j75++ + j79++ } - dAtA76[j75] = uint8(num) - j75++ + dAtA80[j79] = uint8(num) + j79++ } - i -= j75 - copy(dAtA[i:], dAtA76[:j75]) - i = encodeVarintPipeline(dAtA, i, uint64(j75)) + i -= j79 + copy(dAtA[i:], dAtA80[:j79]) + i = encodeVarintPipeline(dAtA, i, uint64(j79)) i-- dAtA[i] = 0xa } @@ -9705,40 +9759,40 @@ func (m *ProductL2) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x1a } if len(m.ColList) > 0 { - dAtA79 := make([]byte, len(m.ColList)*10) - var j78 int + dAtA83 := make([]byte, len(m.ColList)*10) + var j82 int for _, num1 := range m.ColList { num := uint64(num1) for num >= 1<<7 { - dAtA79[j78] = uint8(uint64(num)&0x7f | 0x80) + dAtA83[j82] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j78++ + j82++ } - dAtA79[j78] = uint8(num) - j78++ + dAtA83[j82] = uint8(num) + j82++ } - i -= j78 - copy(dAtA[i:], dAtA79[:j78]) - i = encodeVarintPipeline(dAtA, i, uint64(j78)) + i -= j82 + copy(dAtA[i:], dAtA83[:j82]) + i = encodeVarintPipeline(dAtA, i, uint64(j82)) i-- dAtA[i] = 0x12 } if len(m.RelList) > 0 { - dAtA81 := make([]byte, len(m.RelList)*10) - var j80 int + dAtA85 := make([]byte, len(m.RelList)*10) + var j84 int for _, num1 := range m.RelList { num := uint64(num1) for num >= 1<<7 { - dAtA81[j80] = uint8(uint64(num)&0x7f | 0x80) + dAtA85[j84] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j80++ + j84++ } - dAtA81[j80] = uint8(num) - j80++ + dAtA85[j84] = uint8(num) + j84++ } - i -= j80 - copy(dAtA[i:], dAtA81[:j80]) - i = encodeVarintPipeline(dAtA, i, uint64(j80)) + i -= j84 + copy(dAtA[i:], dAtA85[:j84]) + i = encodeVarintPipeline(dAtA, i, uint64(j84)) i-- dAtA[i] = 0xa } @@ -9784,21 +9838,21 @@ func (m *IndexJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) { } } if len(m.Result) > 0 { - dAtA83 := make([]byte, len(m.Result)*10) - var j82 int + dAtA87 := make([]byte, len(m.Result)*10) + var j86 int for _, num1 := range m.Result { num := uint64(num1) for num >= 1<<7 { - dAtA83[j82] = uint8(uint64(num)&0x7f | 0x80) + dAtA87[j86] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j82++ + j86++ } - dAtA83[j82] = uint8(num) - j82++ + dAtA87[j86] = uint8(num) + j86++ } - i -= j82 - copy(dAtA[i:], dAtA83[:j82]) - i = encodeVarintPipeline(dAtA, i, uint64(j82)) + i -= j86 + copy(dAtA[i:], dAtA87[:j86]) + i = encodeVarintPipeline(dAtA, i, uint64(j86)) i-- dAtA[i] = 0xa } @@ -9947,21 +10001,21 @@ func (m *FileOffset) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.XXX_unrecognized) } if len(m.Offset) > 0 { - dAtA85 := make([]byte, len(m.Offset)*10) - var j84 int + dAtA89 := make([]byte, len(m.Offset)*10) + var j88 int for _, num1 := range m.Offset { num := uint64(num1) for num >= 1<<7 { - dAtA85[j84] = uint8(uint64(num)&0x7f | 0x80) + dAtA89[j88] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j84++ + j88++ } - dAtA85[j84] = uint8(num) - j84++ + dAtA89[j88] = uint8(num) + j88++ } - i -= j84 - copy(dAtA[i:], dAtA85[:j84]) - i = encodeVarintPipeline(dAtA, i, uint64(j84)) + i -= j88 + copy(dAtA[i:], dAtA89[:j88]) + i = encodeVarintPipeline(dAtA, i, uint64(j88)) i-- dAtA[i] = 0xa } @@ -10104,21 +10158,21 @@ func (m *ExternalScan) MarshalToSizedBuffer(dAtA []byte) (int, error) { } } if len(m.FileSize) > 0 { - dAtA88 := make([]byte, len(m.FileSize)*10) - var j87 int + dAtA92 := make([]byte, len(m.FileSize)*10) + var j91 int for _, num1 := range m.FileSize { num := uint64(num1) for num >= 1<<7 { - dAtA88[j87] = uint8(uint64(num)&0x7f | 0x80) + dAtA92[j91] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j87++ + j91++ } - dAtA88[j87] = uint8(num) - j87++ + dAtA92[j91] = uint8(num) + j91++ } - i -= j87 - copy(dAtA[i:], dAtA88[:j87]) - i = encodeVarintPipeline(dAtA, i, uint64(j87)) + i -= j91 + copy(dAtA[i:], dAtA92[:j91]) + i = encodeVarintPipeline(dAtA, i, uint64(j91)) i-- dAtA[i] = 0x12 } @@ -11953,40 +12007,40 @@ func (m *Pipeline) MarshalToSizedBuffer(dAtA []byte) (int, error) { } } if len(m.NilBatchCnt) > 0 { - dAtA144 := make([]byte, len(m.NilBatchCnt)*10) - var j143 int + dAtA148 := make([]byte, len(m.NilBatchCnt)*10) + var j147 int for _, num1 := range m.NilBatchCnt { num := uint64(num1) for num >= 1<<7 { - dAtA144[j143] = uint8(uint64(num)&0x7f | 0x80) + dAtA148[j147] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j143++ + j147++ } - dAtA144[j143] = uint8(num) - j143++ + dAtA148[j147] = uint8(num) + j147++ } - i -= j143 - copy(dAtA[i:], dAtA144[:j143]) - i = encodeVarintPipeline(dAtA, i, uint64(j143)) + i -= j147 + copy(dAtA[i:], dAtA148[:j147]) + i = encodeVarintPipeline(dAtA, i, uint64(j147)) i-- dAtA[i] = 0x6a } if len(m.ChannelBufferSize) > 0 { - dAtA146 := make([]byte, len(m.ChannelBufferSize)*10) - var j145 int + dAtA150 := make([]byte, len(m.ChannelBufferSize)*10) + var j149 int for _, num1 := range m.ChannelBufferSize { num := uint64(num1) for num >= 1<<7 { - dAtA146[j145] = uint8(uint64(num)&0x7f | 0x80) + dAtA150[j149] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j145++ + j149++ } - dAtA146[j145] = uint8(num) - j145++ + dAtA150[j149] = uint8(num) + j149++ } - i -= j145 - copy(dAtA[i:], dAtA146[:j145]) - i = encodeVarintPipeline(dAtA, i, uint64(j145)) + i -= j149 + copy(dAtA[i:], dAtA150[:j149]) + i = encodeVarintPipeline(dAtA, i, uint64(j149)) i-- dAtA[i] = 0x62 } @@ -12223,40 +12277,40 @@ func (m *Apply) MarshalToSizedBuffer(dAtA []byte) (int, error) { } } if len(m.ColList) > 0 { - dAtA151 := make([]byte, len(m.ColList)*10) - var j150 int + dAtA155 := make([]byte, len(m.ColList)*10) + var j154 int for _, num1 := range m.ColList { num := uint64(num1) for num >= 1<<7 { - dAtA151[j150] = uint8(uint64(num)&0x7f | 0x80) + dAtA155[j154] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j150++ + j154++ } - dAtA151[j150] = uint8(num) - j150++ + dAtA155[j154] = uint8(num) + j154++ } - i -= j150 - copy(dAtA[i:], dAtA151[:j150]) - i = encodeVarintPipeline(dAtA, i, uint64(j150)) + i -= j154 + copy(dAtA[i:], dAtA155[:j154]) + i = encodeVarintPipeline(dAtA, i, uint64(j154)) i-- dAtA[i] = 0x1a } if len(m.RelList) > 0 { - dAtA153 := make([]byte, len(m.RelList)*10) - var j152 int + dAtA157 := make([]byte, len(m.RelList)*10) + var j156 int for _, num1 := range m.RelList { num := uint64(num1) for num >= 1<<7 { - dAtA153[j152] = uint8(uint64(num)&0x7f | 0x80) + dAtA157[j156] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j152++ + j156++ } - dAtA153[j152] = uint8(num) - j152++ + dAtA157[j156] = uint8(num) + j156++ } - i -= j152 - copy(dAtA[i:], dAtA153[:j152]) - i = encodeVarintPipeline(dAtA, i, uint64(j152)) + i -= j156 + copy(dAtA[i:], dAtA157[:j156]) + i = encodeVarintPipeline(dAtA, i, uint64(j156)) i-- dAtA[i] = 0x12 } @@ -13606,6 +13660,20 @@ func (m *DedupJoin) ProtoSize() (n int) { } var l int _ = l + if len(m.RelList) > 0 { + l = 0 + for _, e := range m.RelList { + l += sovPipeline(uint64(e)) + } + n += 1 + sovPipeline(uint64(l)) + l + } + if len(m.ColList) > 0 { + l = 0 + for _, e := range m.ColList { + l += sovPipeline(uint64(e)) + } + n += 1 + sovPipeline(uint64(l)) + l + } if len(m.LeftCond) > 0 { for _, e := range m.LeftCond { l = e.ProtoSize() @@ -23616,6 +23684,158 @@ func (m *DedupJoin) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: + if wireType == 0 { + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPipeline + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.RelList = append(m.RelList, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPipeline + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthPipeline + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthPipeline + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } + } + elementCount = count + if elementCount != 0 && len(m.RelList) == 0 { + m.RelList = make([]int32, 0, elementCount) + } + for iNdEx < postIndex { + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPipeline + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.RelList = append(m.RelList, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field RelList", wireType) + } + case 2: + if wireType == 0 { + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPipeline + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.ColList = append(m.ColList, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPipeline + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthPipeline + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthPipeline + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } + } + elementCount = count + if elementCount != 0 && len(m.ColList) == 0 { + m.ColList = make([]int32, 0, elementCount) + } + for iNdEx < postIndex { + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPipeline + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.ColList = append(m.ColList, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field ColList", wireType) + } + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field LeftCond", wireType) } @@ -23649,7 +23869,7 @@ func (m *DedupJoin) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 2: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field RightCond", wireType) } @@ -23683,7 +23903,7 @@ func (m *DedupJoin) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 3: + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field RuntimeFilterBuildList", wireType) } @@ -23717,7 +23937,7 @@ func (m *DedupJoin) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 4: + case 6: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field IsShuffle", wireType) } @@ -23737,7 +23957,7 @@ func (m *DedupJoin) Unmarshal(dAtA []byte) error { } } m.IsShuffle = bool(v != 0) - case 5: + case 7: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field JoinMapTag", wireType) } @@ -23756,7 +23976,7 @@ func (m *DedupJoin) Unmarshal(dAtA []byte) error { break } } - case 6: + case 8: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field ShuffleIdx", wireType) } @@ -23775,7 +23995,7 @@ func (m *DedupJoin) Unmarshal(dAtA []byte) error { break } } - case 7: + case 9: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field OnDuplicateAction", wireType) } @@ -23794,7 +24014,7 @@ func (m *DedupJoin) Unmarshal(dAtA []byte) error { break } } - case 8: + case 10: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field DedupColName", wireType) } @@ -23826,7 +24046,7 @@ func (m *DedupJoin) Unmarshal(dAtA []byte) error { } m.DedupColName = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 9: + case 11: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field DedupColTypes", wireType) } @@ -23860,7 +24080,7 @@ func (m *DedupJoin) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 10: + case 12: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field LeftTypes", wireType) } @@ -23894,7 +24114,7 @@ func (m *DedupJoin) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 11: + case 13: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field RightTypes", wireType) } @@ -23928,7 +24148,7 @@ func (m *DedupJoin) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 12: + case 14: if wireType == 0 { var v int32 for shift := uint(0); ; shift += 7 { @@ -24004,7 +24224,7 @@ func (m *DedupJoin) Unmarshal(dAtA []byte) error { } else { return fmt.Errorf("proto: wrong wireType = %d for field UpdateColIdxList", wireType) } - case 13: + case 15: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field UpdateColExprList", wireType) } diff --git a/pkg/sql/colexec/lockop/lock_op.go b/pkg/sql/colexec/lockop/lock_op.go index 33951b628e4ee..ed89c8731e7aa 100644 --- a/pkg/sql/colexec/lockop/lock_op.go +++ b/pkg/sql/colexec/lockop/lock_op.go @@ -1014,10 +1014,6 @@ func lockTalbeIfLockCountIsZero( } for idx := 0; idx < len(lockOp.targets); idx++ { target := lockOp.targets[idx] - // do not lock table or rows at the end for hidden table - if !target.lockTableAtTheEnd { - continue - } if target.lockRows != nil { vec, free, err := colexec.GetReadonlyResultFromNoColumnExpression(proc, target.lockRows) if err != nil { @@ -1039,6 +1035,9 @@ func lockTalbeIfLockCountIsZero( return err } } else { + if !target.lockTableAtTheEnd { + continue + } err := LockTable(lockOp.engine, proc, target.tableID, target.primaryColumnType, false) if err != nil { return err diff --git a/pkg/sql/compile/compile.go b/pkg/sql/compile/compile.go index 67258fa7a1221..9701a2c424926 100644 --- a/pkg/sql/compile/compile.go +++ b/pkg/sql/compile/compile.go @@ -3768,7 +3768,10 @@ func (c *Compile) newShuffleJoinScopeList(probeScopes, buildScopes []*Scope, n * } } - dop := plan2.GetShuffleDop(c.ncpu, len(cnlist), n.Stats.HashmapStats.HashmapSize) + dop := c.ncpu //for dedup join, limit the dop max to ncpu + if n.JoinType != plan.Node_DEDUP { + dop = plan2.GetShuffleDop(c.ncpu, len(cnlist), n.Stats.HashmapStats.HashmapSize) + } bucketNum := len(cnlist) * dop shuffleJoins := make([]*Scope, 0, bucketNum) diff --git a/pkg/sql/compile/compile2.go b/pkg/sql/compile/compile2.go index 6337dd383f5d5..d1e653e4e1aad 100644 --- a/pkg/sql/compile/compile2.go +++ b/pkg/sql/compile/compile2.go @@ -141,7 +141,6 @@ func (c *Compile) Run(_ uint64) (queryResult *util2.RunResult, err error) { // init context for pipeline. c.proc.ResetQueryContext() - c.proc.ResetCloneTxnOperator() c.InitPipelineContextToExecuteQuery() // record this query to compile service. diff --git a/pkg/sql/compile/operator.go b/pkg/sql/compile/operator.go index a573fbc4120e4..420e7eaa41add 100644 --- a/pkg/sql/compile/operator.go +++ b/pkg/sql/compile/operator.go @@ -561,13 +561,13 @@ func dupOperator(sourceOp vm.Operator, index int, maxParallel int) vm.Operator { op.Channel = t.Channel op.NumCPU = uint64(maxParallel) op.IsMerger = (index == 0) - op.Result = append(op.Result, t.Result...) + op.Result = t.Result op.LeftTypes = t.LeftTypes - op.RightTypes = append(op.RightTypes, t.RightTypes...) - op.Conditions = append(op.Conditions, t.Conditions...) + op.RightTypes = t.RightTypes + op.Conditions = t.Conditions op.IsShuffle = t.IsShuffle op.ShuffleIdx = t.ShuffleIdx - op.RuntimeFilterSpecs = append(op.RuntimeFilterSpecs, t.RuntimeFilterSpecs...) + op.RuntimeFilterSpecs = t.RuntimeFilterSpecs op.JoinMapTag = t.JoinMapTag op.OnDuplicateAction = t.OnDuplicateAction op.DedupColName = t.DedupColName diff --git a/pkg/sql/compile/remoterun.go b/pkg/sql/compile/remoterun.go index c180add9a753c..57a580f18d5b9 100644 --- a/pkg/sql/compile/remoterun.go +++ b/pkg/sql/compile/remoterun.go @@ -801,7 +801,10 @@ func convertToPipelineInstruction(op vm.Operator, proc *process.Process, ctx *sc RuntimeFilterSpec: t.RuntimeFilterSpec, } case *dedupjoin.DedupJoin: + relList, colList := getRelColList(t.Result) in.DedupJoin = &pipeline.DedupJoin{ + RelList: relList, + ColList: colList, LeftCond: t.Conditions[0], RightCond: t.Conditions[1], RuntimeFilterBuildList: t.RuntimeFilterSpecs, @@ -1334,6 +1337,9 @@ func convertToVmOperator(opr *pipeline.Instruction, ctx *scopeContext, eng engin case vm.DedupJoin: arg := dedupjoin.NewArgument() t := opr.GetDedupJoin() + arg.Result = convertToResultPos(t.RelList, t.ColList) + arg.LeftTypes = convertToTypes(t.LeftTypes) + arg.RightTypes = convertToTypes(t.RightTypes) arg.Conditions = [][]*plan.Expr{t.LeftCond, t.RightCond} arg.RuntimeFilterSpecs = t.RuntimeFilterBuildList arg.IsShuffle = t.IsShuffle @@ -1342,8 +1348,6 @@ func convertToVmOperator(opr *pipeline.Instruction, ctx *scopeContext, eng engin arg.OnDuplicateAction = t.OnDuplicateAction arg.DedupColName = t.DedupColName arg.DedupColTypes = t.DedupColTypes - arg.LeftTypes = convertToTypes(t.LeftTypes) - arg.RightTypes = convertToTypes(t.RightTypes) arg.UpdateColIdxList = t.UpdateColIdxList arg.UpdateColExprList = t.UpdateColExprList op = arg diff --git a/pkg/sql/compile/remoterun_test.go b/pkg/sql/compile/remoterun_test.go index d4f75a3a029ed..ad59815b88268 100644 --- a/pkg/sql/compile/remoterun_test.go +++ b/pkg/sql/compile/remoterun_test.go @@ -19,45 +19,33 @@ import ( "testing" "time" + "github.com/golang/mock/gomock" + "github.com/google/uuid" + "github.com/matrixorigin/matrixone/pkg/catalog" "github.com/matrixorigin/matrixone/pkg/common/moerr" "github.com/matrixorigin/matrixone/pkg/common/morpc" - "github.com/matrixorigin/matrixone/pkg/pb/txn" - "github.com/matrixorigin/matrixone/pkg/sql/colexec/connector" - "github.com/matrixorigin/matrixone/pkg/sql/colexec/value_scan" - "github.com/matrixorigin/matrixone/pkg/testutil" - "github.com/matrixorigin/matrixone/pkg/txn/client" - - "github.com/matrixorigin/matrixone/pkg/sql/colexec" - - "github.com/matrixorigin/matrixone/pkg/catalog" + "github.com/matrixorigin/matrixone/pkg/common/mpool" + "github.com/matrixorigin/matrixone/pkg/common/reuse" "github.com/matrixorigin/matrixone/pkg/container/batch" "github.com/matrixorigin/matrixone/pkg/container/types" "github.com/matrixorigin/matrixone/pkg/container/vector" "github.com/matrixorigin/matrixone/pkg/defines" - "github.com/matrixorigin/matrixone/pkg/sql/colexec/aggexec" - "github.com/matrixorigin/matrixone/pkg/sql/colexec/apply" - "github.com/matrixorigin/matrixone/pkg/sql/colexec/hashbuild" - "github.com/matrixorigin/matrixone/pkg/sql/colexec/indexbuild" - "github.com/matrixorigin/matrixone/pkg/sql/colexec/postdml" - "github.com/matrixorigin/matrixone/pkg/sql/colexec/shufflebuild" - - "github.com/matrixorigin/matrixone/pkg/common/mpool" - "github.com/matrixorigin/matrixone/pkg/common/reuse" - - "github.com/golang/mock/gomock" - "github.com/google/uuid" - "github.com/stretchr/testify/require" - - "github.com/matrixorigin/matrixone/pkg/sql/colexec/source" - mock_frontend "github.com/matrixorigin/matrixone/pkg/frontend/test" "github.com/matrixorigin/matrixone/pkg/pb/pipeline" + "github.com/matrixorigin/matrixone/pkg/pb/txn" + "github.com/matrixorigin/matrixone/pkg/sql/colexec" + "github.com/matrixorigin/matrixone/pkg/sql/colexec/aggexec" "github.com/matrixorigin/matrixone/pkg/sql/colexec/anti" + "github.com/matrixorigin/matrixone/pkg/sql/colexec/apply" + "github.com/matrixorigin/matrixone/pkg/sql/colexec/connector" + "github.com/matrixorigin/matrixone/pkg/sql/colexec/dedupjoin" "github.com/matrixorigin/matrixone/pkg/sql/colexec/deletion" "github.com/matrixorigin/matrixone/pkg/sql/colexec/dispatch" "github.com/matrixorigin/matrixone/pkg/sql/colexec/external" "github.com/matrixorigin/matrixone/pkg/sql/colexec/filter" "github.com/matrixorigin/matrixone/pkg/sql/colexec/group" + "github.com/matrixorigin/matrixone/pkg/sql/colexec/hashbuild" + "github.com/matrixorigin/matrixone/pkg/sql/colexec/indexbuild" "github.com/matrixorigin/matrixone/pkg/sql/colexec/insert" "github.com/matrixorigin/matrixone/pkg/sql/colexec/intersect" "github.com/matrixorigin/matrixone/pkg/sql/colexec/intersectall" @@ -75,6 +63,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/sql/colexec/offset" "github.com/matrixorigin/matrixone/pkg/sql/colexec/onduplicatekey" "github.com/matrixorigin/matrixone/pkg/sql/colexec/order" + "github.com/matrixorigin/matrixone/pkg/sql/colexec/postdml" "github.com/matrixorigin/matrixone/pkg/sql/colexec/preinsert" "github.com/matrixorigin/matrixone/pkg/sql/colexec/preinsertunique" "github.com/matrixorigin/matrixone/pkg/sql/colexec/product" @@ -84,12 +73,18 @@ import ( "github.com/matrixorigin/matrixone/pkg/sql/colexec/rightsemi" "github.com/matrixorigin/matrixone/pkg/sql/colexec/semi" "github.com/matrixorigin/matrixone/pkg/sql/colexec/shuffle" + "github.com/matrixorigin/matrixone/pkg/sql/colexec/shufflebuild" "github.com/matrixorigin/matrixone/pkg/sql/colexec/single" + "github.com/matrixorigin/matrixone/pkg/sql/colexec/source" "github.com/matrixorigin/matrixone/pkg/sql/colexec/table_function" "github.com/matrixorigin/matrixone/pkg/sql/colexec/top" + "github.com/matrixorigin/matrixone/pkg/sql/colexec/value_scan" "github.com/matrixorigin/matrixone/pkg/sql/plan" + "github.com/matrixorigin/matrixone/pkg/testutil" + "github.com/matrixorigin/matrixone/pkg/txn/client" "github.com/matrixorigin/matrixone/pkg/vm" "github.com/matrixorigin/matrixone/pkg/vm/process" + "github.com/stretchr/testify/require" ) func Test_EncodeProcessInfo(t *testing.T) { @@ -245,7 +240,13 @@ func Test_convertToPipelineInstruction(t *testing.T) { &source.Source{}, &apply.Apply{TableFunction: &table_function.TableFunction{}}, &postdml.PostDml{ - PostDmlCtx: &postdml.PostDmlCtx{FullText: &postdml.PostDmlFullTextCtx{}}}, + PostDmlCtx: &postdml.PostDmlCtx{ + FullText: &postdml.PostDmlFullTextCtx{}, + }, + }, + &dedupjoin.DedupJoin{ + Conditions: [][]*plan.Expr{nil, nil}, + }, } ctx := &scopeContext{ id: 1, @@ -321,6 +322,7 @@ func Test_convertToVmInstruction(t *testing.T) { {Op: int32(vm.IndexBuild), IndexBuild: &pipeline.Indexbuild{}}, {Op: int32(vm.Apply), Apply: &pipeline.Apply{}, TableFunction: &pipeline.TableFunction{}}, {Op: int32(vm.PostDml), PostDml: &pipeline.PostDml{}}, + {Op: int32(vm.DedupJoin), DedupJoin: &pipeline.DedupJoin{}}, } for _, instruction := range instructions { _, err := convertToVmOperator(instruction, ctx, nil) diff --git a/pkg/sql/plan/function/func_builtin.go b/pkg/sql/plan/function/func_builtin.go index c02dd91758e8c..a84734a1d40f2 100644 --- a/pkg/sql/plan/function/func_builtin.go +++ b/pkg/sql/plan/function/func_builtin.go @@ -1175,61 +1175,202 @@ func builtInHash(parameters []*vector.Vector, result vector.FunctionResultWrappe // result vec is [serial(1, 2, 3), serial(1, 2, 3), null] func (op *opSerial) BuiltInSerial(parameters []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int, selectList *FunctionSelectList) error { rs := vector.MustFunctionResult[types.Varlena](result) + var err error + + bitMap := new(nulls.Nulls) for _, v := range parameters { if v.AllNull() { rs.SetNullResult(uint64(length)) return nil } + bitMap.Merge(v.GetNulls()) } - op.tryExpand(length, proc.Mp()) - bitMap := new(nulls.Nulls) - for _, v := range parameters { - SerialHelper(v, bitMap, op.ps, false) + if len(op.funcs) == 0 { + op.funcs = make([]func(v *vector.Vector, idx int, ps *types.Packer), len(parameters)) + for i, p := range parameters { + op.funcs[i], err = getPackFun(p) + if err != nil { + return err + } + } } - //NOTE: make sure to use uint64(length) instead of len(op.ps[i]) - // as length of packer array could be larger than length of input vectors - for i := uint64(0); i < uint64(length); i++ { - if bitMap.Contains(i) { - if err := rs.AppendBytes(nil, true); err != nil { - return err + if bitMap.IsEmpty() { + for i := 0; i < length; i++ { + op.packer.Reset() + for j, p := range parameters { + op.funcs[j](p, i, op.packer) } - } else { - if err := rs.AppendBytes(op.ps[i].GetBuf(), false); err != nil { + if err = rs.AppendBytes(op.packer.GetBuf(), false); err != nil { return err } } + } else { + for i := 0; i < length; i++ { + if bitMap.Contains(uint64(i)) { + if err = rs.AppendBytes(nil, true); err != nil { + return err + } + } else { + op.packer.Reset() + for j, p := range parameters { + op.funcs[j](p, i, op.packer) + } + if err = rs.AppendBytes(op.packer.GetBuf(), false); err != nil { + return err + } + } + } } return nil } func (op *opSerial) BuiltInSerialFull(parameters []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int, selectList *FunctionSelectList) error { - rs := vector.MustFunctionResult[types.Varlena](result) - op.tryExpand(length, proc.Mp()) - for _, v := range parameters { - if v.IsConstNull() { - for i := 0; i < v.Length(); i++ { - op.ps[i].EncodeNull() + var err error + if len(op.funcs) == 0 { + op.funcs = make([]func(v *vector.Vector, idx int, ps *types.Packer), len(parameters)) + for i, p := range parameters { + if !p.IsConstNull() { + op.funcs[i], err = getPackFun(p) + if err != nil { + return err + } } - continue } - - SerialHelper(v, nil, op.ps, true) } - //NOTE: make sure to use uint64(length) instead of len(op.ps[i]) - // as length of packer array could be larger than length of input vectors - for i := uint64(0); i < uint64(length); i++ { - if err := rs.AppendBytes(op.ps[i].GetBuf(), false); err != nil { + for i := 0; i < length; i++ { + op.packer.Reset() + for j, p := range parameters { + if p.IsNull(uint64(i)) { + op.packer.EncodeNull() + } else { + op.funcs[j](p, i, op.packer) + } + } + if err = rs.AppendBytes(op.packer.GetBuf(), false); err != nil { return err } } return nil } +func getPackFun(v *vector.Vector) (func(v *vector.Vector, idx int, ps *types.Packer), error) { + switch v.GetType().Oid { + case types.T_bool: + return func(v *vector.Vector, idx int, ps *types.Packer) { + val := vector.GetFixedAtNoTypeCheck[bool](v, idx) + ps.EncodeBool(val) + }, nil + case types.T_bit: + return func(v *vector.Vector, idx int, ps *types.Packer) { + val := vector.GetFixedAtNoTypeCheck[uint64](v, idx) + ps.EncodeUint64(val) + }, nil + case types.T_int8: + return func(v *vector.Vector, idx int, ps *types.Packer) { + val := vector.GetFixedAtNoTypeCheck[int8](v, idx) + ps.EncodeInt8(val) + }, nil + case types.T_int16: + return func(v *vector.Vector, idx int, ps *types.Packer) { + val := vector.GetFixedAtNoTypeCheck[int16](v, idx) + ps.EncodeInt16(val) + }, nil + case types.T_int32: + return func(v *vector.Vector, idx int, ps *types.Packer) { + val := vector.GetFixedAtNoTypeCheck[int32](v, idx) + ps.EncodeInt32(val) + }, nil + case types.T_int64: + return func(v *vector.Vector, idx int, ps *types.Packer) { + val := vector.GetFixedAtNoTypeCheck[int64](v, idx) + ps.EncodeInt64(val) + }, nil + case types.T_uint8: + return func(v *vector.Vector, idx int, ps *types.Packer) { + val := vector.GetFixedAtNoTypeCheck[uint8](v, idx) + ps.EncodeUint8(val) + }, nil + case types.T_uint16: + return func(v *vector.Vector, idx int, ps *types.Packer) { + val := vector.GetFixedAtNoTypeCheck[uint16](v, idx) + ps.EncodeUint16(val) + }, nil + case types.T_uint32: + return func(v *vector.Vector, idx int, ps *types.Packer) { + val := vector.GetFixedAtNoTypeCheck[uint32](v, idx) + ps.EncodeUint32(val) + }, nil + case types.T_uint64: + return func(v *vector.Vector, idx int, ps *types.Packer) { + val := vector.GetFixedAtNoTypeCheck[uint64](v, idx) + ps.EncodeUint64(val) + }, nil + case types.T_float32: + return func(v *vector.Vector, idx int, ps *types.Packer) { + val := vector.GetFixedAtNoTypeCheck[float32](v, idx) + ps.EncodeFloat32(val) + }, nil + case types.T_float64: + return func(v *vector.Vector, idx int, ps *types.Packer) { + val := vector.GetFixedAtNoTypeCheck[float64](v, idx) + ps.EncodeFloat64(val) + }, nil + case types.T_date: + return func(v *vector.Vector, idx int, ps *types.Packer) { + val := vector.GetFixedAtNoTypeCheck[types.Date](v, idx) + ps.EncodeDate(val) + }, nil + case types.T_time: + return func(v *vector.Vector, idx int, ps *types.Packer) { + val := vector.GetFixedAtNoTypeCheck[types.Time](v, idx) + ps.EncodeTime(val) + }, nil + case types.T_datetime: + return func(v *vector.Vector, idx int, ps *types.Packer) { + val := vector.GetFixedAtNoTypeCheck[types.Datetime](v, idx) + ps.EncodeDatetime(val) + }, nil + case types.T_timestamp: + return func(v *vector.Vector, idx int, ps *types.Packer) { + val := vector.GetFixedAtNoTypeCheck[types.Timestamp](v, idx) + ps.EncodeTimestamp(val) + }, nil + case types.T_enum: + return func(v *vector.Vector, idx int, ps *types.Packer) { + val := vector.GetFixedAtNoTypeCheck[types.Enum](v, idx) + ps.EncodeEnum(val) + }, nil + case types.T_decimal64: + return func(v *vector.Vector, idx int, ps *types.Packer) { + val := vector.GetFixedAtNoTypeCheck[types.Decimal64](v, idx) + ps.EncodeDecimal64(val) + }, nil + case types.T_decimal128: + return func(v *vector.Vector, idx int, ps *types.Packer) { + val := vector.GetFixedAtNoTypeCheck[types.Decimal128](v, idx) + ps.EncodeDecimal128(val) + }, nil + case types.T_uuid: + return func(v *vector.Vector, idx int, ps *types.Packer) { + val := vector.GetFixedAtNoTypeCheck[types.Uuid](v, idx) + ps.EncodeUuid(val) + }, nil + case types.T_json, types.T_char, types.T_varchar, types.T_binary, types.T_varbinary, types.T_blob, types.T_text, + types.T_array_float32, types.T_array_float64, types.T_datalink: + return func(v *vector.Vector, idx int, ps *types.Packer) { + val := v.GetBytesAt(idx) + ps.EncodeStringType(val) + }, nil + } + + return nil, moerr.NewInternalErrorNoCtxf("not supported type %s", v.GetType().String()) +} + // SerialHelper is unified function used in builtInSerial and BuiltInSerialFull // To use it inside builtInSerial, pass the bitMap pointer and set isFull false // To use it inside BuiltInSerialFull, pass the bitMap as nil and set isFull to true diff --git a/pkg/sql/plan/function/func_builtin_serial.go b/pkg/sql/plan/function/func_builtin_serial.go index f22e2b540c262..58468680cd6d7 100644 --- a/pkg/sql/plan/function/func_builtin_serial.go +++ b/pkg/sql/plan/function/func_builtin_serial.go @@ -15,39 +15,22 @@ package function import ( - "github.com/matrixorigin/matrixone/pkg/common/mpool" "github.com/matrixorigin/matrixone/pkg/container/types" + "github.com/matrixorigin/matrixone/pkg/container/vector" ) type opSerial struct { - ps []*types.Packer + packer *types.Packer + funcs []func(v *vector.Vector, idx int, ps *types.Packer) } func newOpSerial() *opSerial { return &opSerial{ - ps: make([]*types.Packer, 0), - } -} - -func (op *opSerial) tryExpand(length int, mp *mpool.MPool) { - if len(op.ps) < length { - // close the current packer array - for _, p := range op.ps { - p.Close() - } - - // create a new packer array with the new length - op.ps = types.NewPackerArray(length) - } - - for _, p := range op.ps { - p.Reset() + packer: types.NewPacker(), } } func (op *opSerial) Close() error { - for _, p := range op.ps { - p.Close() - } + op.packer.Close() return nil } diff --git a/pkg/sql/plan/opt_misc.go b/pkg/sql/plan/opt_misc.go index 2617bf518d994..85d51b981ba4d 100644 --- a/pkg/sql/plan/opt_misc.go +++ b/pkg/sql/plan/opt_misc.go @@ -1155,9 +1155,6 @@ func (builder *QueryBuilder) lockTableIfLockNoRowsAtTheEndForDelAndUpdate() (err return } tableDef := baseNode.TableDef - if !getLockTableAtTheEnd(tableDef) { - return - } objRef := baseNode.ObjRef tableIDs := make(map[uint64]bool) tableIDs[tableDef.TblId] = true @@ -1229,7 +1226,7 @@ func (builder *QueryBuilder) lockTableIfLockNoRowsAtTheEndForDelAndUpdate() (err } lockTarget.LockRows = lockRows - lockTarget.LockTableAtTheEnd = true + lockTarget.LockTableAtTheEnd = false } return diff --git a/pkg/sql/plan/order_binder.go b/pkg/sql/plan/order_binder.go index ac837f2223615..7c7e75455640b 100644 --- a/pkg/sql/plan/order_binder.go +++ b/pkg/sql/plan/order_binder.go @@ -17,6 +17,7 @@ package plan import ( "github.com/matrixorigin/matrixone/pkg/common/moerr" "github.com/matrixorigin/matrixone/pkg/pb/plan" + "github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect" "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" ) @@ -53,22 +54,18 @@ func (b *OrderBinder) BindExpr(astExpr tree.Expr) (*plan.Expr, error) { }, }, nil } else { - var matchedFields []int32 // SelectField index used to record matches + // SelectField index used to record matches + matchedFields := make(map[string]int) var matchedExpr *plan.Expr // Used to save matched expr for _, selectField := range b.ctx.projectByAst { + // alias has already been matched earlier, no further processing is needed if selectField.aliasName != "" { - if selectField.aliasName == colRef.ColName() { - // Record the selectField index that matches - matchedFields = append(matchedFields, selectField.pos) - // Save matching expr - matchedExpr = b.ctx.projects[selectField.pos] - } else { - continue - } + continue } else if projectField, ok1 := selectField.ast.(*tree.UnresolvedName); ok1 && projectField.ColName() == colRef.ColName() { // Record the selectField index that matches - matchedFields = append(matchedFields, selectField.pos) + field := tree.String(selectField.ast, dialect.MYSQL) + matchedFields[field] += 1 // Save matching expr matchedExpr = &plan.Expr{ Typ: b.ctx.projects[selectField.pos].Typ, diff --git a/pkg/sql/plan/query_builder.go b/pkg/sql/plan/query_builder.go index 4f751024c5c81..91c0a6edf2466 100644 --- a/pkg/sql/plan/query_builder.go +++ b/pkg/sql/plan/query_builder.go @@ -2709,7 +2709,6 @@ func (builder *QueryBuilder) bindSelect(stmt *tree.Select, ctx *BindContext, isR PrimaryColTyp: pkTyp, Block: true, RefreshTsIdxInBat: -1, //unsupport now - LockTableAtTheEnd: getLockTableAtTheEnd(tableDef), } if tableDef.Partition != nil { partTableIDs, _ := getPartTableIdsAndNames(builder.compCtx, objRef, tableDef) diff --git a/pkg/sql/plan/stats.go b/pkg/sql/plan/stats.go index 2f6d3e49e75b4..2ff50973a2645 100644 --- a/pkg/sql/plan/stats.go +++ b/pkg/sql/plan/stats.go @@ -880,50 +880,64 @@ func ReCalcNodeStats(nodeID int32, builder *QueryBuilder, recursive bool, leafNo node.Stats.Cost = leftStats.Cost + rightStats.Cost node.Stats.HashmapStats.HashmapSize = rightStats.Outcnt node.Stats.Selectivity = selectivity_out + node.Stats.BlockNum = leftStats.BlockNum case plan.Node_LEFT: node.Stats.Outcnt = leftStats.Outcnt node.Stats.Cost = leftStats.Cost + rightStats.Cost node.Stats.HashmapStats.HashmapSize = rightStats.Outcnt node.Stats.Selectivity = selectivity_out + node.Stats.BlockNum = leftStats.BlockNum case plan.Node_RIGHT: node.Stats.Outcnt = rightStats.Outcnt node.Stats.Cost = leftStats.Cost + rightStats.Cost node.Stats.HashmapStats.HashmapSize = rightStats.Outcnt node.Stats.Selectivity = selectivity + node.Stats.BlockNum = leftStats.BlockNum case plan.Node_DEDUP: node.Stats.Outcnt = rightStats.Outcnt node.Stats.Cost = leftStats.Cost + rightStats.Cost node.Stats.HashmapStats.HashmapSize = rightStats.Outcnt node.Stats.Selectivity = selectivity + node.Stats.BlockNum = leftStats.BlockNum case plan.Node_OUTER: node.Stats.Outcnt = leftStats.Outcnt + rightStats.Outcnt node.Stats.Cost = leftStats.Cost + rightStats.Cost node.Stats.HashmapStats.HashmapSize = rightStats.Outcnt node.Stats.Selectivity = selectivity_out + node.Stats.BlockNum = leftStats.BlockNum case plan.Node_SEMI, plan.Node_INDEX: node.Stats.Outcnt = leftStats.Outcnt * selectivity node.Stats.Cost = leftStats.Cost + rightStats.Cost node.Stats.HashmapStats.HashmapSize = rightStats.Outcnt node.Stats.Selectivity = selectivity_out + node.Stats.BlockNum = leftStats.BlockNum case plan.Node_ANTI: node.Stats.Outcnt = leftStats.Outcnt * (1 - rightStats.Selectivity) * 0.5 node.Stats.Cost = leftStats.Cost + rightStats.Cost node.Stats.HashmapStats.HashmapSize = rightStats.Outcnt node.Stats.Selectivity = selectivity_out + node.Stats.BlockNum = leftStats.BlockNum case plan.Node_SINGLE, plan.Node_MARK: node.Stats.Outcnt = leftStats.Outcnt node.Stats.Cost = leftStats.Cost + rightStats.Cost node.Stats.HashmapStats.HashmapSize = rightStats.Outcnt node.Stats.Selectivity = selectivity_out + node.Stats.BlockNum = leftStats.BlockNum + + case plan.Node_L2: //L2 join is very time-consuming, increase the cost to get more dop + node.Stats.Outcnt = leftStats.Outcnt + node.Stats.Cost = (leftStats.Cost + rightStats.Cost) * 8 + node.Stats.HashmapStats.HashmapSize = rightStats.Outcnt + node.Stats.Selectivity = selectivity_out + node.Stats.BlockNum = leftStats.BlockNum * 8 } - node.Stats.BlockNum = leftStats.BlockNum case plan.Node_AGG: if needResetHashMapStats { diff --git a/pkg/sql/plan/utils.go b/pkg/sql/plan/utils.go index de4072fccee8b..76608e260eb04 100644 --- a/pkg/sql/plan/utils.go +++ b/pkg/sql/plan/utils.go @@ -2711,11 +2711,12 @@ func offsetToString(offset int) string { return fmt.Sprintf("+%02d:%02d", hours, minutes) } -func getLockTableAtTheEnd(tableDef *TableDef) bool { - if tableDef.Pkey.PkeyColName == catalog.FakePrimaryKeyColName || //fake pk, skip - tableDef.Partition != nil || // unsupport partition table - len(tableDef.Pkey.Names) > 1 { // unsupport multi-column primary key - return false - } - return !strings.HasPrefix(tableDef.Name, catalog.IndexTableNamePrefix) -} +// do not lock table if lock no rows now. +// if need to lock table, uncomment these codes +// func getLockTableAtTheEnd(tableDef *TableDef) bool { +// if tableDef.Pkey.PkeyColName == catalog.FakePrimaryKeyColName || //fake pk, skip +// tableDef.Partition != nil { // unsupport partition table +// return false +// } +// return !strings.HasPrefix(tableDef.Name, catalog.IndexTableNamePrefix) +// } diff --git a/pkg/tests/shard/shard_storage_test.go b/pkg/tests/shard/shard_storage_test.go index 610aab538524f..370695a4b84da 100644 --- a/pkg/tests/shard/shard_storage_test.go +++ b/pkg/tests/shard/shard_storage_test.go @@ -34,6 +34,7 @@ import ( ) func TestPartitionBasedShardCanBeCreated(t *testing.T) { + t.SkipNow() embed.RunBaseClusterTests( func(c embed.Cluster) { cn1, err := c.GetCNService(0) @@ -64,6 +65,7 @@ func TestPartitionBasedShardCanBeCreated(t *testing.T) { } func TestPartitionBasedShardCanBeDeleted(t *testing.T) { + t.SkipNow() embed.RunBaseClusterTests( func(c embed.Cluster) { accountID := uint32(0) diff --git a/pkg/tests/shard/shard_test.go b/pkg/tests/shard/shard_test.go index b45b5c36f60bb..4dd3945e8900c 100644 --- a/pkg/tests/shard/shard_test.go +++ b/pkg/tests/shard/shard_test.go @@ -29,9 +29,11 @@ import ( ) var ( - once sync.Once - shardingCluster embed.Cluster - mu sync.Mutex + // TODO: skip all shard tests. + enableAllShardTests bool + once sync.Once + shardingCluster embed.Cluster + mu sync.Mutex ) func runShardClusterTest( @@ -47,6 +49,10 @@ func runShardClusterTestWithReuse( fn func(embed.Cluster), reuse bool, ) error { + if !enableAllShardTests { + return nil + } + mu.Lock() defer mu.Unlock() diff --git a/pkg/testutil/testengine/testengine_test.go b/pkg/testutil/testengine/testengine_test.go index a37ba8b27e8f5..2e0e9351d5cf6 100644 --- a/pkg/testutil/testengine/testengine_test.go +++ b/pkg/testutil/testengine/testengine_test.go @@ -20,6 +20,8 @@ import ( "github.com/matrixorigin/matrixone/pkg/catalog" "github.com/matrixorigin/matrixone/pkg/common/runtime" + "github.com/matrixorigin/matrixone/pkg/defines" + "github.com/stretchr/testify/require" ) func TestTestEngine(t *testing.T) { @@ -40,3 +42,20 @@ func BenchmarkNew(b *testing.B) { New(context.Background()) } } + +func TestRelationExists(t *testing.T) { + catalog.SetupDefines("") + ctx := context.Background() + ctx = defines.AttachAccountId(ctx, 0) + eng, _, _ := New(ctx) + db, err := eng.Database(ctx, "test", nil) + require.NoError(t, err) + + exist, err := db.RelationExists(ctx, "NotExist", nil) + require.NoError(t, err) + require.False(t, exist) + + exist, err = db.RelationExists(ctx, "r", nil) + require.NoError(t, err) + require.True(t, exist) +} diff --git a/pkg/vm/engine/disttae/local_disttae_datasource.go b/pkg/vm/engine/disttae/local_disttae_datasource.go index 0801f897e2b72..0e9ca820830c6 100644 --- a/pkg/vm/engine/disttae/local_disttae_datasource.go +++ b/pkg/vm/engine/disttae/local_disttae_datasource.go @@ -831,6 +831,16 @@ func (ls *LocalDisttaeDataSource) applyWorkspaceFlushedS3Deletes( s3FlushedDeletes := ls.table.getTxn().cn_flushed_s3_tombstone_object_stats_list + var tombstones []objectio.ObjectStats + s3FlushedDeletes.Range(func(key, value any) bool { + tombstones = append(tombstones, key.(objectio.ObjectStats)) + return true + }) + + if len(tombstones) == 0 { + return + } + release := func() {} if deletedRows == nil { bm := objectio.GetReusableBitmap() @@ -839,12 +849,6 @@ func (ls *LocalDisttaeDataSource) applyWorkspaceFlushedS3Deletes( } defer release() - var tombstones []objectio.ObjectStats - s3FlushedDeletes.Range(func(key, value any) bool { - tombstones = append(tombstones, key.(objectio.ObjectStats)) - return true - }) - curr := 0 getTombstone := func() (*objectio.ObjectStats, error) { if curr >= len(tombstones) { diff --git a/pkg/vm/engine/disttae/txn_database.go b/pkg/vm/engine/disttae/txn_database.go index 882c092aa1094..aca4abd1472be 100644 --- a/pkg/vm/engine/disttae/txn_database.go +++ b/pkg/vm/engine/disttae/txn_database.go @@ -86,7 +86,7 @@ func (db *txnDatabase) Relations(ctx context.Context) ([]string, error) { return rels, nil } -func (db *txnDatabase) Relation(ctx context.Context, name string, proc any) (engine.Relation, error) { +func (db *txnDatabase) relation(ctx context.Context, name string, proc any) (engine.Relation, error) { common.DoIfDebugEnabled(func() { logutil.Debug( "Transaction.Relation", @@ -117,7 +117,8 @@ func (db *txnDatabase) Relation(ctx context.Context, name string, proc any) (eng // check the table is deleted or not if !openSys && txn.tableOps.existAndDeleted(key) { - return nil, moerr.NewParseErrorf(ctx, "table %q does not exist", name) + logutil.Info("[relation] deleted in txn", zap.String("table", name)) + return nil, nil } // get relation from the txn created tables cache: created by this txn @@ -143,10 +144,13 @@ func (db *txnDatabase) Relation(ctx context.Context, name string, proc any) (eng if err != nil { return nil, err } + if item == nil { + return nil, nil + } tbl, err := newTxnTable( db, - item, + *item, p, shardservice.GetService(p.GetService()), txn.engine, @@ -159,6 +163,25 @@ func (db *txnDatabase) Relation(ctx context.Context, name string, proc any) (eng return tbl, nil } +func (db *txnDatabase) Relation(ctx context.Context, name string, proc any) (engine.Relation, error) { + rel, err := db.relation(ctx, name, proc) + if err != nil { + return nil, err + } + if rel == nil { + return nil, moerr.NewParseErrorf(ctx, "table %q does not exist", name) + } + return rel, nil +} + +func (db *txnDatabase) RelationExists(ctx context.Context, name string, proc any) (bool, error) { + rel, err := db.relation(ctx, name, proc) + if err != nil { + return false, err + } + return rel != nil, nil +} + func (db *txnDatabase) Delete(ctx context.Context, name string) error { _, err := db.deleteTable(ctx, name, false, false) return err @@ -584,7 +607,7 @@ func (db *txnDatabase) getTableItem( accountID uint32, name string, engine *Engine, -) (cache.TableItem, error) { +) (*cache.TableItem, error) { item := cache.TableItem{ Name: name, DatabaseId: db.databaseId, @@ -596,14 +619,15 @@ func (db *txnDatabase) getTableItem( if ok := c.GetTable(&item); !ok { var tableitem *cache.TableItem if !c.CanServe(types.TimestampToTS(db.op.SnapshotTS())) { + logutil.Info("FIND_TABLE getTableItem cache cannot serve", zap.String("table", name), zap.Uint32("accountID", accountID), zap.String("timestamp", db.op.SnapshotTS().DebugString())) if tableitem, err = db.loadTableFromStorage(ctx, accountID, name); err != nil { - return cache.TableItem{}, err + return nil, err } } if tableitem == nil { - return cache.TableItem{}, moerr.NewParseErrorf(ctx, "table %q does not exist", name) + return nil, nil } - return *tableitem, nil + return tableitem, nil } - return item, nil + return &item, nil } diff --git a/pkg/vm/engine/disttae/txn_table_sharding_handle.go b/pkg/vm/engine/disttae/txn_table_sharding_handle.go index 2b2d9e43642de..14f610ed3346f 100644 --- a/pkg/vm/engine/disttae/txn_table_sharding_handle.go +++ b/pkg/vm/engine/disttae/txn_table_sharding_handle.go @@ -681,10 +681,13 @@ func getTxnTable( if err != nil { return nil, err } + if item == nil { + return nil, moerr.NewParseErrorf(ctx, "table %q does not exist", param.TxnTable.TableName) + } tbl := newTxnTableWithItem( db, - item, + *item, proc, engine.(*Engine), ) diff --git a/pkg/vm/engine/memoryengine/database.go b/pkg/vm/engine/memoryengine/database.go index 8b4b5a0456dd6..012e9d98b4094 100644 --- a/pkg/vm/engine/memoryengine/database.go +++ b/pkg/vm/engine/memoryengine/database.go @@ -165,6 +165,17 @@ func (d *Database) Relation(ctx context.Context, relName string, _ any) (engine. } } +func (d *Database) RelationExists(ctx context.Context, relName string, _ any) (bool, error) { + rel, err := d.Relation(ctx, relName, nil) + if err != nil { + if moerr.IsMoErrCode(err, moerr.ErrNoSuchTable) { + return false, nil + } else { + return false, err + } + } + return rel != nil, nil +} func (d *Database) Relations(ctx context.Context) ([]string, error) { diff --git a/pkg/vm/engine/tae/blockio/utils.go b/pkg/vm/engine/tae/blockio/utils.go index 9a7df01aee679..c63c5e3492fc4 100644 --- a/pkg/vm/engine/tae/blockio/utils.go +++ b/pkg/vm/engine/tae/blockio/utils.go @@ -108,18 +108,25 @@ func GetTombstonesByBlockId( skipObjectCnt int totalBlkCnt int ) + if tombstoneObjectCnt, skipObjectCnt, totalBlkCnt, err = CheckTombstoneFile( ctx, blockId[:], getTombstoneFileFn, onBlockSelectedFn, fs, ); err != nil { return } - v2.TxnReaderEachBLKLoadedTombstoneHistogram.Observe(float64(loadedBlkCnt)) - v2.TxnReaderScannedTotalTombstoneHistogram.Observe(float64(tombstoneObjectCnt)) + if loadedBlkCnt > 0 { + v2.TxnReaderEachBLKLoadedTombstoneHistogram.Observe(float64(loadedBlkCnt)) + } + if tombstoneObjectCnt > 0 { + v2.TxnReaderScannedTotalTombstoneHistogram.Observe(float64(tombstoneObjectCnt)) + } + + if tombstoneObjectCnt > 0 && skipObjectCnt > 0 { v2.TxnReaderTombstoneZMSelectivityHistogram.Observe(float64(skipObjectCnt) / float64(tombstoneObjectCnt)) } - if totalBlkCnt > 0 { + if totalBlkCnt > 0 && loadedBlkCnt > 0 { v2.TxnReaderTombstoneBLSelectivityHistogram.Observe(float64(loadedBlkCnt) / float64(totalBlkCnt)) } diff --git a/pkg/vm/engine/test/disttae_engine_test.go b/pkg/vm/engine/test/disttae_engine_test.go index 7e8ccaa3ba657..82a244ac10d85 100644 --- a/pkg/vm/engine/test/disttae_engine_test.go +++ b/pkg/vm/engine/test/disttae_engine_test.go @@ -1207,3 +1207,34 @@ func TestCache3Tables(t *testing.T) { require.Equal(t, catalog.MO_COLUMNS, tname) require.NotNil(t, rel) } + +func TestRelationExists(t *testing.T) { + opts := config.WithLongScanAndCKPOpts(nil) + p := testutil.InitEnginePack(testutil.TestOptions{TaeEngineOptions: opts}, t) + defer p.Close() + txnop := p.StartCNTxn() + schema := catalog2.MockSchemaAll(2, 0) + schema.Name = "test" + p.CreateDBAndTable(txnop, "db", schema) + + db, err := p.D.Engine.Database(p.Ctx, "db", txnop) + require.NoError(t, err) + + exist, err := db.RelationExists(p.Ctx, "test", nil) + require.NoError(t, err) + require.True(t, exist) + + exist, err = db.RelationExists(p.Ctx, "testxx", nil) + require.NoError(t, err) + require.False(t, exist) + + // craft no-account-id error + ctx := context.WithValue(p.Ctx, defines.TenantIDKey{}, nil) + exist, err = db.RelationExists(ctx, "testxx", nil) + require.Error(t, err) + require.False(t, exist) + + rel, err := db.Relation(ctx, "test", nil) + require.Error(t, err) + require.Nil(t, rel) +} diff --git a/pkg/vm/engine/types.go b/pkg/vm/engine/types.go index adeb023fe98b0..55000c34bc6d5 100644 --- a/pkg/vm/engine/types.go +++ b/pkg/vm/engine/types.go @@ -921,6 +921,7 @@ type Reader interface { type Database interface { Relations(context.Context) ([]string, error) Relation(context.Context, string, any) (Relation, error) + RelationExists(context.Context, string, any) (bool, error) Delete(context.Context, string) error Create(context.Context, string, []TableDef) error // Create Table - (name, table define) diff --git a/proto/pipeline.proto b/proto/pipeline.proto index 382fd90cff2ec..9354b136fe7e9 100644 --- a/proto/pipeline.proto +++ b/proto/pipeline.proto @@ -356,19 +356,21 @@ message MarkJoin { } message DedupJoin { - repeated plan.Expr left_cond = 1; - repeated plan.Expr right_cond = 2; - repeated plan.RuntimeFilterSpec runtime_filter_build_list = 3; - bool is_shuffle = 4; - int32 join_map_tag = 5; - int32 shuffle_idx = 6; - plan.Node.OnDuplicateAction on_duplicate_action = 7; - string dedup_col_name = 8; - repeated plan.Type dedup_col_types = 9 [(gogoproto.nullable) = false]; - repeated plan.Type left_types = 10 [(gogoproto.nullable) = false]; - repeated plan.Type right_types = 11 [(gogoproto.nullable) = false]; - repeated int32 update_col_idx_list = 12; - repeated plan.Expr update_col_expr_list = 13; + repeated int32 rel_list = 1; + repeated int32 col_list = 2; + repeated plan.Expr left_cond = 3; + repeated plan.Expr right_cond = 4; + repeated plan.RuntimeFilterSpec runtime_filter_build_list = 5; + bool is_shuffle = 6; + int32 join_map_tag = 7; + int32 shuffle_idx = 8; + plan.Node.OnDuplicateAction on_duplicate_action = 9; + string dedup_col_name = 10; + repeated plan.Type dedup_col_types = 11 [(gogoproto.nullable) = false]; + repeated plan.Type left_types = 12 [(gogoproto.nullable) = false]; + repeated plan.Type right_types = 13 [(gogoproto.nullable) = false]; + repeated int32 update_col_idx_list = 14; + repeated plan.Expr update_col_expr_list = 15; } message Product { diff --git a/test/distributed/cases/dml/insert/insert_ignore.result b/test/distributed/cases/dml/insert/insert_ignore.result index 71d282317e258..408aa702f79f6 100644 --- a/test/distributed/cases/dml/insert/insert_ignore.result +++ b/test/distributed/cases/dml/insert/insert_ignore.result @@ -128,3 +128,12 @@ c1 c2 45 45 55 55 222 222 +create table insert_ignore_09(c1 int primary key, c2 int); +insert into insert_ignore_09 values(20,45),(21,55),(1,45),(6,22),(5,1),(1000,222),(99999,19); +insert ignore into insert_ignore_09 select result, result from generate_series(1,10000000) g; +select count(*) from insert_ignore_09; +count(*) +10000000 +select count(*) from insert_ignore_09 where c1 != c2; +count(*) +7 diff --git a/test/distributed/cases/dml/insert/insert_ignore.sql b/test/distributed/cases/dml/insert/insert_ignore.sql index 7184ba8a78170..aa7f5be5801f1 100644 --- a/test/distributed/cases/dml/insert/insert_ignore.sql +++ b/test/distributed/cases/dml/insert/insert_ignore.sql @@ -69,3 +69,9 @@ insert into insert_ignore_08 values(20,45),(21,55),(1,45),(6,22),(5,1),(1000,222 insert ignore into insert_ignore_08 select * from insert_ignore_07; select count(*) from insert_ignore_08; select * from insert_ignore_08 where c2 in (45,55,22,1,222,19); + +create table insert_ignore_09(c1 int primary key, c2 int); +insert into insert_ignore_09 values(20,45),(21,55),(1,45),(6,22),(5,1),(1000,222),(99999,19); +insert ignore into insert_ignore_09 select result, result from generate_series(1,10000000) g; +select count(*) from insert_ignore_09; +select count(*) from insert_ignore_09 where c1 != c2; diff --git a/test/distributed/cases/dml/select/order_by_clause.result b/test/distributed/cases/dml/select/order_by_clause.result index e6f23f6ec3b39..08f1465a20506 100644 --- a/test/distributed/cases/dml/select/order_by_clause.result +++ b/test/distributed/cases/dml/select/order_by_clause.result @@ -156,5 +156,47 @@ select empno, 20 as empno from emp order by empno; invalid input: Column 'empno' in order clause is ambiguous select empno, space(50) as empno from emp order by empno; invalid input: Column 'empno' in order clause is ambiguous +select empno, ename, job, mgr, hiredate, sal, empno from emp where deptno != 20 order by empno; +empno ename job mgr hiredate sal empno +7499 ALLEN SALESMAN 7698 1981-02-20 1600.00 7499 +7521 WARD SALESMAN 7698 1981-02-22 1250.00 7521 +7654 MARTIN SALESMAN 7698 1981-09-28 1250.00 7654 +7698 BLAKE MANAGER 7839 1981-05-01 2850.00 7698 +7782 CLARK MANAGER 7839 1981-06-09 2450.00 7782 +7839 KING PRESIDENT null 1981-11-17 5000.00 7839 +7844 TURNER SALESMAN 7698 1981-09-08 1500.00 7844 +7900 JAMES CLERK 7698 1981-12-03 950.00 7900 +7934 MILLER CLERK 7782 1982-01-23 1300.00 7934 +select empno, ename, job, mgr, hiredate, sal, emp.empno from emp where deptno != 20 order by empno; +empno ename job mgr hiredate sal empno +7499 ALLEN SALESMAN 7698 1981-02-20 1600.00 7499 +7521 WARD SALESMAN 7698 1981-02-22 1250.00 7521 +7654 MARTIN SALESMAN 7698 1981-09-28 1250.00 7654 +7698 BLAKE MANAGER 7839 1981-05-01 2850.00 7698 +7782 CLARK MANAGER 7839 1981-06-09 2450.00 7782 +7839 KING PRESIDENT null 1981-11-17 5000.00 7839 +7844 TURNER SALESMAN 7698 1981-09-08 1500.00 7844 +7900 JAMES CLERK 7698 1981-12-03 950.00 7900 +7934 MILLER CLERK 7782 1982-01-23 1300.00 7934 +select t1.ename, t2.loc, t1.deptno, t2.deptno as deptno from emp t1 left join dept t2 on t1.deptno = t2.deptno order by t1.deptno; +ename loc deptno deptno +CLARK NEW YORK 10 10 +MILLER NEW YORK 10 10 +KING NEW YORK 10 10 +JONES DALLAS 20 20 +SMITH DALLAS 20 20 +SCOTT DALLAS 20 20 +ADAMS DALLAS 20 20 +FORD DALLAS 20 20 +MARTIN CHICAGO 30 30 +BLAKE CHICAGO 30 30 +WARD CHICAGO 30 30 +TURNER CHICAGO 30 30 +JAMES CHICAGO 30 30 +ALLEN CHICAGO 30 30 +select t1.ename, t2.loc, deptno, t2.deptno as deptno from emp t1 left join dept t2 on t1.deptno = t2.deptno order by deptno; +invalid input: ambiguouse column reference to 'deptno' +select t1.ename, t2.loc, t1.deptno, t2.deptno as deptno from emp t1 left join dept t2 on t1.deptno = t2.deptno order by deptno; +invalid input: Column 'deptno' in order clause is ambiguous drop table if exists dept; drop table if exists emp; \ No newline at end of file diff --git a/test/distributed/cases/dml/select/order_by_clause.sql b/test/distributed/cases/dml/select/order_by_clause.sql index 14546f35119b9..bd715160891cd 100644 --- a/test/distributed/cases/dml/select/order_by_clause.sql +++ b/test/distributed/cases/dml/select/order_by_clause.sql @@ -95,5 +95,21 @@ select empno, 20 as empno from emp order by empno; --17..mysql: ok, mo: error(bug,暂时选择报错) (同上) select empno, space(50) as empno from emp order by empno; +--18.mysql:ok, mo: ok +select empno, ename, job, mgr, hiredate, sal, empno from emp where deptno != 20 order by empno; + +--19.mysql:ok, mo: ok +select empno, ename, job, mgr, hiredate, sal, emp.empno from emp where deptno != 20 order by empno; + +--20.mysql:ok, mo: ok +select t1.ename, t2.loc, t1.deptno, t2.deptno as deptno from emp t1 left join dept t2 on t1.deptno = t2.deptno order by t1.deptno; + +--21.mysql:error, mo: error +select t1.ename, t2.loc, deptno, t2.deptno as deptno from emp t1 left join dept t2 on t1.deptno = t2.deptno order by deptno; + +--22.mysql:error, mo: error +select t1.ename, t2.loc, t1.deptno, t2.deptno as deptno from emp t1 left join dept t2 on t1.deptno = t2.deptno order by deptno; + + drop table if exists dept; drop table if exists emp; \ No newline at end of file diff --git a/test/distributed/cases/fulltext/fulltext1.result b/test/distributed/cases/fulltext/fulltext1.result new file mode 100644 index 0000000000000..3557fd614cf0d --- /dev/null +++ b/test/distributed/cases/fulltext/fulltext1.result @@ -0,0 +1,153 @@ +set experimental_fulltext_index=1; +drop database if exists test; +create database test; +use test; +create table articles (id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT, FULLTEXT (title,body)); +show create table articles; +Table Create Table +articles CREATE TABLE `articles` (\n `id` int unsigned NOT NULL AUTO_INCREMENT,\n `title` varchar(200) DEFAULT NULL,\n `body` text DEFAULT NULL,\n PRIMARY KEY (`id`),\n FULLTEXT(`title`,`body`)\n) +drop table articles; +create table articles (id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT); +create fulltext index fdx_01 on articles(title, body); +drop index fdx_01 on articles; +create fulltext index fdx_02 on articles(title); +drop index fdx_02 on articles; +create fulltext index fdx_03 on articles(id); +not supported: fulltext index only support char, varchar, text, datalink and json +drop index fdx_04 on articles(title, body) with PARSER ngram; +SQL parser error: You have an error in your SQL syntax; check the manual that corresponds to your MatrixOne server version for the right syntax to use. syntax error at line 1 column 31 near "(title, body) with PARSER ngram;"; +drop index fdx_04 on articles; +internal error: not found index: fdx_04 +drop table articles; +create table src (id bigint primary key, json1 json, json2 json); +create fulltext index ftidx1 on src(json1) with parser json; +show create table src; +Table Create Table +src CREATE TABLE `src` (\n `id` bigint NOT NULL,\n `json1` json DEFAULT NULL,\n `json2` json DEFAULT NULL,\n PRIMARY KEY (`id`),\n FULLTEXT(`json1`) WITH PARSER json\n) +alter table src drop column json1; +drop table src; +create table articles (id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT); +insert into articles (title,body) VALUES ('MySQL Tutorial','DBMS stands for DataBase ...'), +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial, we show ...'), +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +create fulltext index fdx_01 on articles(title, body) with parser ngram; +select * from articles where match(title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE) union select * from articles where match(title,body) AGAINST ('YourSQL' IN NATURAL LANGUAGE MODE) order by id; +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +5 MySQL vs. YourSQL In the following database comparison ... +drop index fdx_01 on articles; +select * from articles where match(title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE) union select * from articles where match(title,body) AGAINST ('YourSQL' IN NATURAL LANGUAGE MODE) order by id; +not supported: MATCH() AGAINST() function cannot be replaced by FULLTEXT INDEX and full table scan with fulltext search is not supported yet. +create fulltext index fdx_01 on articles(title, body); +select * from articles where match(title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE) union select * from articles where match(title,body) AGAINST ('YourSQL' IN NATURAL LANGUAGE MODE) order by id; +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +5 MySQL vs. YourSQL In the following database comparison ... +select count(*) from (select * from articles where match(title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE)); +count(*) +2 +drop table articles; +create table articles (id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT); +insert into articles (title,body) VALUES ('神雕侠侣 第一回 风月无情','越女采莲秋水畔,窄袖轻罗,暗露双金钏 ...'), +('神雕侠侣 第二回 故人之子','正自发痴,忽听左首屋中传出一人喝道:“这是在人家府上,你又提小龙女干什么?” ...'), +('神雕侠侣 第三回 投师终南','郭靖在舟中潜运神功,数日间伤势便已痊愈了大半。 ...'), +('神雕侠侣 第四回 全真门下','郭靖摆脱众道纠缠,提气向重阳宫奔去,忽听得钟声镗镗响起 ...'), +('神雕侠侣 第五回 活死人墓','杨过摔下山坡,滚入树林长草丛中,便即昏晕 ...'), +('神雕侠侣 第六回 玉女心经','小龙女从怀里取出一个瓷瓶,交在杨过手里 ...'); +create fulltext index fdx_01 on articles(title, body) with parser ngram; +select * from articles where match(title,body) AGAINST ('风月无情' IN NATURAL LANGUAGE MODE); +id title body +1 神雕侠侣 第一回 风月无情 越女采莲秋水畔,窄袖轻罗,暗露双金钏 ... +select * from articles where match(title,body) AGAINST ('杨过' IN NATURAL LANGUAGE MODE); +id title body +5 神雕侠侣 第五回 活死人墓 杨过摔下山坡,滚入树林长草丛中,便即昏晕 ... +6 神雕侠侣 第六回 玉女心经 小龙女从怀里取出一个瓷瓶,交在杨过手里 ... +select * from articles where match(title,body) AGAINST ('小龙女' IN NATURAL LANGUAGE MODE); +id title body +2 神雕侠侣 第二回 故人之子 正自发痴,忽听左首屋中传出一人喝道:“这是在人家府上,你又提小龙女干什么?” ... +6 神雕侠侣 第六回 玉女心经 小龙女从怀里取出一个瓷瓶,交在杨过手里 ... +select * from articles where match(title,body) AGAINST ('神雕侠侣' IN NATURAL LANGUAGE MODE); +id title body +1 神雕侠侣 第一回 风月无情 越女采莲秋水畔,窄袖轻罗,暗露双金钏 ... +2 神雕侠侣 第二回 故人之子 正自发痴,忽听左首屋中传出一人喝道:“这是在人家府上,你又提小龙女干什么?” ... +3 神雕侠侣 第三回 投师终南 郭靖在舟中潜运神功,数日间伤势便已痊愈了大半。 ... +4 神雕侠侣 第四回 全真门下 郭靖摆脱众道纠缠,提气向重阳宫奔去,忽听得钟声镗镗响起 ... +5 神雕侠侣 第五回 活死人墓 杨过摔下山坡,滚入树林长草丛中,便即昏晕 ... +6 神雕侠侣 第六回 玉女心经 小龙女从怀里取出一个瓷瓶,交在杨过手里 ... +drop table articles; +create table articles (id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title json, body json); +insert into articles (title,body) VALUES ('{"title": "MySQL Tutorial"}','{"body":"DBMS stands for DataBase ..."}'), +('{"title":"How To Use MySQL Well"}','{"body":"After you went through a ..."}'), +('{"title":"Optimizing MySQL"}','{"body":"In this tutorial, we show ..."}'), +('{"title":"1001 MySQL Tricks"}','{"body":"1. Never run mysqld as root. 2. ..."}'), +('{"title":"MySQL vs. YourSQL"}','{"body":"In the following database comparison ..."}'), +('{"title":"MySQL Security"}','{"body":"When configured properly, MySQL ..."}'); +create fulltext index fdx_01 on articles(title, body) with parser json; +select * from articles where match(title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE) union select * from articles where match(title,body) AGAINST ('YourSQL' IN NATURAL LANGUAGE MODE) order by id; +id title body +1 {"title": "MySQL Tutorial"} {"body": "DBMS stands for DataBase ..."} +5 {"title": "MySQL vs. YourSQL"} {"body": "In the following database comparison ..."} +drop index fdx_01 on articles; +select * from articles where match(title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE) union select * from articles where match(title,body) AGAINST ('YourSQL' IN NATURAL LANGUAGE MODE) order by id; +not supported: MATCH() AGAINST() function cannot be replaced by FULLTEXT INDEX and full table scan with fulltext search is not supported yet. +create fulltext index fdx_01 on articles(title, body); +select * from articles where match(title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE) union select * from articles where match(title,body) AGAINST ('YourSQL' IN NATURAL LANGUAGE MODE) order by id; +id title body +1 {"title": "MySQL Tutorial"} {"body": "DBMS stands for DataBase ..."} +5 {"title": "MySQL vs. YourSQL"} {"body": "In the following database comparison ..."} +select count(*) from (select * from articles where match(title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE)); +count(*) +2 +drop table articles; +create table articles (id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title json, body json); +insert into articles (title,body) VALUES ('{"title": "神雕侠侣 第一回 风月无情"}','{"body":"越女采莲秋水畔,窄袖轻罗,暗露双金钏 ..."}'), +('{"title":"神雕侠侣 第二回 故人之子"}','{"body":"正自发痴,忽听左首屋中传出一人喝道:“这是在人家府上,你又提小龙女干什么?” ..."}'), +('{"title":"神雕侠侣 第三回 投师终南"}','{"body":"郭靖在舟中潜运神功,数日间伤势便已痊愈了大半。 ..."}'), +('{"title":"神雕侠侣 第四回 全真门下"}','{"body":"郭靖摆脱众道纠缠,提气向重阳宫奔去,忽听得钟声镗镗响起 ..."}'), +('{"title":"神雕侠侣 第五回 活死人墓"}','{"body":"杨过摔下山坡,滚入树林长草丛中,便即昏晕 ..."}'), +('{"title":"神雕侠侣 第六回 玉女心经"}','{"body":"小龙女从怀里取出一个瓷瓶,交在杨过手里 ..."}'); +create fulltext index fdx_01 on articles(title, body) with parser json; +select * from articles where match(title,body) AGAINST ('风月无情' IN NATURAL LANGUAGE MODE); +id title body +1 {"title": "神雕侠侣 第一回 风月无情"} {"body": "越女采莲秋水畔,窄袖轻罗,暗露双金钏 ..."} +select * from articles where match(title,body) AGAINST ('杨过' IN NATURAL LANGUAGE MODE); +id title body +5 {"title": "神雕侠侣 第五回 活死人墓"} {"body": "杨过摔下山坡,滚入树林长草丛中,便即昏晕 ..."} +6 {"title": "神雕侠侣 第六回 玉女心经"} {"body": "小龙女从怀里取出一个瓷瓶,交在杨过手里 ..."} +select * from articles where match(title,body) AGAINST ('小龙女' IN NATURAL LANGUAGE MODE); +id title body +2 {"title": "神雕侠侣 第二回 故人之子"} {"body": "正自发痴,忽听左首屋中传出一人喝道:“这是在人家府上,你又提小龙女干什么?” ..."} +6 {"title": "神雕侠侣 第六回 玉女心经"} {"body": "小龙女从怀里取出一个瓷瓶,交在杨过手里 ..."} +select * from articles where match(title,body) AGAINST ('神雕侠侣' IN NATURAL LANGUAGE MODE); +id title body +1 {"title": "神雕侠侣 第一回 风月无情"} {"body": "越女采莲秋水畔,窄袖轻罗,暗露双金钏 ..."} +2 {"title": "神雕侠侣 第二回 故人之子"} {"body": "正自发痴,忽听左首屋中传出一人喝道:“这是在人家府上,你又提小龙女干什么?” ..."} +3 {"title": "神雕侠侣 第三回 投师终南"} {"body": "郭靖在舟中潜运神功,数日间伤势便已痊愈了大半。 ..."} +4 {"title": "神雕侠侣 第四回 全真门下"} {"body": "郭靖摆脱众道纠缠,提气向重阳宫奔去,忽听得钟声镗镗响起 ..."} +5 {"title": "神雕侠侣 第五回 活死人墓"} {"body": "杨过摔下山坡,滚入树林长草丛中,便即昏晕 ..."} +6 {"title": "神雕侠侣 第六回 玉女心经"} {"body": "小龙女从怀里取出一个瓷瓶,交在杨过手里 ..."} +drop table articles; +drop table if exists t1; +create table t1(a int primary key, b varchar(200), c int); +insert into t1(a,b,c) select result, "test create big fulltext index" ,result from generate_series(10000) g; +create fulltext index ftidx on t1 (b); +create index index2 on t1 (c); +explain select * from t1 where c = 100; +TP QUERY PLAN +Project + -> Join + Join Type: INDEX + Join Cond: (t1.a = #[1,0]) + Runtime Filter Build: #[-1,0] + -> Table Scan on test.t1 [ForceOneCN] + Filter Cond: (t1.c = 100) + Block Filter Cond: (t1.c = 100) + Runtime Filter Probe: t1.a + -> Table Scan on test.index2(index) [ForceOneCN] + Filter Cond: prefix_eq(#[0,0]) + Block Filter Cond: prefix_eq(#[0,0]) +drop table t1; +drop database test; diff --git a/test/distributed/cases/fulltext/fulltext1.sql b/test/distributed/cases/fulltext/fulltext1.sql new file mode 100644 index 0000000000000..75c6462187d2c --- /dev/null +++ b/test/distributed/cases/fulltext/fulltext1.sql @@ -0,0 +1,94 @@ +set experimental_fulltext_index=1; +drop database if exists test; +create database test; +use test; +create table articles (id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT, FULLTEXT (title,body)); +show create table articles; +drop table articles; + +create table articles (id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT); +create fulltext index fdx_01 on articles(title, body); +drop index fdx_01 on articles; +create fulltext index fdx_02 on articles(title); +drop index fdx_02 on articles; +create fulltext index fdx_03 on articles(id); +drop index fdx_04 on articles(title, body) with PARSER ngram; +drop index fdx_04 on articles; +drop table articles; + +create table src (id bigint primary key, json1 json, json2 json); +create fulltext index ftidx1 on src(json1) with parser json; +show create table src; +alter table src drop column json1; +drop table src; + +create table articles (id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT); +insert into articles (title,body) VALUES ('MySQL Tutorial','DBMS stands for DataBase ...'), + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial, we show ...'), + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); +create fulltext index fdx_01 on articles(title, body) with parser ngram; +select * from articles where match(title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE) union select * from articles where match(title,body) AGAINST ('YourSQL' IN NATURAL LANGUAGE MODE) order by id; +drop index fdx_01 on articles; +select * from articles where match(title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE) union select * from articles where match(title,body) AGAINST ('YourSQL' IN NATURAL LANGUAGE MODE) order by id; +create fulltext index fdx_01 on articles(title, body); +select * from articles where match(title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE) union select * from articles where match(title,body) AGAINST ('YourSQL' IN NATURAL LANGUAGE MODE) order by id; +select count(*) from (select * from articles where match(title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE)); +drop table articles; + +create table articles (id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT); +insert into articles (title,body) VALUES ('神雕侠侣 第一回 风月无情','越女采莲秋水畔,窄袖轻罗,暗露双金钏 ...'), + ('神雕侠侣 第二回 故人之子','正自发痴,忽听左首屋中传出一人喝道:“这是在人家府上,你又提小龙女干什么?” ...'), + ('神雕侠侣 第三回 投师终南','郭靖在舟中潜运神功,数日间伤势便已痊愈了大半。 ...'), + ('神雕侠侣 第四回 全真门下','郭靖摆脱众道纠缠,提气向重阳宫奔去,忽听得钟声镗镗响起 ...'), + ('神雕侠侣 第五回 活死人墓','杨过摔下山坡,滚入树林长草丛中,便即昏晕 ...'), + ('神雕侠侣 第六回 玉女心经','小龙女从怀里取出一个瓷瓶,交在杨过手里 ...'); +create fulltext index fdx_01 on articles(title, body) with parser ngram; +select * from articles where match(title,body) AGAINST ('风月无情' IN NATURAL LANGUAGE MODE); +select * from articles where match(title,body) AGAINST ('杨过' IN NATURAL LANGUAGE MODE); +select * from articles where match(title,body) AGAINST ('小龙女' IN NATURAL LANGUAGE MODE); +select * from articles where match(title,body) AGAINST ('神雕侠侣' IN NATURAL LANGUAGE MODE); +drop table articles; + +create table articles (id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title json, body json); +insert into articles (title,body) VALUES ('{"title": "MySQL Tutorial"}','{"body":"DBMS stands for DataBase ..."}'), + ('{"title":"How To Use MySQL Well"}','{"body":"After you went through a ..."}'), + ('{"title":"Optimizing MySQL"}','{"body":"In this tutorial, we show ..."}'), + ('{"title":"1001 MySQL Tricks"}','{"body":"1. Never run mysqld as root. 2. ..."}'), + ('{"title":"MySQL vs. YourSQL"}','{"body":"In the following database comparison ..."}'), + ('{"title":"MySQL Security"}','{"body":"When configured properly, MySQL ..."}'); +create fulltext index fdx_01 on articles(title, body) with parser json; +select * from articles where match(title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE) union select * from articles where match(title,body) AGAINST ('YourSQL' IN NATURAL LANGUAGE MODE) order by id; +drop index fdx_01 on articles; +select * from articles where match(title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE) union select * from articles where match(title,body) AGAINST ('YourSQL' IN NATURAL LANGUAGE MODE) order by id; +create fulltext index fdx_01 on articles(title, body); +select * from articles where match(title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE) union select * from articles where match(title,body) AGAINST ('YourSQL' IN NATURAL LANGUAGE MODE) order by id; +select count(*) from (select * from articles where match(title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE)); +drop table articles; + +create table articles (id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title json, body json); +insert into articles (title,body) VALUES ('{"title": "神雕侠侣 第一回 风月无情"}','{"body":"越女采莲秋水畔,窄袖轻罗,暗露双金钏 ..."}'), + ('{"title":"神雕侠侣 第二回 故人之子"}','{"body":"正自发痴,忽听左首屋中传出一人喝道:“这是在人家府上,你又提小龙女干什么?” ..."}'), + ('{"title":"神雕侠侣 第三回 投师终南"}','{"body":"郭靖在舟中潜运神功,数日间伤势便已痊愈了大半。 ..."}'), + ('{"title":"神雕侠侣 第四回 全真门下"}','{"body":"郭靖摆脱众道纠缠,提气向重阳宫奔去,忽听得钟声镗镗响起 ..."}'), + ('{"title":"神雕侠侣 第五回 活死人墓"}','{"body":"杨过摔下山坡,滚入树林长草丛中,便即昏晕 ..."}'), + ('{"title":"神雕侠侣 第六回 玉女心经"}','{"body":"小龙女从怀里取出一个瓷瓶,交在杨过手里 ..."}'); +create fulltext index fdx_01 on articles(title, body) with parser json; +select * from articles where match(title,body) AGAINST ('风月无情' IN NATURAL LANGUAGE MODE); +select * from articles where match(title,body) AGAINST ('杨过' IN NATURAL LANGUAGE MODE); +select * from articles where match(title,body) AGAINST ('小龙女' IN NATURAL LANGUAGE MODE); +select * from articles where match(title,body) AGAINST ('神雕侠侣' IN NATURAL LANGUAGE MODE); +drop table articles; + +drop table if exists t1; +create table t1(a int primary key, b varchar(200), c int); +insert into t1(a,b,c) select result, "test create big fulltext index" ,result from generate_series(10000) g; +create fulltext index ftidx on t1 (b); +create index index2 on t1 (c); +-- @separator:table +explain select * from t1 where c = 100; +drop table t1; + +drop database test; \ No newline at end of file diff --git a/test/distributed/cases/pessimistic_transaction/select_for_update.sql b/test/distributed/cases/pessimistic_transaction/select_for_update.sql index 5f1d72351319c..2feb591797217 100644 --- a/test/distributed/cases/pessimistic_transaction/select_for_update.sql +++ b/test/distributed/cases/pessimistic_transaction/select_for_update.sql @@ -696,7 +696,6 @@ select * from su_06 where c1>=2 for update; use select_for_update; prepare stmt1 from 'delete from su_06 where c3 in (?)'; set @var = 3; --- @wait:0:commit execute stmt1 using @var; select * from su_06; -- @session} diff --git a/test/distributed/cases/security/password.result b/test/distributed/cases/security/password.result index 6beb1eb9b4d26..59c59e39cff9e 100644 --- a/test/distributed/cases/security/password.result +++ b/test/distributed/cases/security/password.result @@ -51,7 +51,7 @@ create user user1_group2 identified by '12345678'; -- Expected failure invalid input: Password '12345678' does not contain enough changed characters create user user2_group2 identified by 'abcdefgH'; -- Expected failure invalid input: Password 'abcdefgH' does not meet the Uppercase requirements -create user useR32Go identified by 'oG23Resu'; -- Expected failure +create user useR32Go identified by 'useR32Go'; -- Expected failure create user user4_group2 identified by 'AbCLq56%'; -- Expected success select user_name from mo_catalog.mo_user where user_name in ('user3_group2', 'user4_group2'); user_name @@ -226,16 +226,16 @@ SET GLOBAL password_history = 1; SET GLOBAL password_reuse_interval = 7; SHOW VARIABLES LIKE "%connection_control_failed_connections_threshold%"; Variable_name Value -connection_control_failed_connections_threshold 3 +connection_control_failed_connections_threshold 0 SHOW VARIABLES LIKE "%connection_control_max_connection_delay%"; Variable_name Value -connection_control_max_connection_delay 0 +connection_control_max_connection_delay 1000 SHOW VARIABLES LIKE "%password_history%"; Variable_name Value -password_history 0 +password_history 1 SHOW VARIABLES LIKE "%password_reuse_interval%"; Variable_name Value -password_reuse_interval 0 +password_reuse_interval 7 CREATE USER user1_group4 IDENTIFIED BY 'oldpassword123'; CREATE USER user2_group4 IDENTIFIED BY 'oldpassword456'; ALTER USER user1_group4 IDENTIFIED BY 'newpassword123'; @@ -249,18 +249,6 @@ user_name user1_group4 user2_group4 DROP USER IF EXISTS user1_group4, user2_group4; -SHOW VARIABLES LIKE "%connection_control_failed_connections_threshold%"; -Variable_name Value -connection_control_failed_connections_threshold 3 -SHOW VARIABLES LIKE "%connection_control_max_connection_delay%"; -Variable_name Value -connection_control_max_connection_delay 0 -SHOW VARIABLES LIKE "%password_history%"; -Variable_name Value -password_history 0 -SHOW VARIABLES LIKE "%password_reuse_interval%"; -Variable_name Value -password_reuse_interval 0 SET GLOBAL connection_control_failed_connections_threshold = -1; -- Invalid: cannot be negative internal error: convert to the system variable int type failed SET GLOBAL connection_control_max_connection_delay = -100; -- Invalid: cannot be negative diff --git a/test/distributed/cases/security/password.sql b/test/distributed/cases/security/password.sql index 03787d010e3a5..eb46fe1c63173 100644 --- a/test/distributed/cases/security/password.sql +++ b/test/distributed/cases/security/password.sql @@ -1,4 +1,4 @@ --- @session:id=1&user=dump&password=111 +--@session:id=0&user=dump&password=111 -- Test cases for Group 0 create user user1_group0 identified by '1234'; -- Clean up Group 0 @@ -17,7 +17,7 @@ set global validate_password.policy = '0'; -- ======================== -- 1. Test Group 1 -- ======================== --- @session:id=2&user=dump&password=111 +-- @session:id=1&user=dump&password=111 show variables like "%validate_password%"; -- test @@ -44,13 +44,15 @@ set global validate_password.policy = '1'; -- ======================== -- 2. Test Group 2 -- ======================== --- @session:id=3&user=dump&password=111 +-- @session:id=2&user=dump&password=111 show variables like "%validate_password%"; -- Test cases create user user1_group2 identified by '12345678'; -- Expected failure create user user2_group2 identified by 'abcdefgH'; -- Expected failure -create user useR32Go identified by 'oG23Resu'; -- Expected failure +-- @bvt:issue#4511 +create user useR32Go identified by 'useR32Go'; -- Expected failure +-- @bvt:issue create user user4_group2 identified by 'AbCLq56%'; -- Expected success -- Verify results @@ -73,7 +75,7 @@ set global validate_password.policy = '1'; -- ======================== -- 3. Test Group 3 -- ======================== --- @session:id=4&user=dump&password=111 +-- @session:id=3&user=dump&password=111 -- Test cases create user user1_group3 identified by 'abcdefgH'; -- Expected failure create user user2_group3 identified by '1234abcd'; -- Expected failure @@ -100,7 +102,7 @@ set global validate_password.policy = '1'; -- ======================== -- 4. Test Group 4 -- ======================== --- @session:id=5&user=dump&password=111 +-- @session:id=4&user=dump&password=111 -- Test cases create user user1_group4 identified by '123456789abcde'; -- Expected failure create user user2_group4 identified by 'Abcdefg1234567'; -- Expected failure @@ -140,7 +142,7 @@ set global validate_password.policy = '0'; -- ======================== -- 1. Set global parameters for password lifecycle and failed connection threshold -- ======================== --- @session:id=6&user=dump&password=111 +-- @session:id=5&user=dump&password=111 -- Create dump user and grant privileges to modify other users -- Show current variables before setting new values @@ -160,7 +162,7 @@ SET GLOBAL password_reuse_interval = 0; -- 2. Verify parameters for Group 1 in a new session -- ======================== --- @session:id=7&user=dump&password=111 +-- @session:id=6&user=dump&password=111 -- Show the current parameter settings after change SHOW VARIABLES LIKE "%connection_control_failed_connections_threshold%"; SHOW VARIABLES LIKE "%connection_control_max_connection_delay%"; @@ -194,7 +196,7 @@ SET GLOBAL password_history = 6; SET GLOBAL password_reuse_interval = 10; -- @session --- @session:id=8&user=dump&password=111 +-- @session:id=7&user=dump&password=111 -- Show the current parameter settings before test SHOW VARIABLES LIKE "%connection_control_failed_connections_threshold%"; SHOW VARIABLES LIKE "%connection_control_max_connection_delay%"; @@ -234,7 +236,7 @@ SET GLOBAL password_history = 10; SET GLOBAL password_reuse_interval = 30; -- @session --- @session:id=9&user=dump&password=111 +-- @session:id=8&user=dump&password=111 -- Show the current parameter settings before test SHOW VARIABLES LIKE "%connection_control_failed_connections_threshold%"; SHOW VARIABLES LIKE "%connection_control_max_connection_delay%"; @@ -262,7 +264,7 @@ SET GLOBAL password_history = 1; SET GLOBAL password_reuse_interval = 7; -- @session --- @session:id=10&user=dump&password=111 +-- @session:id=9&user=dump&password=111 -- Show the current parameter settings before test SHOW VARIABLES LIKE "%connection_control_failed_connections_threshold%"; SHOW VARIABLES LIKE "%connection_control_max_connection_delay%"; @@ -286,16 +288,9 @@ SELECT user_name FROM mo_catalog.mo_user WHERE user_name IN ('user1_group4', 'us -- Clean up Group 4 DROP USER IF EXISTS user1_group4, user2_group4; --- @session -- ======================== -- 6. Test Group 5: Invalid values for lifecycle parameters -- ======================== --- @session:id=11&user=dump&password=111 --- Show current variables before testing invalid values -SHOW VARIABLES LIKE "%connection_control_failed_connections_threshold%"; -SHOW VARIABLES LIKE "%connection_control_max_connection_delay%"; -SHOW VARIABLES LIKE "%password_history%"; -SHOW VARIABLES LIKE "%password_reuse_interval%"; SET GLOBAL connection_control_failed_connections_threshold = -1; -- Invalid: cannot be negative SET GLOBAL connection_control_max_connection_delay = -100; -- Invalid: cannot be negative