43 public static function buildQuery(
string $sql, $flags,
string $tablePrefix =
'' ) {
44 if ( !$flags && !self::isWriteQuery( $sql ) ) {
45 $flags = SQLPlatform::QUERY_CHANGE_NONE;
46 } elseif ( !$flags ) {
47 $flags = SQLPlatform::QUERY_CHANGE_ROWS;
49 $queryVerb = self::getQueryVerb( $sql );
50 $queryTables = self::getQueryTables( $sql, $tablePrefix );
51 return new Query( $sql, $flags, $queryVerb, $queryTables );
54 private static function isWriteQuery( $rawSql ) {
58 if ( preg_match(
'/^\s*\(?SELECT\b/i', $rawSql ) ) {
59 return (
bool)preg_match(
'/\bFOR\s+UPDATE\)?\s*$/i', $rawSql );
75 '/^\s*(BEGIN|ROLLBACK|COMMIT|SAVEPOINT|RELEASE|SET|SHOW|EXPLAIN|USE)\b/i',
84 private static function getQueryVerb( $sql ) {
87 '/^\s*(rollback\s+to\s+savepoint|[a-z]+)/i',
90 ) ? strtoupper( $m[1] ) :
'';
93 private static function getQueryTables( $sql, $tablePrefix ) {
97 static $regexes =
null;
98 if ( $regexes ===
null ) {
100 $qts =
'((?:\w+|`\w+`|\'\w+\'|"\w+")(?:\s*,\s*(?:\w+|`\w+`|\'\w+\'|"\w+"))*)';
104 "/^(INSERT|REPLACE)\s+(?:\w+\s+)*?INTO\s+$qts/i",
105 "/^(UPDATE)(?:\s+OR\s+\w+|\s+IGNORE|\s+ONLY)?\s+$qts/i",
106 "/^(DELETE)\s+(?:\w+\s+)*?FROM(?:\s+ONLY)?\s+$qts/i",
108 "/^(CREATE)\s+TEMPORARY\s+TABLE(?:\s+IF\s+NOT\s+EXISTS)?\s+$qts/i",
109 "/^(DROP)\s+(?:TEMPORARY\s+)?TABLE(?:\s+IF\s+EXISTS)?\s+$qts/i",
110 "/^(TRUNCATE)\s+(?:TEMPORARY\s+)?TABLE\s+$qts/i",
111 "/^(ALTER)\s+TABLE\s+$qts/i"
116 foreach ( $regexes as $regex ) {
117 if ( preg_match( $regex, $sql, $m, PREG_UNMATCHED_AS_NULL ) ) {
118 $allTables = preg_split(
'/\s*,\s*/', $m[2] );
119 foreach ( $allTables as $quotedTable ) {
120 $tableName = trim( $quotedTable,
"\"'`" );
121 $tableName = preg_replace(
'/^' . $tablePrefix .
'/',
'', $tableName );
122 $queryTables[] = $tableName;
140 # This does the same as the regexp below would do, but in such a way
141 # as to avoid crashing php on some large strings.
142 # $sql = preg_replace( "/'([^\\\\']|\\\\.)*'|\"([^\\\\\"]|\\\\.)*\"/", "'X'", $sql );
144 $sql = str_replace(
"\\\\",
'', $sql );
145 $sql = str_replace(
"\\'",
'', $sql );
146 $sql = str_replace(
"\\\"",
'', $sql );
147 $sql = preg_replace(
"/'.*'/s",
"'X'", $sql );
148 $sql = preg_replace(
'/".*"/s',
"'X'", $sql );
150 # All newlines, tabs, etc replaced by single space
151 $sql = preg_replace(
'/\s+/',
' ', $sql );
154 # except the ones surrounded by characters, e.g. l10n
155 $sql = preg_replace(
'/-?\d+(,-?\d+)+/',
'N,...,N', $sql );
156 $sql = preg_replace(
'/(?<![a-zA-Z])-?\d+(?![a-zA-Z])/',
'N', $sql );