PEAR is archived and read-only

This mirror preserves historical PEAR package releases and metadata so existing references remain available.

Home » Database » SQL_Parser » Bug #4085

Lexer should recognize identifier delimiters

Details

Submitted2005-04-06 18:24 UTC
Fromepte at ruffdogs dot com
Assignedcybot
StatusClosed
PackageSQL_Parser
PHP Version4.3.8
Roadmaps0.5.1

Comments

[2005-04-06 18:24 UTC] epte at ruffdogs dot com

Description:
------------
For example, in MySQL,`tablename` should be seen as an identifier.

Reproduce code:
---------------
MySQL sql:

INSERT INTO `mpn_4nstats_datecnt` VALUES ('18042004',571);

Actual result:
--------------
Parse error: Expected table name on line 2
INSERT INTO `mpn_4nstats_datecnt` VALUES ('18042004',571);
^ found: "`"

[2005-04-06 19:41 UTC] epte at ruffdogs dot com

Here's the patch:

Index: Dialect_MySQL.php
===================================================================
--- Dialect_MySQL.php (revision 2689)
+++ Dialect_MySQL.php (working copy)
@@ -121,7 +121,8 @@
'ascending'=>'asc', 'asc'=>'asc', 'descending'=>'desc', 'desc'=>'desc',
'date'=>'date', 'time'=>'time'),

-'lexeropts'=>array('allowIdentFirstDigit'=>true),
+'lexeropts'=>array('allowIdentFirstDigit'=>true, 'identBeginDelimeter'=>'`',
+ 'identEndDelimeter'=>'`'),

'parseropts'=>array()
);
Index: Lexer.php
===================================================================
--- Lexer.php (revision 2677)
+++ Lexer.php (working copy)
@@ -33,6 +33,8 @@
define('SQL_PARSER_STATE_START', 0);
define('SQL_PARSER_STATE_KEYWORD_OR_IDENT_INCOMPLETE', 1);
define('SQL_PARSER_STATE_KEYWORD_OR_IDENT_COMPLETE', 2);
+define('SQL_PARSER_STATE_IDENT_INCOMPLETE', 3);
+define('SQL_PARSER_STATE_IDENT_COMPLETE', 4);
define('SQL_PARSER_STATE_REAL_OR_INT_INCOMPLETE', 5);
define('SQL_PARSER_STATE_INT_COMPLETE', 6);
define('SQL_PARSER_STATE_REAL_INCOMPLETE', 7);
@@ -95,6 +97,12 @@
$this->stringLen = strlen($string);
$this->lookahead = $lookahead;
$this->allowIdentFirstDigit = $lexeropts['allowIdentFirstDigit'];
+ if (isset($lexeropts['identBeginDelimeter']) &&
+ isset($lexeropts['identEndDelimeter']))
+ {
+ $this->identBeginDelimeter = $lexeropts['identBeginDelimeter'];
+ $this->identEndDelimeter = $lexeropts['identEndDelimeter'];
+ }
}

function get() {
@@ -181,7 +189,7 @@
array('token' => $token,
'tokText' => $this->tokText,
'skipText' => $this->skipText);
- print_r($this->tokenStack[$this->stackPtr]);
+ //print_r($this->tokenStack[$this->stackPtr]);
$this->stackPtr++;
return $token;
}
@@ -270,6 +278,13 @@
break;
}

+ if (isset($this->identBeginDelimeter) &&
+ $c == $this->identBeginDelimeter)
+ {
+ $state = SQL_PARSER_STATE_IDENT_INCOMPLETE;
+ break;
+ }
+
if ($c == '_') { // system variable
$state = SQL_PARSER_STATE_SYSVAR_INCOMPLETE;
break;
@@ -350,6 +365,26 @@
break;
// }}}

+ // {{{ State 3 : Ident incomplete
+ case SQL_PARSER_STATE_IDENT_INCOMPLETE:
+ $c = $this->get();
+ if ($c == $this->identEndDelimeter) {
+ $state = SQL_PARSER_STATE_IDENT_COMPLETE;
+ $this->tokText = substr($this->string,
+ ($this->tokStart+1), ($this->tokLen-2));
+ break;
+ }
+ $state = SQL_PARSER_STATE_IDENT_INCOMPLETE;
+ break;
+ // }}}
+
+ // {{{ State 4: Ident complete
+ case SQL_PARSER_STATE_IDENT_COMPLETE:
+ $this->setToken($this->tokText);
+ return 'ident';
+ break;
+ // }}}
+
// {{{ State 5: Incomplete real or int number
case SQL_PARSER_STATE_REAL_OR_INT_INCOMPLETE:
$c = $this->get();