Package home | Report new bug | New search | Development Roadmap Status: Open | Feedback | All | Closed Since Version 0.7.0

Bug #4035 Update statements should recognize FROM clause
Submitted: 2005-04-03 04:42 UTC
From: epte at ruffdogs dot com Assigned: cybot
Status: Closed Package: SQL_Parser
PHP Version: Irrelevant OS: Irrelevant
Roadmaps: 0.5.1    
Subscription  
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes. If this is not your bug, you can add a comment by following this link. If this is your bug, but you forgot your password, you can retrieve your password here.
Password:
Status:
2008-07-23 15:24 UTC
Package:
Bug Type:
Summary:
From: epte at ruffdogs dot com
New email:
PHP Version: Package Version: OS:

 

 [2005-04-03 04:42 UTC] epte at ruffdogs dot com
Description: ------------ Some valid UPDATE statements have from clauses to set the table (or join) that the source data is coming from (that you're using to populate whatever it is that you're updating). (Should it error if the FROM clause isn't used? Assuming no...) Reproduce code: --------------- UPDATE tblTicklerPatientData SET tblTicklerPatientData.final_diagnosis = ptc.path_diagnosis_codes FROM tblTicklerPatientData INNER JOIN `PatientTest(Case)` as ptc ON tblTicklerPatientData.PatientTest_key = ptc.PatientTest_key WHERE ptc.path_diagnosis_codes Is Not Null and tblTicklerPatientData.final_diagnosis is null'; $_SQLParser = new SQL_Parser(NULL, 'MySQL'); $parseRes = $_SQLParser->parse($sql); Actual result: -------------- Parse error: Expected "where" or "," on line 4 FROM ^ found: "FROM"

Comments

 [2005-04-03 05:00 UTC] epte at ruffdogs dot com
The following patch seems to fix this portion, but it is hard to tell until I get the other issues worked out of this query. More to come. Index: Parser.php =================================================================== RCS file: /repository/pear/SQL_Parser/Parser.php,v retrieving revision 1.27 diff -u -r1.27 Parser.php --- Parser.php 3 Jul 2004 04:49:44 -0000 1.27 +++ Parser.php 3 Apr 2005 04:59:20 -0000 @@ -143,6 +143,7 @@ // {{{ isVal() function isVal() { return (($this->token == 'real_val') || + ($this->token == 'function') || ($this->token == 'int_val') || ($this->token == 'text_val') || ($this->token == 'null')); @@ -766,12 +767,25 @@ return $this->raiseError('Expected ='); } $this->getTok(); - if (!$this->isVal($this->token)) { - return $this->raiseError('Expected a value'); + if (!$this->isVal($this->token) && $this->token != 'ident') { + return $this->raiseError('Expected a value or column name'); } $tree['values'][] = array('value'=>$this->lexer->tokText, 'type'=>$this->token); $this->getTok(); + if ($this->token == ',') { + continue; + } + + if ($this->token == 'from') { + $clause = $this->parseFromClause(); + if (PEAR::isError($clause)) { + return $clause; + } + $tree = array_merge($tree, $clause); + $this->getTok(); + } + if ($this->token == 'where') { $clause = $this->parseSearchClause(); if (PEAR::isError($clause)) { @@ -780,7 +794,7 @@ $tree['where_clause'] = $clause; break; } elseif ($this->token != ',') { - return $this->raiseError('Expected "where" or ","'); + return $this->raiseError('Expected "where"'); } } return $tree; @@ -936,10 +950,97 @@ } else { return $this->raiseError('Expected columns or a set function'); } - if ($this->token != 'from') { + if ($this->token == 'from') { + $clause = $this->parseFromClause(); + if (PEAR::isError($clause)) { + return $clause; + } + $tree = array_merge($tree, $clause); + $this->getTok(); + } else { return $this->raiseError('Expected "from"'); } + while (!is_null($this->token) && (!$subSelect || $this->token != ')') + && $this->token != ')') { + switch ($this->token) { + case 'where': + $clause = $this->parseSearchClause(); + if (PEAR::isError($clause)) { + return $clause; + } + $tree['where_clause'] = $clause; + break; + case 'order': + $this->getTok(); + if ($this->token != 'by') { + return $this->raiseError('Expected "by"'); + } + $this->getTok(); + while ($this->token == 'ident') { + $col = $this->lexer->tokText; + $this->getTok(); + if (isset($this->synonyms[$this->token])) { + $order = $this->synonyms[$this->token]; + if (($order != 'asc') && ($order != 'desc')) { + return $this->raiseError('Unexpected token'); + } + $this->getTok(); + } else { + $order = 'asc'; + } + if ($this->token == ',') { + $this->getTok(); + } + $tree['sort_order'][$col] = $order; + } + break; + case 'limit': + $this->getTok(); + if ($this->token != 'int_val') { + return $this->raiseError('Expected an integer value'); + } + $length = $this->lexer->tokText; + $start = 0; + $this->getTok(); + if ($this->token == ',') { + $this->getTok(); + if ($this->token != 'int_val') { + return $this->raiseError('Expected an integer value'); + } + $start = $length; + $length = $this->lexer->tokText; + $this->getTok(); + } + $tree['limit_clause'] = array('start'=>$start, + 'length'=>$length); + break; + case 'group': + $this->getTok(); + if ($this->token != 'by') { + return $this->raiseError('Expected "by"'); + } + $this->getTok(); + while ($this->token == 'ident') { + $col = $this->lexer->tokText; + $this->getTok(); + if ($this->token == ',') { + $this->getTok(); + } + $tree['group_by'][] = $col; + } + break; + default: + return $this->raiseError('Unexpected clause'); + } + } + return $tree; + } + // }}} + + // {{{ parseFromClause() + function parseFromClause() { $this->getTok(); + $tree = array(); while ($this->token == 'ident') { $tree['table_names'][] = $this->lexer->tokText; $this->getTok(); @@ -1032,83 +1133,9 @@ break; } } - while (!is_null($this->token) && (!$subSelect || $this->token != ')') - && $this->token != ')') { - switch ($this->token) { - case 'where': - $clause = $this->parseSearchClause(); - if (PEAR::isError($clause)) { - return $clause; - } - $tree['where_clause'] = $clause; - break; - case 'order': - $this->getTok(); - if ($this->token != 'by') { - return $this->raiseError('Expected "by"'); - } - $this->getTok(); - while ($this->token == 'ident') { - $col = $this->lexer->tokText; - $this->getTok(); - if (isset($this->synonyms[$this->token])) { - $order = $this->synonyms[$this->token]; - if (($order != 'asc') && ($order != 'desc')) { - return $this->raiseError('Unexpected token'); - } - $this->getTok(); - } else { - $order = 'asc'; - } - if ($this->token == ',') { - $this->getTok(); - } - $tree['sort_order'][$col] = $order; - } - break; - case 'limit': - $this->getTok(); - if ($this->token != 'int_val') { - return $this->raiseError('Expected an integer value'); - } - $length = $this->lexer->tokText; - $start = 0; - $this->getTok(); - if ($this->token == ',') { - $this->getTok(); - if ($this->token != 'int_val') { - return $this->raiseError('Expected an integer value'); - } - $start = $length; - $length = $this->lexer->tokText; - $this->getTok(); - } - $tree['limit_clause'] = array('start'=>$start, - 'length'=>$length); - break; - case 'group': - $this->getTok(); - if ($this->token != 'by') { - return $this->raiseError('Expected "by"'); - } - $this->getTok(); - while ($this->token == 'ident') { - $col = $this->lexer->tokText; - $this->getTok(); - if ($this->token == ',') { - $this->getTok(); - } - $tree['group_by'][] = $col; - } - break; - default: - return $this->raiseError('Unexpected clause'); - } - } return $tree; } - // }}} - + // {{{ parse($string) function parse($string = null) {
 [2008-04-01 12:41 UTC] User who submitted this comment has not confirmed identity
If you submitted this note, check your email.If you do not have a message, click here to re-send
MANUAL CONFIRMATION IS NOT POSSIBLE.  Write a message to pear-dev@lists.php.net
to request the confirmation link.  All bugs/comments/patches associated with this

email address will be deleted within 48 hours if the account request is not confirmed!
 [2008-07-23 15:24 UTC] User who submitted this comment has not confirmed identity
If you submitted this note, check your email.If you do not have a message, click here to re-send
MANUAL CONFIRMATION IS NOT POSSIBLE.  Write a message to pear-dev@lists.php.net
to request the confirmation link.  All bugs/comments/patches associated with this

email address will be deleted within 48 hours if the account request is not confirmed!