Repository: cloudnative-pg/cloudnative-pg

Issue:
[Feature]: Allow extra pg_dump/pg_restore settings to apply only to predata/postdata
### Is there an existing issue already for this feature request/idea?

- [x] I have searched for an existing issue, and could not find anything. I believe this is a new feature request to be evaluated.

### What problem is this feature going to solve? Why should it be added?

Importing a db with pg_dump using a single worker is slow. There is also no easy hook for the `SELECT timescaledb_pre_restore();` and `SELECT timescaledb_post_restore();` functions.

### Describe the solution you'd like

A common pattern is to split the job into pgdumps predata, data, and postdata stages. You generally want to use a single worker when copying the schema, many workers when copying the actual data, and at least one worker when applying constraints at the end depending on how fast that is. The current extra settings flag does not give you the control to do this.

I'm willing to work on this feature. Looking at the existing codebase, this does look like a good first issue assuming prior experience with pg_dump, since the import section is fairly self-contained.

### Describe alternatives you've considered

Running a shell script by piping to kubectl exec sh). This is pretty close to what we do now, since pg_dump/pg_restore is fairly independent of how it runs.

Other options would be to have a CNPG-I plugin for other restore options like pgcopydb. Another is to not bother with any optimizations but to add six lines to  detect whether timescaledb is a preloaded extension and if so to run the  `SELECT timescaledb_pre_restore();` and `SELECT timescaledb_post_restore();` functions which are required to load the backup correctly, with no API changes and only a fix to import databases with a common extension.

### Additional context

Exposing a good API for this is tricky and this is something I'd like a maintainer opinion on. 

### Backport?

No

### Are you willing to actively contribute to this feature?

Yes

### Code of Conduct

- [x] I agree to follow this project's Code of Conduct

Hints from issue comments:
@hanshal101: Hey @gbartolini are you still working on this? If not I would like to pick up!@saolof: I can work on this during weekends, but if someone else wants to work on it I have zero complaints@anthonypelletier: looking for a preinitsql too@github-actions: This issue is stale because it has been open for 60 days with no activity.@gbartolini: I am moving this to 1.28 as we are in feature freeze and we are not planning a second RC release.

Solution patch:
diff --git a/.wordlist-en-custom.txt b/.wordlist-en-custom.txt
index 4a3eb7ec..876f8e0a 100644
--- a/.wordlist-en-custom.txt
+++ b/.wordlist-en-custom.txt
@@ -1125,7 +1125,10 @@ pgBouncerIntegration
 pgBouncerSecrets
 pgDataImageInfo
 pgDumpExtraOptions
+pgRestoreDataOptions
 pgRestoreExtraOptions
+pgRestorePostdataOptions
+pgRestorePredataOptions
 pgRouting
 pgSQL
 pgadmin
