From 65ef54ccca4a7ba10607c08a3f3f5e43b236cb1a Mon Sep 17 00:00:00 2001 From: Evgenii-Zinner Date: Tue, 6 Jan 2026 14:41:02 +0700 Subject: [PATCH 1/3] Fix: Handle MariaDB sandbox mode during db import Detects the sandbox mode directive in the SQL file and switches to a piped import to avoid MariaDB syntax errors. --- features/db-import.feature | 18 +++++++++++++++ src/DB_Command.php | 45 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/features/db-import.feature b/features/db-import.feature index 5761fb24..e13a74cb 100644 --- a/features/db-import.feature +++ b/features/db-import.feature @@ -178,3 +178,21 @@ Feature: Import a WordPress database """ 🍣 """ + + Scenario: Import MariaDB sandbox dump + Given a WP install + And a sandbox.sql file: + """ + /*!999999\- enable the sandbox mode */ + INSERT INTO wp_terms (name, slug, term_group) VALUES ('Test Term', 'test-term', 0); + """ + + When I run `wp db import sandbox.sql` + Then STDOUT should contain: + """ + MariaDB sandbox mode directive detected. Skipping it by piping the file content. + """ + And STDOUT should contain: + """ + Success: Imported from 'sandbox.sql'. + """ \ No newline at end of file diff --git a/src/DB_Command.php b/src/DB_Command.php index 06781cee..829946d0 100644 --- a/src/DB_Command.php +++ b/src/DB_Command.php @@ -816,6 +816,51 @@ public function import( $args, $assoc_args ) { WP_CLI::error( sprintf( 'Import file missing or not readable: %s', $result_file ) ); } + // Check for MariaDB sandbox mode directive in the first line. + // This directive can interfere with standard imports by enabling a sandbox mode + // that restricts certain operations. We skip it by piping the file content + // and skipping the first line. + $fp = fopen( $result_file, 'r' ); + if ( ! $fp ) { + WP_CLI::error( sprintf( 'Unable to read import file: %s', $result_file ) ); + } + $first_line = fgets( $fp ); + fclose( $fp ); + + if ( 0 === strpos( $first_line, '/*!999999\- enable the sandbox mode */' ) ) { + WP_CLI::log( 'MariaDB sandbox mode directive detected. Skipping it by piping the file content.' ); + + $preamble = $this->get_sql_mode_query( $assoc_args ) . "\n"; + if ( ! Utils\get_flag_value( $assoc_args, 'skip-optimization' ) ) { + $preamble .= "SET autocommit = 0; SET unique_checks = 0; SET foreign_key_checks = 0;\n"; + } + + $postamble = Utils\get_flag_value( $assoc_args, 'skip-optimization' ) ? '' : "\nCOMMIT;\n"; + + // Use a shell pipeline to skip the first line and wrap the rest in transaction/optimizations. + $command = sprintf( + 'sh -c \'p="$1"; f="$2"; s="$3"; shift 3; ( printf "%%s" "$p"; tail -n +2 "$f"; printf "%%s" "$s" ) | %s %s --no-auto-rehash "$@"\' sh %s %s %s', + $this->get_mysql_command(), + $this->get_defaults_flag_string( $assoc_args ), + escapeshellarg( $preamble ), + escapeshellarg( $result_file ), + escapeshellarg( $postamble ) + ); + + // Ensure we don't pass 'execute' which would conflict with STDIN. + unset( $mysql_args['execute'] ); + + $result = self::run( $command, $mysql_args ); + + if ( 0 === $result['exit_code'] ) { + WP_CLI::success( sprintf( "Imported from '%s'.", $result_file ) ); + } else { + WP_CLI::error( sprintf( "Failed to import from '%s'.", $result_file ) ); + } + + return; + } + $query = Utils\get_flag_value( $assoc_args, 'skip-optimization' ) ? 'SOURCE %s;' : 'SET autocommit = 0; SET unique_checks = 0; SET foreign_key_checks = 0; SOURCE %s; COMMIT;'; From 17f55680c543340de40413cbf68dfcd6e343a299 Mon Sep 17 00:00:00 2001 From: Evgenii-Zinner Date: Tue, 6 Jan 2026 15:56:02 +0700 Subject: [PATCH 2/3] Fix: Remove explicit exit_code check and handle potential false from fgets --- src/DB_Command.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/DB_Command.php b/src/DB_Command.php index 829946d0..ad1efd91 100644 --- a/src/DB_Command.php +++ b/src/DB_Command.php @@ -827,9 +827,8 @@ public function import( $args, $assoc_args ) { $first_line = fgets( $fp ); fclose( $fp ); - if ( 0 === strpos( $first_line, '/*!999999\- enable the sandbox mode */' ) ) { + if ( false !== $first_line && 0 === strpos( $first_line, '/*!999999\- enable the sandbox mode */' ) ) { WP_CLI::log( 'MariaDB sandbox mode directive detected. Skipping it by piping the file content.' ); - $preamble = $this->get_sql_mode_query( $assoc_args ) . "\n"; if ( ! Utils\get_flag_value( $assoc_args, 'skip-optimization' ) ) { $preamble .= "SET autocommit = 0; SET unique_checks = 0; SET foreign_key_checks = 0;\n"; @@ -852,11 +851,9 @@ public function import( $args, $assoc_args ) { $result = self::run( $command, $mysql_args ); - if ( 0 === $result['exit_code'] ) { - WP_CLI::success( sprintf( "Imported from '%s'.", $result_file ) ); - } else { - WP_CLI::error( sprintf( "Failed to import from '%s'.", $result_file ) ); - } + self::run( $command, $mysql_args ); + + WP_CLI::success( sprintf( "Imported from '%s'.", $result_file ) ); return; } From 10e19a278cd9017930e83341acf90aed6d2a15fc Mon Sep 17 00:00:00 2001 From: Evgenii-Zinner Date: Tue, 6 Jan 2026 16:21:56 +0700 Subject: [PATCH 3/3] fix: broaden MariaDB sandbox mode detection MariaDB 10.11+ can output the sandbox header as /*M!999999\- enable the sandbox mode */. By checking for '999999' and 'sandbox mode' separately, we ensure compatibility across different MariaDB versions and escaping styles. --- src/DB_Command.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/DB_Command.php b/src/DB_Command.php index ad1efd91..25aa32fc 100644 --- a/src/DB_Command.php +++ b/src/DB_Command.php @@ -827,7 +827,7 @@ public function import( $args, $assoc_args ) { $first_line = fgets( $fp ); fclose( $fp ); - if ( false !== $first_line && 0 === strpos( $first_line, '/*!999999\- enable the sandbox mode */' ) ) { + if ( false !== $first_line && strpos( $first_line, '999999' ) !== false && strpos( $first_line, 'sandbox mode' ) !== false ) { WP_CLI::log( 'MariaDB sandbox mode directive detected. Skipping it by piping the file content.' ); $preamble = $this->get_sql_mode_query( $assoc_args ) . "\n"; if ( ! Utils\get_flag_value( $assoc_args, 'skip-optimization' ) ) { @@ -846,16 +846,16 @@ public function import( $args, $assoc_args ) { escapeshellarg( $postamble ) ); - // Ensure we don't pass 'execute' which would conflict with STDIN. - unset( $mysql_args['execute'] ); + // Ensure we don't pass 'execute' which would conflict with STDIN. + unset( $mysql_args['execute'] ); - $result = self::run( $command, $mysql_args ); + $result = self::run( $command, $mysql_args ); - self::run( $command, $mysql_args ); + self::run( $command, $mysql_args ); - WP_CLI::success( sprintf( "Imported from '%s'.", $result_file ) ); + WP_CLI::success( sprintf( "Imported from '%s'.", $result_file ) ); - return; + return; } $query = Utils\get_flag_value( $assoc_args, 'skip-optimization' )