summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMadhura Jayaratne <madhura.cj@gmail.com>2017-09-23 15:57:04 +1000
committerMadhura Jayaratne <madhura.cj@gmail.com>2017-09-23 15:57:04 +1000
commitd88d392cbf6237857a450ab44217386970e33d78 (patch)
treea16c0eff7c1dadda0bb2bb393e0d9f072abe4c28
parent83bcdffcff1a0e86c36ae51fe02597939d6fc2d2 (diff)
downloadsql-parser-d88d392cbf6237857a450ab44217386970e33d78.zip
sql-parser-d88d392cbf6237857a450ab44217386970e33d78.tar.gz
sql-parser-d88d392cbf6237857a450ab44217386970e33d78.tar.bz2
Fix #172 Support parameter binding
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
-rw-r--r--src/Components/Expression.php2
-rw-r--r--src/Context.php2
-rw-r--r--src/Lexer.php4
-rw-r--r--src/Token.php4
-rw-r--r--tests/Misc/ParameterTest.php25
-rw-r--r--tests/data/misc/parseParameter.in1
-rw-r--r--tests/data/misc/parseParameter.out1
7 files changed, 39 insertions, 0 deletions
diff --git a/src/Components/Expression.php b/src/Components/Expression.php
index a1b460b..cce797f 100644
--- a/src/Components/Expression.php
+++ b/src/Components/Expression.php
@@ -267,6 +267,8 @@ class Expression extends Component
|| ($token->type === Token::TYPE_BOOL)
|| (($token->type === Token::TYPE_SYMBOL)
&& ($token->flags & Token::FLAG_SYMBOL_VARIABLE))
+ || (($token->type === Token::TYPE_SYMBOL)
+ && ($token->flags & Token::FLAG_SYMBOL_PARAMETER))
|| (($token->type === Token::TYPE_OPERATOR)
&& ($token->value !== '.'))
) {
diff --git a/src/Context.php b/src/Context.php
index f31f42c..8f180bf 100644
--- a/src/Context.php
+++ b/src/Context.php
@@ -388,6 +388,8 @@ abstract class Context
return Token::FLAG_SYMBOL_VARIABLE;
} elseif ($str[0] === '`') {
return Token::FLAG_SYMBOL_BACKTICK;
+ } elseif ($str[0] === ':') {
+ return Token::FLAG_SYMBOL_PARAMETER;
}
return null;
diff --git a/src/Lexer.php b/src/Lexer.php
index 1aa376e..e734c6f 100644
--- a/src/Lexer.php
+++ b/src/Lexer.php
@@ -871,6 +871,10 @@ class Lexer extends Core
$token .= $this->str[$this->last++];
$flags |= Token::FLAG_SYMBOL_SYSTEM;
}
+ } elseif ($flags & Token::FLAG_SYMBOL_PARAMETER) {
+ if ($this->last + 1 < $this->len) {
+ $this->last++;
+ }
} else {
$token = '';
}
diff --git a/src/Token.php b/src/Token.php
index e481119..c3bdc19 100644
--- a/src/Token.php
+++ b/src/Token.php
@@ -167,6 +167,7 @@ class Token
const FLAG_SYMBOL_BACKTICK = 2;
const FLAG_SYMBOL_USER = 4;
const FLAG_SYMBOL_SYSTEM = 8;
+ const FLAG_SYMBOL_PARAMETER = 16;
/**
* The token it its raw string representation.
@@ -301,6 +302,9 @@ class Token
'UTF-8'
);
}
+ if ((isset($str[0])) && ($str[0] === ':')) {
+ $str = mb_substr($str, 1, mb_strlen($str), 'UTF-8');
+ }
if ((isset($str[0])) && (($str[0] === '`')
|| ($str[0] === '"') || ($str[0] === '\''))
) {
diff --git a/tests/Misc/ParameterTest.php b/tests/Misc/ParameterTest.php
new file mode 100644
index 0000000..8aaed96
--- /dev/null
+++ b/tests/Misc/ParameterTest.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace PhpMyAdmin\SqlParser\Tests\Misc;
+
+use PhpMyAdmin\SqlParser\Tests\TestCase;
+
+class ParameterTest extends TestCase
+{
+ /**
+ * @dataProvider testParameterProvider
+ *
+ * @param mixed $test
+ */
+ public function testParameter($test)
+ {
+ $this->runParserTest($test);
+ }
+
+ public function testParameterProvider()
+ {
+ return array(
+ array('misc/parseParameter'),
+ );
+ }
+}
diff --git a/tests/data/misc/parseParameter.in b/tests/data/misc/parseParameter.in
new file mode 100644
index 0000000..0a34382
--- /dev/null
+++ b/tests/data/misc/parseParameter.in
@@ -0,0 +1 @@
+INSERT INTO `person` (`firstname`, `lastname`, `email`) VALUES (:firstname, :lastname, :email); \ No newline at end of file
diff --git a/tests/data/misc/parseParameter.out b/tests/data/misc/parseParameter.out
new file mode 100644
index 0000000..d1dd350
--- /dev/null
+++ b/tests/data/misc/parseParameter.out
@@ -0,0 +1 @@
+a:3:{s:5:"lexer";O:26:"PhpMyAdmin\SqlParser\Lexer":8:{s:3:"str";s:95:"INSERT INTO `person` (`firstname`, `lastname`, `email`) VALUES (:firstname, :lastname, :email);";s:3:"len";i:95;s:4:"last";i:95;s:4:"list";O:31:"PhpMyAdmin\SqlParser\TokensList":3:{s:6:"tokens";a:29:{i:0;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:6:"INSERT";s:5:"value";s:6:"INSERT";s:7:"keyword";s:6:"INSERT";s:4:"type";i:1;s:5:"flags";i:35;s:8:"position";i:0;}i:1;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:7:"keyword";N;s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:6;}i:2;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:4:"INTO";s:5:"value";s:4:"INTO";s:7:"keyword";s:4:"INTO";s:4:"type";i:1;s:5:"flags";i:3;s:8:"position";i:7;}i:3;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:7:"keyword";N;s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:11;}i:4;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:8:"`person`";s:5:"value";s:6:"person";s:7:"keyword";N;s:4:"type";i:8;s:5:"flags";i:2;s:8:"position";i:12;}i:5;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:7:"keyword";N;s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:20;}i:6;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:1:"(";s:5:"value";s:1:"(";s:7:"keyword";N;s:4:"type";i:2;s:5:"flags";i:16;s:8:"position";i:21;}i:7;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:11:"`firstname`";s:5:"value";s:9:"firstname";s:7:"keyword";N;s:4:"type";i:8;s:5:"flags";i:2;s:8:"position";i:22;}i:8;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:1:",";s:5:"value";s:1:",";s:7:"keyword";N;s:4:"type";i:2;s:5:"flags";i:16;s:8:"position";i:33;}i:9;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:7:"keyword";N;s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:34;}i:10;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:10:"`lastname`";s:5:"value";s:8:"lastname";s:7:"keyword";N;s:4:"type";i:8;s:5:"flags";i:2;s:8:"position";i:35;}i:11;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:1:",";s:5:"value";s:1:",";s:7:"keyword";N;s:4:"type";i:2;s:5:"flags";i:16;s:8:"position";i:45;}i:12;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:7:"keyword";N;s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:46;}i:13;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:7:"`email`";s:5:"value";s:5:"email";s:7:"keyword";N;s:4:"type";i:8;s:5:"flags";i:2;s:8:"position";i:47;}i:14;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:1:")";s:5:"value";s:1:")";s:7:"keyword";N;s:4:"type";i:2;s:5:"flags";i:16;s:8:"position";i:54;}i:15;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:7:"keyword";N;s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:55;}i:16;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:6:"VALUES";s:5:"value";s:6:"VALUES";s:7:"keyword";s:6:"VALUES";s:4:"type";i:1;s:5:"flags";i:35;s:8:"position";i:56;}i:17;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:7:"keyword";N;s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:62;}i:18;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:1:"(";s:5:"value";s:1:"(";s:7:"keyword";N;s:4:"type";i:2;s:5:"flags";i:16;s:8:"position";i:63;}i:19;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:10:":firstname";s:5:"value";s:9:"firstname";s:7:"keyword";N;s:4:"type";i:8;s:5:"flags";i:16;s:8:"position";i:64;}i:20;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:1:",";s:5:"value";s:1:",";s:7:"keyword";N;s:4:"type";i:2;s:5:"flags";i:16;s:8:"position";i:74;}i:21;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:7:"keyword";N;s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:75;}i:22;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:9:":lastname";s:5:"value";s:8:"lastname";s:7:"keyword";N;s:4:"type";i:8;s:5:"flags";i:16;s:8:"position";i:76;}i:23;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:1:",";s:5:"value";s:1:",";s:7:"keyword";N;s:4:"type";i:2;s:5:"flags";i:16;s:8:"position";i:85;}i:24;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:1:" ";s:5:"value";s:1:" ";s:7:"keyword";N;s:4:"type";i:3;s:5:"flags";i:0;s:8:"position";i:86;}i:25;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:6:":email";s:5:"value";s:5:"email";s:7:"keyword";N;s:4:"type";i:8;s:5:"flags";i:16;s:8:"position";i:87;}i:26;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:1:")";s:5:"value";s:1:")";s:7:"keyword";N;s:4:"type";i:2;s:5:"flags";i:16;s:8:"position";i:93;}i:27;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";s:1:";";s:5:"value";s:1:";";s:7:"keyword";N;s:4:"type";i:9;s:5:"flags";i:0;s:8:"position";i:94;}i:28;O:26:"PhpMyAdmin\SqlParser\Token":6:{s:5:"token";N;s:5:"value";N;s:7:"keyword";N;s:4:"type";i:9;s:5:"flags";i:0;s:8:"position";N;}}s:5:"count";i:29;s:3:"idx";i:29;}s:9:"delimiter";s:1:";";s:12:"delimiterLen";i:1;s:6:"strict";b:0;s:6:"errors";a:0:{}}s:6:"parser";O:27:"PhpMyAdmin\SqlParser\Parser":5:{s:4:"list";r:6;s:10:"statements";a:1:{i:0;O:47:"PhpMyAdmin\SqlParser\Statements\InsertStatement":8:{s:4:"into";O:43:"PhpMyAdmin\SqlParser\Components\IntoKeyword":7:{s:4:"type";N;s:4:"dest";O:42:"PhpMyAdmin\SqlParser\Components\Expression":7:{s:8:"database";N;s:5:"table";s:6:"person";s:6:"column";N;s:4:"expr";s:8:"`person`";s:5:"alias";N;s:8:"function";N;s:8:"subquery";N;}s:7:"columns";a:3:{i:0;s:9:"firstname";i:1;s:8:"lastname";i:2;s:5:"email";}s:6:"values";N;s:14:"fields_options";N;s:14:"fields_keyword";N;s:13:"lines_options";N;}s:6:"values";a:1:{i:0;O:40:"PhpMyAdmin\SqlParser\Components\ArrayObj":2:{s:3:"raw";a:3:{i:0;s:10:":firstname";i:1;s:9:":lastname";i:2;s:6:":email";}s:6:"values";a:3:{i:0;s:9:"firstname";i:1;s:8:"lastname";i:2;s:5:"email";}}}s:3:"set";N;s:6:"select";N;s:14:"onDuplicateSet";N;s:7:"options";O:44:"PhpMyAdmin\SqlParser\Components\OptionsArray":1:{s:7:"options";a:0:{}}s:5:"first";i:0;s:4:"last";i:26;}}s:8:"brackets";i:0;s:6:"strict";b:0;s:6:"errors";a:0:{}}s:6:"errors";a:2:{s:5:"lexer";a:0:{}s:6:"parser";a:0:{}}} \ No newline at end of file