Skip to content

Commit 883c08a

Browse files
committed
Fix handling of identifiers preceded by a “.”
1 parent f1c56cc commit 883c08a

File tree

3 files changed

+9
-40
lines changed

3 files changed

+9
-40
lines changed

custom-parser/parser/MySQLLexer.php

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2035,7 +2035,8 @@ private function nextToken()
20352035
if ($this->isDigit($la2)) {
20362036
$this->NUMBER();
20372037
} else {
2038-
$this->DOT_IDENTIFIER();
2038+
$this->consume();
2039+
$this->type = self::DOT_SYMBOL;
20392040
}
20402041
} elseif ($la === '=') {
20412042
$this->consume();
@@ -2222,11 +2223,16 @@ private function nextToken()
22222223
} elseif (($la === 'x' || $la === 'X' || $la === 'b' || $la === 'B') && $la2 === "'") {
22232224
$this->NUMBER();
22242225
} elseif (preg_match('/\G' . self::PATTERN_UNQUOTED_IDENTIFIER . '/u', $this->input, $matches, 0, $this->position)) {
2226+
$p = $this->position - 1;
22252227
$this->text = $matches[0];
22262228
$this->position += strlen($this->text);
22272229
$this->c = $this->input[$this->position] ?? null;
22282230
$this->n = $this->input[$this->position + 1] ?? null;
2229-
if ($la === '_' && isset(self::UNDERSCORE_CHARSETS[strtolower($this->text)])) {
2231+
2232+
// When preceded by a dot, it is always an identifier.
2233+
if ($p >= 0 && $this->input[$p] === '.') {
2234+
$this->type = self::IDENTIFIER;
2235+
} elseif ($la === '_' && isset(self::UNDERSCORE_CHARSETS[strtolower($this->text)])) {
22302236
$this->type = self::UNDERSCORE_CHARSET;
22312237
} else {
22322238
$this->IDENTIFIER_OR_KEYWORD();
@@ -2277,17 +2283,6 @@ protected function checkVersion(string $text): bool
22772283
return false;
22782284
}
22792285

2280-
/**
2281-
* This is a place holder to support features of MySQLBaseLexer which are not yet implemented
2282-
* in the PHP target.
2283-
*
2284-
* @return void
2285-
*/
2286-
protected function emitDot(): void
2287-
{
2288-
return;
2289-
}
2290-
22912286
protected function IDENTIFIER_OR_KEYWORD()
22922287
{
22932288
$text = strtoupper($this->getText());
@@ -2409,13 +2404,6 @@ protected function sqlCodeInComment(): void
24092404
$this->VERSION_COMMENT_END();
24102405
}
24112406

2412-
protected function DOT_IDENTIFIER()
2413-
{
2414-
$this->consume(); // Consume the '.'.
2415-
$this->type = self::IDENTIFIER;
2416-
$this->type = self::DOT_SYMBOL;//@TODO: DOT_IDENTIFIER);
2417-
}
2418-
24192407
protected function NUMBER()
24202408
{
24212409
if (($this->c === '0' && $this->n === 'x') || (strtolower($this->c) === 'x' && $this->n === "'")) {
@@ -2447,10 +2435,6 @@ protected function NUMBER()
24472435
} else {
24482436
$this->type = self::DECIMAL_NUMBER;
24492437
}
2450-
} else {
2451-
// If there is no digit after the '.', it's a DOT_IDENTIFIER.
2452-
$this->emitDot();
2453-
$this->type = self::IDENTIFIER;
24542438
}
24552439
} elseif (($this->c === 'e' || $this->c === 'E') && ($this->n === '+' || $this->n === '-' || $this->isDigit($this->n))) {
24562440
$this->consume();

tests/parser/data/failures.csv

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1645,8 +1645,6 @@ WHERE (dt.f2 <> ANY (SELECT t1.f1 FROM t1 WHERE t1.f2 = dt.f2))"
16451645
"create table t1 (k int, index (k), index using hash (k)) engine=heap"
16461646
"create table t1 (k int, index using btree (k), index (k)) engine=innodb"
16471647
"create table t1 (k int, index using btree (k), index using hash (k)) engine=innodb"
1648-
"SELECT @@global.default.key_buffer_size"
1649-
"SELECT @@global.default.`key_buffer_size`"
16501648
"create table t3 (like t1)"
16511649
"create table tm (k int, index using btree (k)) charset utf8mb4 engine=myisam"
16521650
"alter table tm add column l int, add index using btree (l)"
@@ -3669,12 +3667,6 @@ end"
36693667
begin
36703668
alter database character set koi8r;
36713669
end"
3672-
"drop function if exists test.database"
3673-
"drop function if exists test.current_user"
3674-
"select test.database(), test.database ()"
3675-
"select test.current_user(), test.current_user ()"
3676-
"drop function test.database"
3677-
"drop function test.current_user"
36783670
"CREATE PROCEDURE p1(IN loops BIGINT(19) UNSIGNED)
36793671
BEGIN
36803672
WHILE loops > 0 DO
@@ -3853,7 +3845,6 @@ end"
38533845
"SELECT IF(e='a', e, NULL) FROM t GROUP BY ROLLUP(e) EXCEPT SELECT 1"
38543846
"SELECT COALESCE(e, NULL) FROM t GROUP BY ROLLUP(e) EXCEPT SELECT 1"
38553847
"SELECT 10,10.0,10.,.1e+2,100.0e-1"
3856-
"SELECT 1e1,1.e1,1.0e1,1e+1,1.e+1,1.0e+1,1e-1,1.e-1,1.0e-1"
38573848
"create table t1 (c nchar varchar(10))"
38583849
"create table t1 (c national character varying(10))"
38593850
"create table t1 (c nchar varying(10))"
@@ -4443,12 +4434,6 @@ ROW_NUMBER() OVER (PARTITION BY j)"
44434434
"EXPLAIN FORMAT=tree SELECT a, SUM(c) OVER (ORDER BY b), AVG(c) OVER (ORDER BY a), SUM(c) OVER (PARTITION BY a) AS x FROM t1 ORDER BY b, x"
44444435
"SELECT k, AVG(DISTINCT j), MIN(k) OVER (ROWS UNBOUNDED PRECEDING) min,
44454436
MAX(k) OVER (ROWS UNBOUNDED PRECEDING) max FROM t GROUP BY (k)"
4446-
"SELECT t.*, MIN(t.rank) OVER (ROWS UNBOUNDED PRECEDING) min,
4447-
MAX(t.rank) OVER (ROWS UNBOUNDED PRECEDING) max FROM
4448-
(SELECT sex, id, date, ROW_NUMBER() OVER w AS row_no, RANK() OVER w AS `rank` FROM t1,t2
4449-
WHERE t1.id=t2.user_id
4450-
WINDOW w AS (PARTITION BY date ORDER BY id)
4451-
) AS t"
44524437
"SELECT AVG(id) OVER w, MIN(id) OVER w min, MAX(id) OVER w max FROM t1
44534438
WINDOW w AS (PARTITION BY sex)"
44544439
"SELECT id, AVG(id) OVER (ROWS UNBOUNDED PRECEDING) avg,

tests/parser/data/stats.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Total: 66241 | Failures: 1876 / 2% | Exceptions: 0 / 0%
1+
Total: 66241 | Failures: 1866 / 2% | Exceptions: 0 / 0%

0 commit comments

Comments
 (0)