Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
doctrine-dbal
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Tomáš Trávníček
doctrine-dbal
Commits
a45560db
Commit
a45560db
authored
May 18, 2010
by
Roman S. Borschel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[DDC-505] Fixed and small lexer simplifcations that were marked as todo.
parent
3cbee1fa
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
99 additions
and
119 deletions
+99
-119
Lexer.php
lib/Doctrine/ORM/Query/Lexer.php
+78
-116
Parser.php
lib/Doctrine/ORM/Query/Parser.php
+7
-2
LanguageRecognitionTest.php
tests/Doctrine/Tests/ORM/Query/LanguageRecognitionTest.php
+14
-1
No files found.
lib/Doctrine/ORM/Query/Lexer.php
View file @
a45560db
<?php
<?php
/*
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
...
@@ -27,20 +25,33 @@ namespace Doctrine\ORM\Query;
...
@@ -27,20 +25,33 @@ namespace Doctrine\ORM\Query;
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
* @author Roman Borschel <roman@code-factory.org>
* @author Roman Borschel <roman@code-factory.org>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @since 2.0
* @version $Revision$
*/
*/
class
Lexer
extends
\Doctrine\Common\Lexer
class
Lexer
extends
\Doctrine\Common\Lexer
{
{
// All tokens that are not valid identifiers must be < 100
const
T_NONE
=
1
;
const
T_NONE
=
1
;
const
T_IDENTIFIER
=
2
;
const
T_INTEGER
=
2
;
const
T_INTEGER
=
3
;
const
T_STRING
=
3
;
const
T_STRING
=
4
;
const
T_INPUT_PARAMETER
=
4
;
const
T_INPUT_PARAMETER
=
5
;
const
T_FLOAT
=
5
;
const
T_FLOAT
=
6
;
const
T_CLOSE_PARENTHESIS
=
6
;
const
T_OPEN_PARENTHESIS
=
7
;
const
T_COMMA
=
8
;
const
T_DIVIDE
=
9
;
const
T_DOT
=
10
;
const
T_EQUALS
=
11
;
const
T_GREATER_THAN
=
12
;
const
T_LOWER_THAN
=
13
;
const
T_MINUS
=
14
;
const
T_MULTIPLY
=
15
;
const
T_NEGATE
=
16
;
const
T_PLUS
=
17
;
const
T_OPEN_CURLY_BRACE
=
18
;
const
T_CLOSE_CURLY_BRACE
=
19
;
// All tokens that are also identifiers should be >= 100
const
T_IDENTIFIER
=
100
;
const
T_ALL
=
101
;
const
T_ALL
=
101
;
const
T_AND
=
102
;
const
T_AND
=
102
;
const
T_ANY
=
103
;
const
T_ANY
=
103
;
...
@@ -50,62 +61,46 @@ class Lexer extends \Doctrine\Common\Lexer
...
@@ -50,62 +61,46 @@ class Lexer extends \Doctrine\Common\Lexer
const
T_BETWEEN
=
107
;
const
T_BETWEEN
=
107
;
const
T_BOTH
=
108
;
const
T_BOTH
=
108
;
const
T_BY
=
109
;
const
T_BY
=
109
;
const
T_CLOSE_PARENTHESIS
=
110
;
const
T_COUNT
=
110
;
const
T_COMMA
=
111
;
const
T_DELETE
=
111
;
const
T_COUNT
=
112
;
const
T_DESC
=
112
;
const
T_DELETE
=
113
;
const
T_DISTINCT
=
113
;
const
T_DESC
=
114
;
const
T_EMPTY
=
114
;
const
T_DISTINCT
=
115
;
const
T_ESCAPE
=
115
;
const
T_DIVIDE
=
116
;
const
T_EXISTS
=
116
;
const
T_DOT
=
117
;
const
T_FALSE
=
117
;
const
T_EMPTY
=
118
;
const
T_FROM
=
118
;
const
T_EQUALS
=
119
;
const
T_GROUP
=
119
;
const
T_ESCAPE
=
120
;
const
T_HAVING
=
120
;
const
T_EXISTS
=
121
;
const
T_IN
=
121
;
const
T_FALSE
=
122
;
const
T_INDEX
=
122
;
const
T_FROM
=
123
;
const
T_INNER
=
123
;
const
T_GREATER_THAN
=
124
;
const
T_IS
=
124
;
const
T_GROUP
=
125
;
const
T_JOIN
=
125
;
const
T_HAVING
=
126
;
const
T_LEADING
=
126
;
const
T_IN
=
127
;
const
T_LEFT
=
127
;
const
T_INDEX
=
128
;
const
T_LIKE
=
128
;
const
T_INNER
=
129
;
const
T_MAX
=
129
;
const
T_IS
=
130
;
const
T_MEMBER
=
130
;
const
T_JOIN
=
131
;
const
T_MIN
=
131
;
const
T_LEADING
=
132
;
const
T_NOT
=
132
;
const
T_LEFT
=
133
;
const
T_NULL
=
133
;
const
T_LIKE
=
134
;
const
T_OF
=
134
;
const
T_LIMIT
=
135
;
const
T_OR
=
135
;
const
T_LOWER_THAN
=
136
;
const
T_ORDER
=
136
;
const
T_MAX
=
137
;
const
T_OUTER
=
137
;
const
T_MEMBER
=
138
;
const
T_SELECT
=
138
;
const
T_MIN
=
139
;
const
T_SET
=
139
;
const
T_MINUS
=
140
;
const
T_SIZE
=
140
;
const
T_MOD
=
141
;
const
T_SOME
=
141
;
const
T_MULTIPLY
=
142
;
const
T_SUM
=
142
;
const
T_NEGATE
=
143
;
const
T_TRAILING
=
143
;
const
T_NOT
=
144
;
const
T_TRUE
=
144
;
const
T_NULL
=
145
;
const
T_UPDATE
=
145
;
const
T_OF
=
146
;
const
T_WHERE
=
146
;
const
T_OFFSET
=
147
;
const
T_WITH
=
147
;
const
T_OPEN_PARENTHESIS
=
149
;
const
T_PARTIAL
=
148
;
const
T_OR
=
150
;
const
T_MOD
=
149
;
const
T_ORDER
=
151
;
const
T_OUTER
=
152
;
const
T_PLUS
=
153
;
const
T_SELECT
=
154
;
const
T_SET
=
155
;
const
T_SIZE
=
156
;
const
T_SOME
=
157
;
const
T_SUM
=
158
;
const
T_TRAILING
=
159
;
const
T_TRUE
=
160
;
const
T_UPDATE
=
161
;
const
T_WHERE
=
162
;
const
T_WITH
=
163
;
const
T_PARTIAL
=
164
;
const
T_OPEN_CURLY_BRACE
=
165
;
const
T_CLOSE_CURLY_BRACE
=
166
;
/**
/**
* Creates a new query scanner object.
* Creates a new query scanner object.
...
@@ -144,22 +139,26 @@ class Lexer extends \Doctrine\Common\Lexer
...
@@ -144,22 +139,26 @@ class Lexer extends \Doctrine\Common\Lexer
protected
function
_getType
(
&
$value
)
protected
function
_getType
(
&
$value
)
{
{
$type
=
self
::
T_NONE
;
$type
=
self
::
T_NONE
;
$newVal
=
$this
->
_getNumeric
(
$value
);
// Recognizing numeric values
// Recognizing numeric values
if
(
$newVal
!==
false
){
if
(
is_numeric
(
$value
))
{
$value
=
$newVal
;
return
(
strpos
(
$value
,
'.'
)
!==
false
||
stripos
(
$value
,
'e'
)
!==
false
)
return
(
strpos
(
$value
,
'.'
)
!==
false
||
stripos
(
$value
,
'e'
)
!==
false
)
?
self
::
T_FLOAT
:
self
::
T_INTEGER
;
?
self
::
T_FLOAT
:
self
::
T_INTEGER
;
}
}
// Differentiate between quoted names, identifiers, input parameters and symbols
if
(
$value
[
0
]
===
"'"
)
{
if
(
$value
[
0
]
===
"'"
)
{
$value
=
str_replace
(
"''"
,
"'"
,
substr
(
$value
,
1
,
strlen
(
$value
)
-
2
));
$value
=
str_replace
(
"''"
,
"'"
,
substr
(
$value
,
1
,
strlen
(
$value
)
-
2
));
return
self
::
T_STRING
;
return
self
::
T_STRING
;
}
else
if
(
ctype_alpha
(
$value
[
0
])
||
$value
[
0
]
===
'_'
)
{
}
else
if
(
ctype_alpha
(
$value
[
0
])
||
$value
[
0
]
===
'_'
)
{
return
$this
->
_checkLiteral
(
$value
);
$name
=
'Doctrine\ORM\Query\Lexer::T_'
.
strtoupper
(
$value
);
if
(
defined
(
$name
))
{
$type
=
constant
(
$name
);
if
(
$type
>
100
)
{
return
$type
;
}
}
return
self
::
T_IDENTIFIER
;
}
else
if
(
$value
[
0
]
===
'?'
||
$value
[
0
]
===
':'
)
{
}
else
if
(
$value
[
0
]
===
'?'
||
$value
[
0
]
===
':'
)
{
return
self
::
T_INPUT_PARAMETER
;
return
self
::
T_INPUT_PARAMETER
;
}
else
{
}
else
{
...
@@ -186,41 +185,4 @@ class Lexer extends \Doctrine\Common\Lexer
...
@@ -186,41 +185,4 @@ class Lexer extends \Doctrine\Common\Lexer
return
$type
;
return
$type
;
}
}
/**
* @todo Inline this method.
*/
private
function
_getNumeric
(
$value
)
{
if
(
!
is_scalar
(
$value
))
{
return
false
;
}
// Checking for valid numeric numbers: 1.234, -1.234e-2
if
(
is_numeric
(
$value
))
{
return
$value
;
}
return
false
;
}
/**
* Checks if an identifier is a keyword and returns its correct type.
*
* @param string $identifier identifier name
* @return int token type
* @todo Inline this method.
*/
private
function
_checkLiteral
(
$identifier
)
{
$name
=
'Doctrine\ORM\Query\Lexer::T_'
.
strtoupper
(
$identifier
);
if
(
defined
(
$name
))
{
$type
=
constant
(
$name
);
if
(
$type
>
100
)
{
return
$type
;
}
}
return
self
::
T_IDENTIFIER
;
}
}
}
\ No newline at end of file
lib/Doctrine/ORM/Query/Parser.php
View file @
a45560db
...
@@ -231,7 +231,11 @@ class Parser
...
@@ -231,7 +231,11 @@ class Parser
*/
*/
public
function
match
(
$token
)
public
function
match
(
$token
)
{
{
if
(
!
(
$this
->
_lexer
->
lookahead
[
'type'
]
===
$token
))
{
// short-circuit on first condition, usually types match
if
(
$this
->
_lexer
->
lookahead
[
'type'
]
!==
$token
&&
$token
!==
Lexer
::
T_IDENTIFIER
&&
$this
->
_lexer
->
lookahead
[
'type'
]
<=
Lexer
::
T_IDENTIFIER
)
{
$this
->
syntaxError
(
$this
->
_lexer
->
getLiteral
(
$token
));
$this
->
syntaxError
(
$this
->
_lexer
->
getLiteral
(
$token
));
}
}
...
@@ -890,7 +894,8 @@ class Parser
...
@@ -890,7 +894,8 @@ class Parser
$identVariable
=
$this
->
IdentificationVariable
();
$identVariable
=
$this
->
IdentificationVariable
();
$this
->
match
(
Lexer
::
T_DOT
);
$this
->
match
(
Lexer
::
T_DOT
);
$this
->
match
(
$this
->
_lexer
->
lookahead
[
'type'
]);
$this
->
match
(
Lexer
::
T_IDENTIFIER
);
//$this->match($this->_lexer->lookahead['type']);
$field
=
$this
->
_lexer
->
token
[
'value'
];
$field
=
$this
->
_lexer
->
token
[
'value'
];
// Validate association field
// Validate association field
...
...
tests/Doctrine/Tests/ORM/Query/LanguageRecognitionTest.php
View file @
a45560db
...
@@ -414,11 +414,22 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
...
@@ -414,11 +414,22 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
$this
->
assertValidDql
(
'SELECT u, u.id + ?1 AS someNumber FROM Doctrine\Tests\Models\CMS\CmsUser u'
);
$this
->
assertValidDql
(
'SELECT u, u.id + ?1 AS someNumber FROM Doctrine\Tests\Models\CMS\CmsUser u'
);
}
}
/**
* @group DDC-505
*/
public
function
testDQLKeywordInJoinIsAllowed
()
public
function
testDQLKeywordInJoinIsAllowed
()
{
{
$this
->
assertValidDql
(
'SELECT u FROM '
.
__NAMESPACE__
.
'\DQLKeywordsModelUser u JOIN u.group g'
);
$this
->
assertValidDql
(
'SELECT u FROM '
.
__NAMESPACE__
.
'\DQLKeywordsModelUser u JOIN u.group g'
);
}
}
/**
* @group DDC-505
*/
public
function
testDQLKeywordInConditionIsAllowed
()
{
$this
->
assertValidDql
(
'SELECT g FROM '
.
__NAMESPACE__
.
'\DQLKeywordsModelGroup g WHERE g.from=0'
);
}
/* The exception is currently thrown in the SQLWalker, not earlier.
/* The exception is currently thrown in the SQLWalker, not earlier.
public function testInverseSideSingleValuedAssociationPathNotAllowed()
public function testInverseSideSingleValuedAssociationPathNotAllowed()
{
{
...
@@ -441,4 +452,6 @@ class DQLKeywordsModelGroup
...
@@ -441,4 +452,6 @@ class DQLKeywordsModelGroup
{
{
/** @Id @Column(type="integer") @GeneratedValue */
/** @Id @Column(type="integer") @GeneratedValue */
private
$id
;
private
$id
;
/** @Column */
private
$from
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment