append RETURNING * to REPLACE Commands

This commit is contained in:
Matthew Bucci
2024-02-26 23:31:22 -08:00
12 changed files with 99 additions and 19 deletions
-9
View File
@@ -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);
@@ -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;
}
}