From 48d61a0c05316a25d9462379e79ff56d5e22a29c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Tobias=20de=20Freitas=20Neto?= Date: Wed, 31 May 2017 11:52:34 -0400 Subject: [PATCH 1/3] Add GroupKeyword class to fix postgres GROUP BY --- src/Components/GroupKeyword.php | 141 ++++++++++++++++++++++++++ src/Parser.php | 2 +- tests/Components/GroupKeywordTest.php | 24 +++++ 3 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 src/Components/GroupKeyword.php create mode 100644 tests/Components/GroupKeywordTest.php diff --git a/src/Components/GroupKeyword.php b/src/Components/GroupKeyword.php new file mode 100644 index 000000000..4fb667f4b --- /dev/null +++ b/src/Components/GroupKeyword.php @@ -0,0 +1,141 @@ +expr = $expr; + $this->type = $type; + } + + /** + * @param Parser $parser the parser that serves as context + * @param TokensList $list the list of tokens that are being parsed + * @param array $options parameters for parsing + * + * @return GroupKeyword[] + */ + public static function parse(Parser $parser, TokensList $list, array $options = array()) + { + $ret = array(); + + $expr = new self(); + + /** + * The state of the parser. + * + * Below are the states of the parser. + * + * 0 --------------------[ expression ]-------------------> 1 + * + * 1 ------------------------[ , ]------------------------> 0 + * 1 -------------------[ ASC / DESC ]--------------------> 1 + * + * @var int + */ + $state = 0; + + for (; $list->idx < $list->count; ++$list->idx) { + /** + * Token parsed at this moment. + * + * @var Token + */ + $token = $list->tokens[$list->idx]; + + // End of statement. + if ($token->type === Token::TYPE_DELIMITER) { + break; + } + + // Skipping whitespaces and comments. + if (($token->type === Token::TYPE_WHITESPACE) || ($token->type === Token::TYPE_COMMENT)) { + continue; + } + + if ($state === 0) { + $expr->expr = Expression::parse($parser, $list); + $state = 1; + } elseif ($state === 1) { + if (($token->type === Token::TYPE_KEYWORD) + && (($token->keyword === 'ASC') || ($token->keyword === 'DESC')) + ) { + $expr->type = $token->keyword; + } elseif (($token->type === Token::TYPE_OPERATOR) + && ($token->value === ',') + ) { + if (!empty($expr->expr)) { + $ret[] = $expr; + } + $expr = new self(); + $state = 0; + } else { + break; + } + } + } + + // Last iteration was not processed. + if (!empty($expr->expr)) { + $ret[] = $expr; + } + + --$list->idx; + + return $ret; + } + + /** + * @param GroupKeyword|GroupKeyword[] $component the component to be built + * @param array $options parameters for building + * + * @return string + */ + public static function build($component, array $options = array()) + { + if (is_array($component)) { + return implode(', ', $component); + } + + return trim($component->expr . ' ' . $component->type); + + } +} diff --git a/src/Parser.php b/src/Parser.php index 1aaa565b7..9ef7debf5 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -168,7 +168,7 @@ class Parser extends Core 'options' => array('field' => 'table'), ), 'GROUP BY' => array( - 'class' => 'PhpMyAdmin\\SqlParser\\Components\\OrderKeyword', + 'class' => 'PhpMyAdmin\\SqlParser\\Components\\GroupKeyword', 'field' => 'group', ), 'HAVING' => array( diff --git a/tests/Components/GroupKeywordTest.php b/tests/Components/GroupKeywordTest.php new file mode 100644 index 000000000..515de6b1e --- /dev/null +++ b/tests/Components/GroupKeywordTest.php @@ -0,0 +1,24 @@ +assertEquals( + GroupKeyword::build( + array( + new GroupKeyword(new Expression('a'), 'ASC'), + new GroupKeyword(new Expression('b'), 'DESC'), + new GroupKeyword(new Expression('c')), + ) + ), + 'a ASC, b DESC, c' + ); + } +} From acc4fbd589ba0d48effc17ab8cdbd27e2ef04197 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Tobias=20de=20Freitas=20Neto?= Date: Wed, 31 May 2017 12:59:37 -0400 Subject: [PATCH 2/3] Changing name, description and homepage --- composer.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index eb61a926d..6d28321a3 100644 --- a/composer.json +++ b/composer.json @@ -1,9 +1,9 @@ { - "name": "phpmyadmin/sql-parser", - "description": "A validating SQL lexer and parser with a focus on MySQL dialect.", + "name": "phppgadmin/sql-parser", + "description": "Fork of phpmyadmin https://github.com/phpmyadmin/sql-parser.", "license": "GPL-2.0+", "keywords": ["sql", "lexer", "parser", "analysis"], - "homepage": "https://github.com/phpmyadmin/sql-parser", + "homepage": "https://github.com/JoseNetoooo/sql-parser", "authors": [ { "name": "The phpMyAdmin Team", @@ -12,8 +12,8 @@ } ], "support": { - "issues": "https://github.com/phpmyadmin/sql-parser/issues", - "source": "https://github.com/phpmyadmin/sql-parser" + "issues": "https://github.com/JoseNetoooo/sql-parser/issues", + "source": "https://github.com/JoseNetoooo/sql-parser" }, "require": { "php": ">=5.3.0", From 94c49f59eb4eee33455b7c7775797dbc82b64b67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Tobias=20de=20Freitas=20Neto?= Date: Wed, 31 May 2017 13:01:27 -0400 Subject: [PATCH 3/3] Changing name to use as a composer dependency --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 6d28321a3..d05c43358 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "phppgadmin/sql-parser", + "name": "jtfnetoo/sql-parser", "description": "Fork of phpmyadmin https://github.com/phpmyadmin/sql-parser.", "license": "GPL-2.0+", "keywords": ["sql", "lexer", "parser", "analysis"],