Skip to content

Commit a1fdf68

Browse files
authored
Merge pull request #99 from devenbansod/end_options_in_select
Add parsing End options like FOR UPDATE and LOCK IN SHARE MODE in Select
2 parents 5050a52 + cf44600 commit a1fdf68

17 files changed

+99
-19
lines changed

src/Contexts/ContextMySql50000.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,8 @@ class ContextMySql50000 extends Context
145145
'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7,
146146
'LESS THAN' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7,
147147
'UNION ALL' => 7,
148-
'CROSS JOIN' => 7, 'INNER JOIN' => 7, 'LINEAR KEY' => 7, 'NO RELEASE' => 7,
149-
'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
148+
'CROSS JOIN' => 7, 'FOR UPDATE' => 7, 'INNER JOIN' => 7, 'LINEAR KEY' => 7,
149+
'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
150150
'LINEAR HASH' => 7,
151151
'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'NATURAL JOIN' => 7,
152152
'PARTITION BY' => 7, 'SET PASSWORD' => 7, 'SQL SECURITY' => 7,
@@ -156,7 +156,7 @@ class ContextMySql50000 extends Context
156156
'INDEX DIRECTORY' => 7, 'LEFT OUTER JOIN' => 7, 'SUBPARTITION BY' => 7,
157157
'GENERATED ALWAYS' => 7, 'RIGHT OUTER JOIN' => 7,
158158
'NATURAL LEFT JOIN' => 7, 'START TRANSACTION' => 7,
159-
'NATURAL RIGHT JOIN' => 7, 'SELECT TRANSACTION' => 7,
159+
'LOCK IN SHARE MODE' => 7, 'NATURAL RIGHT JOIN' => 7, 'SELECT TRANSACTION' => 7,
160160
'DEFAULT CHARACTER SET' => 7,
161161
'NATURAL LEFT OUTER JOIN' => 7,
162162
'NATURAL RIGHT OUTER JOIN' => 7, 'WITH CONSISTENT SNAPSHOT' => 7,

src/Contexts/ContextMySql50100.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,8 @@ class ContextMySql50100 extends Context
159159
'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7,
160160
'LESS THAN' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7,
161161
'UNION ALL' => 7,
162-
'CROSS JOIN' => 7, 'INNER JOIN' => 7, 'LINEAR KEY' => 7, 'NO RELEASE' => 7,
163-
'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
162+
'CROSS JOIN' => 7, 'FOR UPDATE' => 7, 'INNER JOIN' => 7, 'LINEAR KEY' => 7,
163+
'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
164164
'LINEAR HASH' => 7,
165165
'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'NATURAL JOIN' => 7,
166166
'PARTITION BY' => 7, 'SET PASSWORD' => 7, 'SQL SECURITY' => 7,
@@ -170,7 +170,7 @@ class ContextMySql50100 extends Context
170170
'INDEX DIRECTORY' => 7, 'LEFT OUTER JOIN' => 7, 'SUBPARTITION BY' => 7,
171171
'GENERATED ALWAYS' => 7, 'RIGHT OUTER JOIN' => 7,
172172
'NATURAL LEFT JOIN' => 7, 'START TRANSACTION' => 7,
173-
'NATURAL RIGHT JOIN' => 7, 'SELECT TRANSACTION' => 7,
173+
'LOCK IN SHARE MODE' => 7, 'NATURAL RIGHT JOIN' => 7, 'SELECT TRANSACTION' => 7,
174174
'DEFAULT CHARACTER SET' => 7,
175175
'NATURAL LEFT OUTER JOIN' => 7,
176176
'NATURAL RIGHT OUTER JOIN' => 7, 'WITH CONSISTENT SNAPSHOT' => 7,

