88use PhpMyAdmin \DatabaseInterface ;
99use PhpMyAdmin \Html ;
1010use PhpMyAdmin \SqlParser \Parser ;
11- use PhpMyAdmin \SqlParser \Statement ;
1211use PhpMyAdmin \SqlParser \Statements \DeleteStatement ;
1312use PhpMyAdmin \SqlParser \Statements \UpdateStatement ;
1413use PhpMyAdmin \SqlParser \Utils \Query ;
@@ -37,28 +36,27 @@ public function getError(): string
3736 * @return array<string, int|string>
3837 * @psalm-return array{
3938 * sql_query: string,
40- * matched_rows: ( int|numeric-string) ,
39+ * matched_rows: int,
4140 * matched_rows_url: string
4241 * }
4342 */
4443 public function getMatchedRows (
4544 string $ query ,
4645 Parser $ parser ,
47- DeleteStatement |UpdateStatement | Statement $ statement ,
46+ DeleteStatement |UpdateStatement $ statement ,
4847 ): array {
49- $ matchedRowQuery = '' ;
5048 if ($ statement instanceof DeleteStatement) {
51- $ matchedRowQuery = $ this ->getSimulatedDeleteQuery ($ parser , $ statement );
52- } elseif ( $ statement instanceof UpdateStatement) {
53- $ matchedRowQuery = $ this ->getSimulatedUpdateQuery ($ parser , $ statement );
49+ $ matchedRowsQuery = $ this ->getSimulatedDeleteQuery ($ parser , $ statement );
50+ } else {
51+ $ matchedRowsQuery = $ this ->getSimulatedUpdateQuery ($ parser , $ statement );
5452 }
5553
5654 // Execute the query and get the number of matched rows.
57- $ matchedRows = $ this ->executeMatchedRowQuery ($ matchedRowQuery );
55+ $ matchedRows = $ this ->executeMatchedRowQuery ($ matchedRowsQuery );
5856 $ matchedRowsUrl = Url ::getFromRoute ('/sql ' , [
5957 'db ' => $ GLOBALS ['db ' ],
60- 'sql_query ' => $ matchedRowQuery ,
61- 'sql_signature ' => Core ::signSqlQuery ($ matchedRowQuery ),
58+ 'sql_query ' => $ matchedRowsQuery ,
59+ 'sql_signature ' => Core ::signSqlQuery ($ matchedRowsQuery ),
6260 ]);
6361
6462 return [
@@ -76,9 +74,12 @@ public function getMatchedRows(
7674 private function executeMatchedRowQuery (string $ matchedRowQuery ): int
7775 {
7876 $ this ->dbi ->selectDb ($ GLOBALS ['db ' ]);
77+ $ result = $ this ->dbi ->tryQuery ($ matchedRowQuery );
78+ if ($ result === false ) {
79+ return 0 ;
80+ }
7981
80- // Execute the query.
81- return (int ) $ this ->dbi ->fetchValue ($ matchedRowQuery );
82+ return (int ) $ result ->numRows ();
8283 }
8384
8485 /**
@@ -99,8 +100,7 @@ private function getSimulatedDeleteQuery(Parser $parser, DeleteStatement $statem
99100 : ' ORDER BY ' . Query ::getClause ($ statement , $ parser ->list , 'ORDER BY ' );
100101 $ limit = $ statement ->limit === null ? '' : ' LIMIT ' . Query ::getClause ($ statement , $ parser ->list , 'LIMIT ' );
101102
102- return 'SELECT COUNT(*) FROM ( ' .
103- 'SELECT 1 FROM ' . $ tableReferences [0 ] . $ where . $ order . $ limit . ') AS `pma_tmp` ' ;
103+ return 'SELECT * FROM ' . $ tableReferences [0 ] . $ where . $ order . $ limit ;
104104 }
105105
106106 /**
@@ -114,21 +114,18 @@ private function getSimulatedUpdateQuery(Parser $parser, UpdateStatement $statem
114114 Assert ::count ($ tableReferences , 1 , 'No joins allowed in simulation query ' );
115115 Assert ::isNonEmptyList ($ statement ->set , 'SET statements missing ' );
116116 Assert ::notNull ($ parser ->list , 'Parser list not set ' );
117- $ newValues = [];
118- $ oldValues = [];
117+
118+ $ values = [];
119119 $ newColumns = [];
120120 $ oldColumns = [];
121- $ i = 0 ;
122- $ handledColumns = [];
123121 foreach (array_reverse ($ statement ->set ) as $ set ) {
124- if (array_key_exists ($ set ->column , $ handledColumns )) {
122+ $ column = Util ::unQuote ($ set ->column );
123+ if (array_key_exists ($ column , $ values )) {
125124 continue ;
126125 }
127126
128- $ handledColumns [$ set ->column ] = true ;
129- $ oldValues [] = $ set ->column . ' AS ' . ($ oldColumns [] = Util ::backquote ('o ' . $ i ));
130- $ newValues [] = $ set ->value . ' AS ' . ($ newColumns [] = Util ::backquote ('n ' . $ i ));
131- ++$ i ;
127+ $ oldColumns [] = Util ::backquote ($ column );
128+ $ values [$ column ] = $ set ->value . ' AS ' . ($ newColumns [] = Util ::backquote ($ column . ' `new` ' ));
132129 }
133130
134131 $ condition = Query ::getClause ($ statement , $ parser ->list , 'WHERE ' );
@@ -138,11 +135,10 @@ private function getSimulatedUpdateQuery(Parser $parser, UpdateStatement $statem
138135 : ' ORDER BY ' . Query ::getClause ($ statement , $ parser ->list , 'ORDER BY ' );
139136 $ limit = $ statement ->limit === null ? '' : ' LIMIT ' . Query ::getClause ($ statement , $ parser ->list , 'LIMIT ' );
140137
141- return 'SELECT COUNT(*) ' .
142- ' FROM (SELECT ' . implode (', ' , $ newValues ) . ') AS `pma_new` ' .
143- ' JOIN ( ' .
144- 'SELECT ' . implode (', ' , $ oldValues ) . ' FROM ' . $ tableReferences [0 ] . $ where . $ order . $ limit .
145- ') AS `pma_old` ' .
146- ' WHERE NOT ( ' . implode (', ' , $ newColumns ) . ') <=> ( ' . implode (', ' , $ oldColumns ) . ') ' ;
138+ return 'SELECT * ' .
139+ ' FROM ( ' .
140+ 'SELECT *, ' . implode (', ' , $ values ) . ' FROM ' . $ tableReferences [0 ] . $ where . $ order . $ limit .
141+ ') AS `pma_tmp` ' .
142+ ' WHERE NOT ( ' . implode (', ' , $ oldColumns ) . ') <=> ( ' . implode (', ' , $ newColumns ) . ') ' ;
147143 }
148144}
0 commit comments