diff --git a/pg4wp/rewriters/InsertSQLRewriter.php b/pg4wp/rewriters/InsertSQLRewriter.php index 50e9d59..89d28a3 100644 --- a/pg4wp/rewriters/InsertSQLRewriter.php +++ b/pg4wp/rewriters/InsertSQLRewriter.php @@ -8,15 +8,6 @@ class InsertSQLRewriter extends AbstractSQLRewriter $sql = $this->original(); - $sql = str_replace('(0,', "('0',", $sql); - $sql = str_replace('(1,', "('1',", $sql); - - // Fix inserts into wp_categories - if(false !== strpos($sql, 'INSERT INTO ' . $wpdb->categories)) { - $sql = str_replace('"cat_ID",', '', $sql); - $sql = str_replace("VALUES ('0',", "VALUES(", $sql); - } - // Those are used when we need to set the date to now() in gmt time $sql = str_replace("'0000-00-00 00:00:00'", 'now() AT TIME ZONE \'gmt\'', $sql); diff --git a/pg4wp/rewriters/ReplaceIntoSQLRewriter.php b/pg4wp/rewriters/ReplaceIntoSQLRewriter.php index 7f9e2b8..7e91948 100644 --- a/pg4wp/rewriters/ReplaceIntoSQLRewriter.php +++ b/pg4wp/rewriters/ReplaceIntoSQLRewriter.php @@ -96,6 +96,21 @@ class ReplaceIntoSQLRewriter extends AbstractSQLRewriter // Construct the PostgreSQL query $postgresSQL = sprintf('%s %s %s ON CONFLICT (%s) DO UPDATE SET %s', $tableSection, $columnsSection, $valuesSection, $primaryKey, $updateSection); + if(false === strpos($postgresSQL, 'RETURNING')) { + $end_of_statement = $this->findSemicolon($postgresSQL); + if ($end_of_statement !== false) { + // Create the substrings up to and after the semicolon + $sql_before_semicolon = substr($postgresSQL, 0, $end_of_statement); + $sql_after_semicolon = substr($postgresSQL, $end_of_statement, strlen($postgresSQL)); + + // Splice the SQL string together with 'RETURNING *' + $postgresSQL = $sql_before_semicolon . ' RETURNING *' . $sql_after_semicolon; + + } else { + $postgresSQL = $postgresSQL .= " RETURNING *"; + } + } + // Append to the converted statements list $convertedStatements[] = $postgresSQL; } @@ -104,4 +119,25 @@ class ReplaceIntoSQLRewriter extends AbstractSQLRewriter return $sql; } + + // finds semicolons that aren't in variables + private function findSemicolon($sql) + { + $quoteOpened = false; + $parenthesisDepth = 0; + + $sqlAsArray = str_split($sql); + for($i = 0; $i < count($sqlAsArray); $i++) { + if(($sqlAsArray[$i] == '"' || $sqlAsArray[$i] == "'") && ($i == 0 || $sqlAsArray[$i - 1] != '\\')) { + $quoteOpened = !$quoteOpened; + } elseif($sqlAsArray[$i] == '(' && !$quoteOpened) { + $parenthesisDepth++; + } elseif($sqlAsArray[$i] == ')' && !$quoteOpened) { + $parenthesisDepth--; + } elseif($sqlAsArray[$i] == ';' && !$quoteOpened && $parenthesisDepth == 0) { + return $i; + } + } + return false; + } } diff --git a/tests/rewriteTest.php b/tests/rewriteTest.php index 52c80fd..f91bdc4 100644 --- a/tests/rewriteTest.php +++ b/tests/rewriteTest.php @@ -444,7 +444,7 @@ final class rewriteTest extends TestCase public function test_it_can_handle_replacement_sql() { $sql = "REPLACE INTO test2 (column1, column2, column3) VALUES (1, 'Old', '2014-08-20 18:47:00')"; - $expected = "INSERT INTO test2 (column1, column2, column3) VALUES (1, 'Old', '2014-08-20 18:47:00') ON CONFLICT (column1) DO UPDATE SET column2 = EXCLUDED.column2, column3 = EXCLUDED.column3"; + $expected = "INSERT INTO test2 (column1, column2, column3) VALUES (1, 'Old', '2014-08-20 18:47:00') ON CONFLICT (column1) DO UPDATE SET column2 = EXCLUDED.column2, column3 = EXCLUDED.column3 RETURNING *"; $postgresql = pg4wp_rewrite($sql); $this->assertSame(trim($expected), trim($postgresql)); @@ -515,6 +515,59 @@ final class rewriteTest extends TestCase $this->assertSame(trim($expected), trim($postgresql)); } + public function test_it_can_handle_insert_sql_containing_nested_parathesis_with_numbers() + { + $sql = <<