Repository: xataio/pgstream
Pull request #370 (2025-05-30 13:19:56)

[Snapshot] Do not dump sequence values if there's no sequences
This PR fixes an edge case when dumping sequence data to only call `pg_dump` if there are sequences created by the schema dump. Currently when there are no sequences the table filter is not used, and all data is dumped.


Patch:
diff --git a/pkg/snapshot/generator/postgres/schema/pgdumprestore/snapshot_pg_dump_restore_generator.go b/pkg/snapshot/generator/postgres/schema/pgdumprestore/snapshot_pg_dump_restore_generator.go
index 39c237a..a24da36 100644
--- a/pkg/snapshot/generator/postgres/schema/pgdumprestore/snapshot_pg_dump_restore_generator.go
+++ b/pkg/snapshot/generator/postgres/schema/pgdumprestore/snapshot_pg_dump_restore_generator.go
@@ -192,6 +192,10 @@ func (s *SnapshotGenerator) dumpSchema(ctx context.Context, ss *snapshot.Snapsho
 }
 
 func (s *SnapshotGenerator) dumpSequenceValues(ctx context.Context, sequences []string) ([]byte, error) {
+	if len(sequences) == 0 {
+		return nil, nil
+	}
+
 	opts := &pglib.PGDumpOptions{
 		ConnectionString: s.sourceURL,
 		Format:           "p",


Test patch:
diff --git a/pkg/snapshot/generator/postgres/schema/pgdumprestore/snapshot_pg_dump_restore_generator_test.go b/pkg/snapshot/generator/postgres/schema/pgdumprestore/snapshot_pg_dump_restore_generator_test.go
index 8b90de5..7529309 100644
--- a/pkg/snapshot/generator/postgres/schema/pgdumprestore/snapshot_pg_dump_restore_generator_test.go
+++ b/pkg/snapshot/generator/postgres/schema/pgdumprestore/snapshot_pg_dump_restore_generator_test.go
@@ -24,14 +24,16 @@ import (
 func TestSnapshotGenerator_CreateSnapshot(t *testing.T) {
 	t.Parallel()
 
-	schemaDump := []byte("schema dump")
-	filteredDump := []byte("schema dump\n")
+	schemaDump := []byte("schema dump\nCREATE SEQUENCE test.test_sequence")
+	schemaDumpNoSequences := []byte("schema dump")
+	filteredDump := []byte("schema dump\nCREATE SEQUENCE test.test_sequence\n")
 	sequenceDump := []byte("sequence dump")
 	testSchema := "test_schema"
 	testTable := "test_table"
 	excludedTable := "excluded_test_table"
 	excludedSchema := "excluded_test_schema"
 	errTest := errors.New("oh noes")
+	testSequence := "test_sequence"
 
 	validQuerier := func() *mocks.Querier {
 		return &mocks.Querier{
@@ -112,7 +114,7 @@ func TestSnapshotGenerator_CreateSnapshot(t *testing.T) {
 						ConnectionString: "source-url",
 						Format:           "p",
 						DataOnly:         true,
-						Tables:           []string{},
+						Tables:           []string{testSequence},
 					}, po)
 					return sequenceDump, nil
 				default:
@@ -130,6 +132,39 @@ func TestSnapshotGenerator_CreateSnapshot(t *testing.T) {
 
 			wantErr: nil,
 		},
+		{
+			name: "ok - no sequence dump",
+			snapshot: &snapshot.Snapshot{
+				SchemaName: testSchema,
+				TableNames: []string{testTable},
+			},
+			conn: validQuerier(),
+			pgdumpFn: newMockPgdump(func(_ context.Context, i uint, po pglib.PGDumpOptions) ([]byte, error) {
+				switch i {
+				case 1:
+					require.Equal(t, pglib.PGDumpOptions{
+						ConnectionString: "source-url",
+						Format:           "p",
+						SchemaOnly:       true,
+						ExcludeSchemas:   []string{pglib.QuoteIdentifier(excludedSchema)},
+						ExcludeTables:    []string{pglib.QuoteIdentifier(excludedTable)},
+					}, po)
+					return schemaDumpNoSequences, nil
+				default:
+					return nil, fmt.Errorf("unexpected call to pgdumpFn: %d", i)
+				}
+			}),
+			pgrestoreFn: func(_ context.Context, po pglib.PGRestoreOptions, dump []byte) (string, error) {
+				require.Equal(t, pglib.PGRestoreOptions{
+					ConnectionString: "target-url",
+					Format:           "p",
+				}, po)
+				require.Equal(t, schemaDumpNoSequences, dump)
+				return "", nil
+			},
+
+			wantErr: nil,
+		},
 		{
 			name: "ok - with generator",
 			snapshot: &snapshot.Snapshot{
@@ -153,7 +188,7 @@ func TestSnapshotGenerator_CreateSnapshot(t *testing.T) {
 						ConnectionString: "source-url",
 						Format:           "p",
 						DataOnly:         true,
-						Tables:           []string{},
+						Tables:           []string{testSequence},
 					}, po)
 					return sequenceDump, nil
 				default:
@@ -209,7 +244,7 @@ func TestSnapshotGenerator_CreateSnapshot(t *testing.T) {
 						ConnectionString: "source-url",
 						Format:           "p",
 						DataOnly:         true,
-						Tables:           []string{},
+						Tables:           []string{testSequence},
 					}, po)
 					return sequenceDump, nil
 				default:
@@ -452,7 +487,7 @@ func TestSnapshotGenerator_CreateSnapshot(t *testing.T) {
 						ConnectionString: "source-url",
 						Format:           "p",
 						DataOnly:         true,
-						Tables:           []string{},
+						Tables:           []string{testSequence},
 					}, po)
 					return sequenceDump, nil
 				default:
@@ -506,7 +541,7 @@ func TestSnapshotGenerator_CreateSnapshot(t *testing.T) {
 						ConnectionString: "source-url",
 						Format:           "p",
 						DataOnly:         true,
-						Tables:           []string{},
+						Tables:           []string{testSequence},
 					}, po)
 					return sequenceDump, nil
 				default: