(statement string, backupItem *storepb.PriorBackupDetail_Item)
| 58 | } |
| 59 | |
| 60 | func findStatementAtPosition(statement string, backupItem *storepb.PriorBackupDetail_Item) (ast.Node, error) { |
| 61 | stmts, err := ParsePg(statement) |
| 62 | if err != nil { |
| 63 | return nil, errors.Wrap(err, "failed to parse statement") |
| 64 | } |
| 65 | |
| 66 | posMapper := base.NewByteOffsetPositionMapper(statement) |
| 67 | for _, stmt := range stmts { |
| 68 | if stmt.Empty() { |
| 69 | continue |
| 70 | } |
| 71 | switch stmt.AST.(type) { |
| 72 | case *ast.UpdateStmt, *ast.DeleteStmt: |
| 73 | nodeLoc := ast.NodeLoc(stmt.AST) |
| 74 | startPos := posMapper.Position(nodeLoc.Start) |
| 75 | startPos.Column-- // 0-based to match backup convention |
| 76 | endPos := posMapper.Position(nodeLoc.End) |
| 77 | if inRange(startPos, endPos, backupItem.StartPosition, backupItem.EndPosition) { |
| 78 | return stmt.AST, nil |
| 79 | } |
| 80 | default: |
| 81 | } |
| 82 | } |
| 83 | return nil, nil |
| 84 | } |
| 85 | |
| 86 | func doGenerate(ctx context.Context, rCtx base.RestoreContext, sqlForComment string, node ast.Node, backupItem *storepb.PriorBackupDetail_Item, prependStatements string) (string, error) { |
| 87 | _, sourceDatabase, err := common.GetInstanceDatabaseID(backupItem.SourceTable.Database) |
no test coverage detected