src/Contexts/ContextMySql50500.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,8 @@ class ContextMySql50500 extends Context
163163
'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7,
164164
'LESS THAN' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7,
165165
'UNION ALL' => 7,
166-
'CROSS JOIN' => 7, 'INNER JOIN' => 7, 'LINEAR KEY' => 7, 'NO RELEASE' => 7,
167-
'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
166+
'CROSS JOIN' => 7, 'FOR UPDATE' => 7, 'INNER JOIN' => 7, 'LINEAR KEY' => 7,
167+
'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
168168
'LINEAR HASH' => 7,
169169
'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'NATURAL JOIN' => 7,
170170
'PARTITION BY' => 7, 'SET PASSWORD' => 7, 'SQL SECURITY' => 7,
@@ -174,7 +174,7 @@ class ContextMySql50500 extends Context
174174
'INDEX DIRECTORY' => 7, 'LEFT OUTER JOIN' => 7, 'SUBPARTITION BY' => 7,
175175
'GENERATED ALWAYS' => 7, 'RIGHT OUTER JOIN' => 7,
176176
'NATURAL LEFT JOIN' => 7, 'START TRANSACTION' => 7,
177-
'NATURAL RIGHT JOIN' => 7, 'SELECT TRANSACTION' => 7,
177+
'LOCK IN SHARE MODE' => 7, 'NATURAL RIGHT JOIN' => 7, 'SELECT TRANSACTION' => 7,
178178
'DEFAULT CHARACTER SET' => 7,
179179
'NATURAL LEFT OUTER JOIN' => 7,
180180
'NATURAL RIGHT OUTER JOIN' => 7, 'WITH CONSISTENT SNAPSHOT' => 7,

src/Contexts/ContextMySql50600.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,8 @@ class ContextMySql50600 extends Context
169169
'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7,
170170
'LESS THAN' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7,
171171
'UNION ALL' => 7,
172-
'CROSS JOIN' => 7, 'INNER JOIN' => 7, 'LINEAR KEY' => 7, 'NO RELEASE' => 7,
173-
'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
172+
'CROSS JOIN' => 7, 'FOR UPDATE' => 7, 'INNER JOIN' => 7, 'LINEAR KEY' => 7,
173+
'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
174174
'LINEAR HASH' => 7,
175175
'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'NATURAL JOIN' => 7,
176176
'PARTITION BY' => 7, 'SET PASSWORD' => 7, 'SQL SECURITY' => 7,
@@ -180,7 +180,7 @@ class ContextMySql50600 extends Context
180180
'INDEX DIRECTORY' => 7, 'LEFT OUTER JOIN' => 7, 'SUBPARTITION BY' => 7,
181181
'GENERATED ALWAYS' => 7, 'RIGHT OUTER JOIN' => 7,
182182
'NATURAL LEFT JOIN' => 7, 'START TRANSACTION' => 7,
183-
'NATURAL RIGHT JOIN' => 7, 'SELECT TRANSACTION' => 7,
183+
'LOCK IN SHARE MODE' => 7, 'NATURAL RIGHT JOIN' => 7, 'SELECT TRANSACTION' => 7,
184184
'DEFAULT CHARACTER SET' => 7,
185185
'NATURAL LEFT OUTER JOIN' => 7,
186186
'NATURAL RIGHT OUTER JOIN' => 7, 'WITH CONSISTENT SNAPSHOT' => 7,

src/Contexts/ContextMySql50700.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,8 @@ class ContextMySql50700 extends Context
175175
'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7,
176176
'LESS THAN' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7,
177177
'UNION ALL' => 7,
178-
'CROSS JOIN' => 7, 'INNER JOIN' => 7, 'LINEAR KEY' => 7, 'NO RELEASE' => 7,
179-
'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
178+
'CROSS JOIN' => 7, 'FOR UPDATE' => 7, 'INNER JOIN' => 7, 'LINEAR KEY' => 7,
179+
'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
180180
'LINEAR HASH' => 7,
181181
'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'NATURAL JOIN' => 7,
182182
'PARTITION BY' => 7, 'SET PASSWORD' => 7, 'SQL SECURITY' => 7,
@@ -186,7 +186,7 @@ class ContextMySql50700 extends Context
186186
'INDEX DIRECTORY' => 7, 'LEFT OUTER JOIN' => 7, 'SUBPARTITION BY' => 7,
187187
'GENERATED ALWAYS' => 7, 'RIGHT OUTER JOIN' => 7,
188188
'NATURAL LEFT JOIN' => 7, 'START TRANSACTION' => 7,
189-
'NATURAL RIGHT JOIN' => 7, 'SELECT TRANSACTION' => 7,
189+
'LOCK IN SHARE MODE' => 7, 'NATURAL RIGHT JOIN' => 7, 'SELECT TRANSACTION' => 7,
190190
'DEFAULT CHARACTER SET' => 7,
191191
'NATURAL LEFT OUTER JOIN' => 7,
192192
'NATURAL RIGHT OUTER JOIN' => 7, 'WITH CONSISTENT SNAPSHOT' => 7,

