Repository: xataio/pgstream
Pull request #309 (2025-04-29 13:18:57)

Error if table_transformers not provided, when there's a transformati…
…on config

github-actions[bot]: ### Merging this branch will **increase** overall coverage

| Impacted Packages | Coverage Δ | :robot: |
|-------------------|------------|---------|
| github.com/xataio/pgstream/cmd/config | 83.43% (**+1.18%**) | :thumbsup: |

---

<details>

<summary>Coverage by file</summary>

### Changed files (no unit tests)

| Changed File | Coverage Δ | Total | Covered | Missed | :robot: |
|--------------|------------|-------|---------|--------|---------|
| github.com/xataio/pgstream/cmd/config/config_yaml.go | 85.62% (**+2.61%**) | 153 | 131 (+4) | 22 (-4) | :thumbsup: |

_Please note that the "Total", "Covered", and "Missed" counts above refer to ***code statements*** instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code._

### Changed unit test files

- github.com/xataio/pgstream/cmd/config/config_yaml_test.go

</details>


Patch:
diff --git a/cmd/config/config_yaml.go b/cmd/config/config_yaml.go
index 5f9e0d5..e858495 100644
--- a/cmd/config/config_yaml.go
+++ b/cmd/config/config_yaml.go
@@ -197,9 +197,9 @@ type WebhookNotifierConfig struct {
 }
 
 type ModifiersConfig struct {
-	Injector        *InjectorConfig       `mapstructure:"injector" yaml:"injector"`
-	Transformations TransformationsConfig `mapstructure:"transformations" yaml:"transformations"`
-	Filter          *FilterConfig         `mapstructure:"filter" yaml:"filter"`
+	Injector        *InjectorConfig        `mapstructure:"injector" yaml:"injector"`
+	Transformations *TransformationsConfig `mapstructure:"transformations" yaml:"transformations"`
+	Filter          *FilterConfig          `mapstructure:"filter" yaml:"filter"`
 }
 
 type InjectorConfig struct {
@@ -268,6 +268,7 @@ var (
 	errUnsupportedPostgresSourceMode           = errors.New("unsupported postgres source mode, must be one of 'replication', 'snapshot' or 'snapshot_and_replication'")
 	errUnsupportedTransformationValidationMode = errors.New("unsupported transformation validation mode, must be one of 'strict', 'table_level' or 'relaxed'")
 	errUnsupportedTableValidationMode          = errors.New("unsupported table level validation mode, must be either 'strict' or 'relaxed'")
+	errTableTransformersNotProvided            = errors.New("table_transformers must be provided when transformation config is set")
 	errInvalidTableValidationConfig            = errors.New("table level validation mode should be used when transformation validation mode is set to 'table_level'")
 	errUnsupportedSearchEngine                 = errors.New("unsupported search engine, must be one of 'opensearch' or 'elasticsearch'")
 	errInvalidPgdumpPgrestoreConfig            = errors.New("pgdump_pgrestore snapshot mode requires target postgres config")
@@ -574,7 +575,8 @@ func (c *YAMLConfig) parseWebhookProcessorConfig() *stream.WebhookProcessorConfi
 }
 
 func (c *YAMLConfig) parseTransformationConfig() (*transformer.Config, error) {
-	if c.Modifiers.Transformations.TransformerRules == nil {
+	if c.Modifiers.Transformations == nil {
+		// no transformers configured
 		return nil, nil
 	}
 
@@ -593,7 +595,8 @@ func (c YAMLConfig) parseFilterConfig() *filter.Config {
 
 func (c TransformationsConfig) parseTransformationConfig() (*transformer.Config, error) {
 	if len(c.TransformerRules) == 0 {
-		return nil, nil
+		// transformation configuration provided, but no rules defined
+		return nil, errTableTransformersNotProvided
 	}
 
 	var globalValidationMode string


Test patch:
diff --git a/cmd/config/config_yaml_test.go b/cmd/config/config_yaml_test.go
index 692b904..8202793 100644
--- a/cmd/config/config_yaml_test.go
+++ b/cmd/config/config_yaml_test.go
@@ -142,6 +142,19 @@ func TestYAMLConfig_toStreamConfig_ErrorCases(t *testing.T) {
 
 			wantErr: errInvalidInjectorConfig,
 		},
+		{
+			name: "err - invalid transformers config",
+			config: YAMLConfig{
+				Modifiers: ModifiersConfig{
+					Transformations: &TransformationsConfig{
+						ValidationMode:   "strict",
+						TransformerRules: nil,
+					},
+				},
+			},
+
+			wantErr: errTableTransformersNotProvided,
+		},
 	}
 
 	for _, tt := range tests {