diff --git a/api/v1/cluster_types.go b/api/v1/cluster_types.go
index 94006080..77f9f06c 100644
--- a/api/v1/cluster_types.go
+++ b/api/v1/cluster_types.go
@@ -1782,19 +1782,58 @@ type Import struct {
 	// +optional
 	SchemaOnly bool `json:"schemaOnly,omitempty"`
 
-	// List of custom options to pass to the `pg_dump` command. IMPORTANT:
-	// Use these options with caution and at your own risk, as the operator
-	// does not validate their content. Be aware that certain options may
-	// conflict with the operator's intended functionality or design.
+	// List of custom options to pass to the `pg_dump` command.
+	//
+	// IMPORTANT: Use with caution. The operator does not validate these options,
+	// and certain flags may interfere with its intended functionality or design.
+	// You are responsible for ensuring that the provided options are compatible
+	// with your environment and desired behavior.
+	//
 	// +optional
 	PgDumpExtraOptions []string `json:"pgDumpExtraOptions,omitempty"`
 
-	// List of custom options to pass to the `pg_restore` command. IMPORTANT:
-	// Use these options with caution and at your own risk, as the operator
-	// does not validate their content. Be aware that certain options may
-	// conflict with the operator's intended functionality or design.
+	// List of custom options to pass to the `pg_restore` command.
+	//
+	// IMPORTANT: Use with caution. The operator does not validate these options,
+	// and certain flags may interfere with its intended functionality or design.
+	// You are responsible for ensuring that the provided options are compatible
+	// with your environment and desired behavior.
+	//
 	// +optional
 	PgRestoreExtraOptions []string `json:"pgRestoreExtraOptions,omitempty"`
+
+	// Custom options to pass to the `pg_restore` command during the `pre-data`
+	// section. This setting overrides the generic `pgRestoreExtraOptions` value.
+	//
+	// IMPORTANT: Use with caution. The operator does not validate these options,
+	// and certain flags may interfere with its intended functionality or design.
+	// You are responsible for ensuring that the provided options are compatible
+	// with your environment and desired behavior.
+	//
+	// +optional
+	PgRestorePredataOptions []string `json:"pgRestorePredataOptions,omitempty"`
+
+	// Custom options to pass to the `pg_restore` command during the `data`
+	// section. This setting overrides the generic `pgRestoreExtraOptions` value.
+	//
+	// IMPORTANT: Use with caution. The operator does not validate these options,
+	// and certain flags may interfere with its intended functionality or design.
+	// You are responsible for ensuring that the provided options are compatible
+	// with your environment and desired behavior.
+	//
+	// +optional
+	PgRestoreDataOptions []string `json:"pgRestoreDataOptions,omitempty"`
+
+	// Custom options to pass to the `pg_restore` command during the `post-data`
+	// section. This setting overrides the generic `pgRestoreExtraOptions` value.
+	//
+	// IMPORTANT: Use with caution. The operator does not validate these options,
+	// and certain flags may interfere with its intended functionality or design.
+	// You are responsible for ensuring that the provided options are compatible
+	// with your environment and desired behavior.
+	//
+	// +optional
+	PgRestorePostdataOptions []string `json:"pgRestorePostdataOptions,omitempty"`
 }
 
 // ImportSource describes the source for the logical snapshot
diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go
index e712ac32..1239af87 100644
--- a/api/v1/zz_generated.deepcopy.go
+++ b/api/v1/zz_generated.deepcopy.go
@@ -1627,6 +1627,21 @@ func (in *Import) DeepCopyInto(out *Import) {
 		*out = make([]string, len(*in))
 		copy(*out, *in)
 	}