src/Parser.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,12 @@ class Parser
111111
'class' => 'SqlParser\\Components\\OptionsArray',
112112
'field' => 'options',
113113
),
114+
'_END_OPTIONS' => array(
115+
'class' => 'SqlParser\\Components\\OptionsArray',
116+
'field' => 'end_options',
117+
),
118+
119+
114120
'UNION' => array(
115121
'class' => 'SqlParser\\Components\\UnionKeyword',
116122
'field' => 'union',

src/Statement.php

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -352,10 +352,23 @@ public function parse(Parser $parser, TokensList $list)
352352
$parsedOptions = true;
353353
}
354354
} elseif ($class === null) {
355-
// There is no parser for this keyword and isn't the beginning
356-
// of a statement (so no options) either.
357-
$parser->error(__('Unrecognized keyword.'), $token);
358-
continue;
355+
// Handle special end options in Select statement
356+
// See Statements\SelectStatement::$END_OPTIONS
357+
if (get_class($this) === 'SqlParser\Statements\SelectStatement'
358+
&& ($token->value === 'FOR UPDATE'
359+
|| $token->value === 'LOCK IN SHARE MODE')
360+
) {
361+
$this->end_options = OptionsArray::parse(
362+
$parser,
363+
$list,
364+
static::$END_OPTIONS
365+
);
366+
} else {
367+
// There is no parser for this keyword and isn't the beginning
368+
// of a statement (so no options) either.
369+
$parser->error(__('Unrecognized keyword.'), $token);
370+
continue;
371+
}
359372
}
360373

361374
$this->before($parser, $list, $token);

src/Statements/SelectStatement.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ class SelectStatement extends Statement
7474
'SQL_CALC_FOUND_ROWS' => 9,
7575
);
7676

77+
public static $END_OPTIONS = array(
78+
'FOR UPDATE' => 1,
79+
'LOCK IN SHARE MODE' => 1
80+
);
81+
7782
/**
7883
* The clauses of this statement, in order.
7984
*
@@ -111,6 +116,7 @@ class SelectStatement extends Statement
111116
'LIMIT' => array('LIMIT', 3),
112117
'PROCEDURE' => array('PROCEDURE', 3),
113118
'UNION' => array('UNION', 1),
119+
'_END_OPTIONS' => array('_END_OPTIONS', 1)
114120
// These are available only when `UNION` is present.
115121
// 'ORDER BY' => array('ORDER BY', 3),
116122
// 'LIMIT' => array('LIMIT', 3),
@@ -200,6 +206,15 @@ class SelectStatement extends Statement
200206
*/
201207
public $union = array();
202208

209+
/**
210+
* The end options of this query.
211+
*
212+
* @var OptionsArray
213+
*
214+
* @see static::$END_OPTIONS
215+
*/
216+
public $end_options;
217+
203218
/**
204219
* Gets the clauses of this statement.
205220
*

tests/Builder/SelectStatementTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,27 @@ public function testBuilderAlias()
5353
$stmt->build()
5454
);
5555
}
56+
57+
public function testBuilderEndOptions()
58+
{
59+
/* Assertion 1 */
60+
$query = 'SELECT pid, name2 FROM tablename WHERE pid = 20 FOR UPDATE ';
61+
$parser = new Parser($query);
62+
$stmt = $parser->statements[0];
63+
64+
$this->assertEquals(
65+
$query,
66+
$stmt->build()
67+
);
68+
69+
/* Assertion 2 */
70+
$query = 'SELECT pid, name2 FROM tablename WHERE pid = 20 LOCK IN SHARE MODE ';
71+
$parser = new Parser($query);
72+
$stmt = $parser->statements[0];
73+
74+
$this->assertEquals(
75+
$query,
76+
$stmt->build()
77+
);
78+
}
5679
}

tests/Parser/SelectStatementTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ public function testSelectProvider()
5656
array('parser/parseSelectJoinNaturalRightOuter'),
5757
array('parser/parseSelectJoinMultiple'),
5858
array('parser/parseSelectWrongOrder'),
59+
array('parser/parseSelectEndOptions1'),
60+
array('parser/parseSelectEndOptions2'),
61+
array('parser/parseSelectEndOptionsErr'),
5962
);
6063
}
6164
}

0 commit comments

Comments
 (0)