From 5d8407d244bc4cd399a11f339d55ef9dd38088a3 Mon Sep 17 00:00:00 2001 From: Matthew Bucci Date: Fri, 18 Oct 2024 22:41:40 -0700 Subject: [PATCH] add date casting examples --- pg4wp/rewriters/SelectSQLRewriter.php | 32 ++++++++ tests/parseTest.php | 2 + tests/rewriteTest.php | 110 ++++++++++++++++++++++++++ 3 files changed, 144 insertions(+) diff --git a/pg4wp/rewriters/SelectSQLRewriter.php b/pg4wp/rewriters/SelectSQLRewriter.php index 7f8899d..fdf8ccd 100644 --- a/pg4wp/rewriters/SelectSQLRewriter.php +++ b/pg4wp/rewriters/SelectSQLRewriter.php @@ -68,8 +68,40 @@ class SelectSQLRewriter extends AbstractSQLRewriter // HANDLE REGEXP $sql = preg_replace('/REGEXP/', '~', $sql); + // Replace utc_timestamp with equivalent $sql = str_replace("utc_timestamp()", "CURRENT_TIMESTAMP AT TIME ZONE 'UTC'", $sql); + // Remove quotes from order by statmeents + $sql = preg_replace("/ORDER BY\s+'(\w+)'\s*(ASC|DESC)?/i", "ORDER BY $1 $2", $sql); + + // remove backticks + $sql = preg_replace('/`/', '', $sql); + + // rewrite DATE function + $sql = preg_replace('/DATE\(([^)]+)\)/i', '$1::date', $sql); + + // Replace SUBSTRING_INDEX with PostgreSQL equivalent (split_part) + // Match the structure: SUBSTRING_INDEX(..., 'delimiter', number) + $sql = preg_replace_callback( + '/SUBSTRING_INDEX\(\s*(.+?)\s*,\s*\'([^\']+)\'\s*,\s*(\d+)\s*\)/i', + function ($matches) { + // Convert to split_part(column, 'delimiter', number) + $column = $matches[1]; + $delimiter = $matches[2]; + $number = $matches[3]; + + // If the number is positive, use split_part directly, + // else we can adjust for negative numbers by manually counting parts (not supported by split_part). + if ($number > 0) { + return "split_part($column, '$delimiter', $number)"; + } else { + // Handle the negative case if needed (split_part doesn't directly support negative indexing). + return "reverse(split_part(reverse($column), '$delimiter', " . abs($number) . "))"; + } + }, + $sql + ); + // In order for users counting to work... $matches = array(); if(preg_match_all('/COUNT[^C]+\),/', $sql, $matches)) { diff --git a/tests/parseTest.php b/tests/parseTest.php index ca58a5f..e49a2be 100644 --- a/tests/parseTest.php +++ b/tests/parseTest.php @@ -33,6 +33,8 @@ final class parseTest extends TestCase $this->assertSame($GLOBALS['pg4wp_ins_field'], "post_author"); } + + protected function setUp(): void { global $wpdb; diff --git a/tests/rewriteTest.php b/tests/rewriteTest.php index 7555682..ea3ddfe 100644 --- a/tests/rewriteTest.php +++ b/tests/rewriteTest.php @@ -785,6 +785,116 @@ final class rewriteTest extends TestCase $this->assertSame(trim($expected), trim($postgresql)); } + public function test_it_handles_order_by_on_non_integer() + { + $sql = <<assertSame(trim($expected), trim($postgresql)); + } + + public function test_it_replaces_backticks_with_quotes() + { + $sql = <<assertSame(trim($expected), trim($postgresql)); + } + + + public function test_it_replaces_backticks_substring_index_with_split_part() + { + $sql = << '' + AND LENGTH(referred) >=12 + AND `last_counter` BETWEEN '2024-09-20' AND '2024-10-19' + AND `referred` NOT LIKE 'http://wordpress.localhost%' + AND `referred` NOT LIKE 'http://www.wordpress.localhost%' + AND `referred` NOT LIKE 'https://wordpress.localhost%' + AND `referred` NOT LIKE 'https://www.wordpress.localhost%' + AND `referred` NOT LIKE 'ftp://wordpress.localhost%' + AND `referred` NOT LIKE 'ftp://www.wordpress.localhost%' + GROUP BY domain + ORDER BY `number` DESC LIMIT 10 + SQL; + + $expected = << '' + AND LENGTH(referred) >= 12 + AND last_counter BETWEEN '2024-09-20' AND '2024-10-19' + AND referred NOT LIKE 'http://wordpress.localhost%' + AND referred NOT LIKE 'http://www.wordpress.localhost%' + AND referred NOT LIKE 'https://wordpress.localhost%' + AND referred NOT LIKE 'https://www.wordpress.localhost%' + AND referred NOT LIKE 'ftp://wordpress.localhost%' + AND referred NOT LIKE 'ftp://www.wordpress.localhost%' + GROUP BY domain + ORDER BY number DESC + LIMIT 10; + SQL; + + $postgresql = pg4wp_rewrite($sql); + $this->assertSame(trim($expected), trim($postgresql)); + } + + public function test_it_converts_to_date_casting() + { + $sql = <<assertSame(trim($expected), trim($postgresql)); + } + + public function test_it_converts_to_date_casting_another_example() + { + $sql = <<assertSame(trim($expected), trim($postgresql)); + } + + public function test_it_correctly_handles_alias_orderBys() + { + $sql = <<assertSame(trim($expected), trim($postgresql)); + } + protected function setUp(): void { global $wpdb;