+	if in.PgRestorePredataOptions != nil {
+		in, out := &in.PgRestorePredataOptions, &out.PgRestorePredataOptions
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
+	if in.PgRestoreDataOptions != nil {
+		in, out := &in.PgRestoreDataOptions, &out.PgRestoreDataOptions
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
+	if in.PgRestorePostdataOptions != nil {
+		in, out := &in.PgRestorePostdataOptions, &out.PgRestorePostdataOptions
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Import.
diff --git a/config/crd/bases/postgresql.cnpg.io_clusters.yaml b/config/crd/bases/postgresql.cnpg.io_clusters.yaml
index ba89604e..558e406a 100644
--- a/config/crd/bases/postgresql.cnpg.io_clusters.yaml
+++ b/config/crd/bases/postgresql.cnpg.io_clusters.yaml
@@ -1534,19 +1534,59 @@ spec:
                             type: array
                           pgDumpExtraOptions:
                             description: |-
-                              List of custom options to pass to the `pg_dump` command. IMPORTANT:
-                              Use these options with caution and at your own risk, as the operator
-                              does not validate their content. Be aware that certain options may
-                              conflict with the operator's intended functionality or design.
+                              List of custom options to pass to the `pg_dump` command.
+
+                              IMPORTANT: Use with caution. The operator does not validate these options,
+                              and certain flags may interfere with its intended functionality or design.
+                              You are responsible for ensuring that the provided options are compatible
+                              with your environment and desired behavior.
+                            items:
+                              type: string
+                            type: array
+                          pgRestoreDataOptions:
+                            description: |-
+                              Custom options to pass to the `pg_restore` command during the `data`
+                              section. This setting overrides the generic `pgRestoreExtraOptions` value.
+
+                              IMPORTANT: Use with caution. The operator does not validate these options,
+                              and certain flags may interfere with its intended functionality or design.
+                              You are responsible for ensuring that the provided options are compatible
+                              with your environment and desired behavior.
                             items:
                               type: string
                             type: array
                           pgRestoreExtraOptions:
                             description: |-
-                              List of custom options to pass to the `pg_restore` command. IMPORTANT:
-                              Use these options with caution and at your own risk, as the operator
-                              does not validate their content. Be aware that certain options may
-                              conflict with the operator's intended functionality or design.
+                              List of custom options to pass to the `pg_restore` command.
+
+                              IMPORTANT: Use with caution. The operator does not validate these options,
+                              and certain flags may interfere with its intended functionality or design.
+                              You are responsible for ensuring that the provided options are compatible
+                              with your environment and desired behavior.
+                            items:
+                              type: string
+                            type: array
+                          pgRestorePostdataOptions:
+                            description: |-
+                              Custom options to pass to the `pg_restore` command during the `post-data`
+                              section. This setting overrides the generic `pgRestoreExtraOptions` value.
+
+                              IMPORTANT: Use with caution. The operator does not validate these options,
+                              and certain flags may interfere with its intended functionality or design.
+                              You are responsible for ensuring that the provided options are compatible
+                              with your environment and desired behavior.
+                            items:
+                              type: string
+                            type: array
+                          pgRestorePredataOptions:
+                            description: |-
+                              Custom options to pass to the `pg_restore` command during the `pre-data`
+                              section. This setting overrides the generic `pgRestoreExtraOptions` value.
+
+                              IMPORTANT: Use with caution. The operator does not validate these options,
+                              and certain flags may interfere with its intended functionality or design.
+                              You are responsible for ensuring that the provided options are compatible
+                              with your environment and desired behavior.
                             items:
                               type: string
                             type: array
diff --git a/docs/src/cloudnative-pg.v1.md b/docs/src/cloudnative-pg.v1.md
index 731f8aaf..a772d014 100644
--- a/docs/src/cloudnative-pg.v1.md
+++ b/docs/src/cloudnative-pg.v1.md
@@ -3348,20 +3348,58 @@ database right after is imported - to be used with extreme care
 <i>[]string</i>
 </td>
 <td>
-   <p>List of custom options to pass to the <code>pg_dump</code> command. IMPORTANT:
-Use these options with caution and at your own risk, as the operator
-does not validate their content. Be aware that certain options may
-conflict with the operator's intended functionality or design.</p>
+   <p>List of custom options to pass to the <code>pg_dump</code> command.</p>
+<p>IMPORTANT: Use with caution. The operator does not validate these options,
+and certain flags may interfere with its intended functionality or design.
+You are responsible for ensuring that the provided options are compatible
+with your environment and desired behavior.</p>
 </td>
 </tr>
 <tr><td><code>pgRestoreExtraOptions</code><br/>
 <i>[]string</i>
 </td>
 <td>
-   <p>List of custom options to pass to the <code>pg_restore</code> command. IMPORTANT:
-Use these options with caution and at your own risk, as the operator
-does not validate their content. Be aware that certain options may
-conflict with the operator's intended functionality or design.</p>
+   <p>List of custom options to pass to the <code>pg_restore</code> command.</p>
+<p>IMPORTANT: Use with caution. The operator does not validate these options,
+and certain flags may interfere with its intended functionality or design.
+You are responsible for ensuring that the provided options are compatible
+with your environment and desired behavior.</p>
+</td>
+</tr>
+<tr><td><code>pgRestorePredataOptions</code><br/>
+<i>[]string</i>
+</td>
+<td>
+   <p>Custom options to pass to the <code>pg_restore</code> command during the <code>pre-data</code>
+section. This setting overrides the generic <code>pgRestoreExtraOptions</code> value.</p>
+<p>IMPORTANT: Use with caution. The operator does not validate these options,
+and certain flags may interfere with its intended functionality or design.
+You are responsible for ensuring that the provided options are compatible
+with your environment and desired behavior.</p>
+</td>
+</tr>
+<tr><td><code>pgRestoreDataOptions</code><br/>
+<i>[]string</i>
+</td>
+<td>
+   <p>Custom options to pass to the <code>pg_restore</code> command during the <code>data</code>
+section. This setting overrides the generic <code>pgRestoreExtraOptions</code> value.</p>
+<p>IMPORTANT: Use with caution. The operator does not validate these options,
+and certain flags may interfere with its intended functionality or design.
+You are responsible for ensuring that the provided options are compatible
+with your environment and desired behavior.</p>
+</td>
+</tr>
+<tr><td><code>pgRestorePostdataOptions</code><br/>
+<i>[]string</i>
+</td>
+<td>
+   <p>Custom options to pass to the <code>pg_restore</code> command during the <code>post-data</code>
+section. This setting overrides the generic <code>pgRestoreExtraOptions</code> value.</p>
+<p>IMPORTANT: Use with caution. The operator does not validate these options,
+and certain flags may interfere with its intended functionality or design.
+You are responsible for ensuring that the provided options are compatible
+with your environment and desired behavior.</p>
 </td>
 </tr>
 </tbody>
diff --git a/docs/src/database_import.md b/docs/src/database_import.md
index 593ea430..e79d9f23 100644
--- a/docs/src/database_import.md
+++ b/docs/src/database_import.md
@@ -247,7 +247,7 @@ There are a few things you need to be aware of when using the `monolith` type:
     - The `SUPERUSER` option is removed from any imported role
 - Wildcard `"*"` can be used as the only element in the `databases` and/or
   `roles` arrays to import every object of the kind; When matching databases
-  the wildcard will ignore the `postgres` database, template databases,
+  the wildcard will ignore the `postgres` database, template databases
   and those databases not allowing connections
 - After the clone procedure is done, `ANALYZE VERBOSE` is executed for every
   database.
@@ -390,36 +390,84 @@ unnecessary writes in the checkpoint area by tuning Postgres GUCs like
 `shared_buffers`, `max_wal_size`, `checkpoint_timeout` directly in the
 `Cluster` configuration.
 
-## Customizing `pg_dump` and `pg_restore` Behavior
+## Customizing `pg_dump` and `pg_restore` behavior
 
-You can customize the behavior of `pg_dump` and `pg_restore` by specifying
-additional options using the `pgDumpExtraOptions` and `pgRestoreExtraOptions`
-parameters. For instance, you can enable parallel jobs to speed up data
-import/export processes, as shown in the following example:
+You can customize the behavior of `pg_dump` and `pg_restore` by specifying additional
+options using the `pgDumpExtraOptions` and `pgRestoreExtraOptions` parameters.
+This is especially useful for improving performance or managing import/export complexity.
+
+For example, enabling parallel jobs can significantly speed up data transfer:
 
 ```yaml
-  # <snip>
-  bootstrap:
-    initdb:
-      import:
-        type: microservice
-        databases:
-        - app
-        source:
-          externalCluster: cluster-example
-        pgDumpExtraOptions:
-        - '--jobs=2'
-        pgRestoreExtraOptions:
+bootstrap:
+  initdb:
+    import:
+      type: microservice
+      databases:
+      - app
+      source:
+        externalCluster: cluster-example
+      pgDumpExtraOptions:
+      - '--jobs=2'
+      pgRestoreExtraOptions:
+      - '--jobs=2'
+```
+
+### Stage-Specific `pg_restore` options
+
+For more granular control over the import process, CloudNativePG supports
+stage-specific `pg_restore` options for the following phases:
+
+- `pre-data` – e.g., schema definitions
+- `data` – e.g., table contents
+- `post-data` – e.g., indexes, constraints and triggers
+
+By specifying options for each phase, you can optimize parallelism and apply
+flags tailored to the nature of the objects being restored.
+
+```yaml
+bootstrap:
+  initdb:
+    import:
+      type: microservice
+      schemaOnly: false
+      databases:
+        - mynewdb
+      source:
+        externalCluster: sourcedb-external
+      pgRestorePredataOptions:
+        - '--jobs=1'
+      pgRestoreDataOptions:
+        - '--jobs=4'
+      pgRestorePostdataOptions:
         - '--jobs=2'
-  # <snip>
 ```
 
+In the example above:
+
+- `--jobs=1` is applied to the `pre-data` stage to preserve the ordering of
+  schema creation.
+- `--jobs=4` increases parallelism during the `data` stage, speeding up large
+  data imports.
+- `--jobs=2` balances performance and dependency handling in the `post-data`
+  stage.
+
+These stage-specific settings are particularly valuable for large databases or
+resource-sensitive environments where tuning concurrency can significantly
+improve performance.
+
+!!! Note
+    When provided, stage-specific options take precedence over the general
+    `pgRestoreExtraOptions`.
+
 !!! Warning
-    Use the `pgDumpExtraOptions` and `pgRestoreExtraOptions` fields with
-    caution and at your own risk. These options are not validated or verified by
-    the operator, and some configurations may conflict with its intended
-    functionality or behavior. Always test thoroughly in a safe and controlled
-    environment before applying them in production.
+    The `pgDumpExtraOptions`, `pgRestoreExtraOptions`, and all stage-specific
+    restore options (`pgRestorePredataOptions`, `pgRestoreDataOptions`,
+    `pgRestorePostdataOptions`) are passed directly to the underlying PostgreSQL
+    tools without validation by the operator. Certain flags may conflict with the
+    operator’s intended functionality or design. Use these options with caution
+    and always test them thoroughly in a safe, controlled environment before
+    applying them in production.
 
 ## Online Import and Upgrades
 
diff --git a/pkg/management/postgres/logicalimport/database.go b/pkg/management/postgres/logicalimport/database.go
index eb485075..a091506e 100644
--- a/pkg/management/postgres/logicalimport/database.go
+++ b/pkg/management/postgres/logicalimport/database.go
@@ -128,17 +128,17 @@ func (ds *databaseSnapshotter) importDatabases(
 	ctx context.Context,
 	target pool.Pooler,
 	databases []string,
-	extraOptions []string,
+	flags sectionOptions,
 ) error {
 	contextLogger := log.FromContext(ctx)
 
 	for _, database := range databases {
-		for _, section := range ds.getSectionsToExecute() {
+		for _, sec := range ds.getSectionsToExecute() {
 			targetDatabase := target.GetDsn(database)
 			contextLogger.Info(
 				"executing database importing section",
 				"databaseName", database,
-				"section", section,
+				"section", sec,
 			)
 
 			exists, err := ds.databaseExists(target, database)
@@ -158,11 +158,11 @@ func (ds *databaseSnapshotter) importDatabases(
 			alwaysPresentOptions := []string{
 				"-U", "postgres",
 				"-d", targetDatabase,
-				"--section", section,
+				"--section", string(sec),
 				generateFileNameForDatabase(database),
 			}
 
-			options = append(options, extraOptions...)
+			options = append(options, flags.forSection(sec)...)
 			options = append(options, alwaysPresentOptions...)
 
 			contextLogger.Info("Running pg_restore",
@@ -172,7 +172,7 @@ func (ds *databaseSnapshotter) importDatabases(
 			pgRestoreCommand := exec.Command(pgRestore, options...) // #nosec
 			err = execlog.RunStreaming(pgRestoreCommand, pgRestore)
 			if err != nil {
-				return fmt.Errorf("error while executing pg_restore, section:%s, %w", section, err)
+				return fmt.Errorf("error while executing pg_restore, section:%s, %w", sec, err)
 			}
 		}
 	}
@@ -186,7 +186,7 @@ func (ds *databaseSnapshotter) importDatabaseContent(
 	database string,
 	targetDatabase string,
 	owner string,
-	extraOptions []string,
+	flags sectionOptions,
 ) error {
 	contextLogger := log.FromContext(ctx)
 
@@ -220,11 +220,11 @@ func (ds *databaseSnapshotter) importDatabaseContent(
 			"--no-privileges",
 			fmt.Sprintf("--role=%s", owner),
 			"-d", targetDatabase,
-			"--section", section,
+			"--section", string(section),
 			generateFileNameForDatabase(database),
 		}
 
-		options = append(options, extraOptions...)
+		options = append(options, flags.forSection(section)...)
 		options = append(options, alwaysPresentOptions...)
 
 		contextLogger.Info("Running pg_restore",
@@ -364,16 +364,17 @@ func (ds *databaseSnapshotter) dropExtensionsFromDatabase(
 // getSectionsToExecute determines which stages of `pg_restore` and `pg_dump` to execute,
 // based on the configuration of the cluster. It returns a slice of strings representing
 // the sections to execute. These sections are labeled as "pre-data", "data", and "post-data".
-func (ds *databaseSnapshotter) getSectionsToExecute() []string {
-	const (
-		preData  = "pre-data"
-		data     = "data"
-		postData = "post-data"
-	)
-
+func (ds *databaseSnapshotter) getSectionsToExecute() []section {
 	if ds.cluster.Spec.Bootstrap.InitDB.Import.SchemaOnly {
-		return []string{preData, postData}
+		return []section{
+			sectionPreData,
+			sectionPostData,
+		}
 	}
 
-	return []string{preData, data, postData}
+	return []section{
+		sectionPreData,
+		sectionData,
+		sectionPostData,
+	}
 }
diff --git a/pkg/management/postgres/logicalimport/microservice.go b/pkg/management/postgres/logicalimport/microservice.go
index de461ba1..9c93418d 100644
--- a/pkg/management/postgres/logicalimport/microservice.go
+++ b/pkg/management/postgres/logicalimport/microservice.go
@@ -69,7 +69,7 @@ func Microservice(
 		databases[0],
 		initDB.Database,
 		initDB.Owner,
-		initDB.Import.PgRestoreExtraOptions,
+		buildPgRestoreSectionOptions(initDB.Import),
 	); err != nil {
 		return err
 	}
diff --git a/pkg/management/postgres/logicalimport/monolith.go b/pkg/management/postgres/logicalimport/monolith.go
index 017ef6e6..ed46c109 100644
--- a/pkg/management/postgres/logicalimport/monolith.go
+++ b/pkg/management/postgres/logicalimport/monolith.go
@@ -70,7 +70,7 @@ func Monolith(
 		ctx,
 		destination,
 		databases,
-		cluster.Spec.Bootstrap.InitDB.Import.PgRestoreExtraOptions,
+		buildPgRestoreSectionOptions(cluster.Spec.Bootstrap.InitDB.Import),
 	); err != nil {
 		return err
 	}
diff --git a/pkg/management/postgres/logicalimport/section.go b/pkg/management/postgres/logicalimport/section.go
new file mode 100644
index 00000000..a6bc94ec
--- /dev/null
+++ b/pkg/management/postgres/logicalimport/section.go
@@ -0,0 +1,70 @@
+/*
+Copyright © contributors to CloudNativePG, established as
+CloudNativePG a Series of LF Projects, LLC.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package logicalimport
+
+import apiv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
+
+// section is a possible value of the --section flag
+type section string
+
+const (
+	// sectionPreData represents the pre-data section
+	sectionPreData section = "pre-data"
+
+	// sectionData represents the data section
+	sectionData section = "data"
+
+	// sectionPostData represents the post-data section
+	sectionPostData section = "post-data"
+)
+
+// sectionOptions contain the options to be used when invoking the --section flag
+type sectionOptions struct {
+	// fallbackOptions the default values to use for when no specific option is available
+	fallbackOptions []string
+
+	// specificOptions contains specific options for a given section
+	specificOptions map[section][]string
+}
+
+// forSection gets the options that should be used for the
+// option with the specified name
+func (opts *sectionOptions) forSection(name section) []string {
+	result, ok := opts.specificOptions[name]
+	if ok && len(result) > 0 {
+		return result
+	}
+
+	return opts.fallbackOptions
+}
+
+// buildPgRestoreSectionOptions creates the pg_restore options for a database import
+func buildPgRestoreSectionOptions(importBootstrap *apiv1.Import) sectionOptions {
+	result := sectionOptions{
+		fallbackOptions: importBootstrap.PgRestoreExtraOptions,
+		specificOptions: make(map[section][]string),
+	}
+
+	result.specificOptions[sectionPreData] = importBootstrap.PgRestorePredataOptions
+	result.specificOptions[sectionData] = importBootstrap.PgRestoreDataOptions
+	result.specificOptions[sectionPostData] = importBootstrap.PgRestorePostdataOptions
+
+	return result
+}



Test patch:
diff --git a/pkg/management/postgres/logicalimport/section_test.go b/pkg/management/postgres/logicalimport/section_test.go
new file mode 100644
index 00000000..b2194cea
--- /dev/null
+++ b/pkg/management/postgres/logicalimport/section_test.go
@@ -0,0 +1,68 @@
+/*
+Copyright © contributors to CloudNativePG, established as
+CloudNativePG a Series of LF Projects, LLC.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package logicalimport
+
+import (
+	apiv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
+
+	. "github.com/onsi/ginkgo/v2"
+	. "github.com/onsi/gomega"
+)
+
+var _ = Describe("pg_restore options management", func() {
+	var importBootstrap *apiv1.Import
+
+	BeforeEach(func() {
+		importBootstrap = &apiv1.Import{
+			PgRestoreExtraOptions:    []string{"--extra-options"},
+			PgRestorePredataOptions:  []string{"--predata-options"},
+			PgRestoreDataOptions:     []string{"--data-options"},
+			PgRestorePostdataOptions: []string{"--postdata-options"},
+		}
+	})
+
+	It("creates the options from the import bootstrap method", func() {
+		options := buildPgRestoreSectionOptions(importBootstrap)
+		Expect(options).NotTo(BeNil())
+		Expect(options.forSection(sectionPreData)).To(ConsistOf("--predata-options"))
+		Expect(options.forSection(sectionData)).To(ConsistOf("--data-options"))
+		Expect(options.forSection(sectionPostData)).To(ConsistOf("--postdata-options"))
+	})
+
+	It("defaults a section to the common options, when the specific options are empty", func() {
+		importBootstrap.PgRestoreDataOptions = nil
+		options := buildPgRestoreSectionOptions(importBootstrap)
+		Expect(options).NotTo(BeNil())
+		Expect(options.forSection(sectionPreData)).To(ConsistOf("--predata-options"))
+		Expect(options.forSection(sectionData)).To(ConsistOf("--extra-options"))
+		Expect(options.forSection(sectionPostData)).To(ConsistOf("--postdata-options"))
+	})
+
+	It("defaults every section to the common options when needed", func() {
+		importBootstrap = &apiv1.Import{
+			PgRestoreExtraOptions: []string{"--extra-options"},
+		}
+		options := buildPgRestoreSectionOptions(importBootstrap)
+		Expect(options).NotTo(BeNil())
+		Expect(options.forSection(sectionPreData)).To(ConsistOf("--extra-options"))
+		Expect(options.forSection(sectionData)).To(ConsistOf("--extra-options"))
+		Expect(options.forSection(sectionPostData)).To(ConsistOf("--extra-options"))
+	})
+})