Skip to content

Commit b62a461

Browse files
committed
importsdk: support multi-statement schema in size estimator
1 parent a6bf749 commit b62a461

File tree

2 files changed

+82
-4
lines changed

2 files changed

+82
-4
lines changed

pkg/importsdk/file_scanner.go

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -393,13 +393,13 @@ func (s *fileScanner) buildEstimateTableInfo(ctx context.Context, tblMeta *mydum
393393
}
394394
p := parser.New()
395395
p.SetSQLMode(s.config.sqlMode)
396-
stmt, err := p.ParseOneStmt(schemaSQL, "", "")
396+
stmts, _, err := p.ParseSQL(schemaSQL)
397397
if err != nil {
398398
return nil, errors.Trace(err)
399399
}
400-
createStmt, ok := stmt.(*ast.CreateTableStmt)
401-
if !ok {
402-
return nil, errors.Errorf("schema file %s does not contain a CREATE TABLE statement", tblMeta.SchemaFile.FileMeta.Path)
400+
createStmt, err := buildEstimateCreateTableStmt(stmts, tblMeta)
401+
if err != nil {
402+
return nil, err
403403
}
404404
tableInfo, err := ddl.BuildTableInfoFromAST(metabuild.NewContext(), createStmt)
405405
if err != nil {
@@ -408,6 +408,49 @@ func (s *fileScanner) buildEstimateTableInfo(ctx context.Context, tblMeta *mydum
408408
return tableInfo, nil
409409
}
410410

411+
func buildEstimateCreateTableStmt(stmts []ast.StmtNode, tblMeta *mydump.MDTableMeta) (*ast.CreateTableStmt, error) {
412+
var (
413+
firstCreateStmt *ast.CreateTableStmt
414+
createStmtCount int
415+
)
416+
for _, stmt := range stmts {
417+
createStmt, ok := stmt.(*ast.CreateTableStmt)
418+
if !ok {
419+
continue
420+
}
421+
if firstCreateStmt == nil {
422+
firstCreateStmt = createStmt
423+
}
424+
createStmtCount++
425+
if estimateCreateTableStmtMatchesMeta(createStmt, tblMeta) {
426+
return createStmt, nil
427+
}
428+
}
429+
if createStmtCount == 1 {
430+
return firstCreateStmt, nil
431+
}
432+
if createStmtCount == 0 {
433+
return nil, errors.Errorf("schema file %s does not contain a CREATE TABLE statement", tblMeta.SchemaFile.FileMeta.Path)
434+
}
435+
return nil, errors.Errorf(
436+
"schema file %s contains %d CREATE TABLE statements but none match table %s.%s",
437+
tblMeta.SchemaFile.FileMeta.Path,
438+
createStmtCount,
439+
tblMeta.DB,
440+
tblMeta.Name,
441+
)
442+
}
443+
444+
func estimateCreateTableStmtMatchesMeta(createStmt *ast.CreateTableStmt, tblMeta *mydump.MDTableMeta) bool {
445+
if !strings.EqualFold(createStmt.Table.Name.String(), tblMeta.Name) {
446+
return false
447+
}
448+
if createStmt.Table.Schema.String() == "" {
449+
return true
450+
}
451+
return strings.EqualFold(createStmt.Table.Schema.String(), tblMeta.DB)
452+
}
453+
411454
func sourceTypeToImportFormat(tp mydump.SourceType) (string, error) {
412455
switch tp {
413456
case mydump.SourceTypeCSV:

pkg/importsdk/file_scanner_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,41 @@ func TestFileScanner(t *testing.T) {
266266
require.Equal(t, estimate.Tables[0].SourceSize, estimate.TotalSourceSize)
267267
require.Equal(t, estimate.Tables[0].TiKVSize, estimate.TotalTiKVSize)
268268
})
269+
270+
t.Run("EstimateImportDataSizeMultiStatementSchema", func(t *testing.T) {
271+
estimateDir := t.TempDir()
272+
require.NoError(t, os.WriteFile(filepath.Join(estimateDir, "test_db-schema-create.sql"), []byte("CREATE DATABASE test_db;"), 0o644))
273+
require.NoError(t, os.WriteFile(
274+
filepath.Join(estimateDir, "test_db.users-schema.sql"),
275+
[]byte(strings.Join([]string{
276+
"CREATE DATABASE IF NOT EXISTS test_db;",
277+
"USE test_db;",
278+
"DROP TABLE IF EXISTS users;",
279+
"CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(255), KEY idx_name (name));",
280+
}, "\n")),
281+
0o644,
282+
))
283+
require.NoError(t, os.WriteFile(
284+
filepath.Join(estimateDir, "test_db.users.001.csv"),
285+
[]byte("1,alice\n2,bob\n"),
286+
0o644,
287+
))
288+
289+
cfg := defaultSDKConfig()
290+
cfg.skipInvalidFiles = true
291+
estimateScanner, err := NewFileScanner(ctx, "file://"+estimateDir, db, cfg)
292+
require.NoError(t, err)
293+
defer estimateScanner.Close()
294+
295+
estimate, err := estimateScanner.EstimateImportDataSize(ctx)
296+
require.NoError(t, err)
297+
require.Len(t, estimate.Tables, 1)
298+
require.Equal(t, "users", estimate.Tables[0].Table)
299+
require.Positive(t, estimate.Tables[0].SourceSize)
300+
require.Positive(t, estimate.Tables[0].TiKVSize)
301+
require.Equal(t, estimate.Tables[0].SourceSize, estimate.TotalSourceSize)
302+
require.Equal(t, estimate.Tables[0].TiKVSize, estimate.TotalTiKVSize)
303+
})
269304
}
270305

271306
func TestFileScannerWithEstimateRealSize(t *testing.T) {

0 commit comments

Comments
 (0)