Skip to content

Commit fdac7b8

Browse files
committed
Trivial solution to identier quotes in SQL Mode ANSI_QUOTES, with CLI tools ansi mode update
1 parent 717cb27 commit fdac7b8

File tree

3 files changed

+45
-14
lines changed

3 files changed

+45
-14
lines changed

src/Context.php

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ public static function isSymbol($str)
423423

424424
if ($str[0] === '@') {
425425
return Token::FLAG_SYMBOL_VARIABLE;
426-
} elseif ($str[0] === '`') {
426+
} elseif ($str[0] === self::getIdentifierQuote()) {
427427
return Token::FLAG_SYMBOL_BACKTICK;
428428
} elseif ($str[0] === ':' || $str[0] === '?') {
429429
return Token::FLAG_SYMBOL_PARAMETER;
@@ -450,6 +450,8 @@ public static function isString($str)
450450

451451
if ($str[0] === '\'') {
452452
return Token::FLAG_STRING_SINGLE_QUOTES;
453+
} elseif (self::hasMode(self::SQL_MODE_ANSI_QUOTES) && $str[0] === '"') {
454+
return null;
453455
} elseif ($str[0] === '"') {
454456
return Token::FLAG_STRING_DOUBLE_QUOTES;
455457
}
@@ -604,6 +606,29 @@ public static function escape($str, $quote = '`')
604606

605607
return $quote . str_replace($quote, $quote . $quote, $str) . $quote;
606608
}
609+
610+
/**
611+
* Returns char used to quote identifiers based on currently set SQL Mode (ie. standard or ANSI_QUOTES)
612+
* @return string either " (double quote, ansi_quotes mode) or ` (backtick, standard mode)
613+
*/
614+
public static function getIdentifierQuote()
615+
{
616+
return self::hasMode(self::SQL_MODE_ANSI_QUOTES) ? '"' : '`';
617+
}
618+
619+
/**
620+
* Function verifies that given SQL Mode constant is currently set
621+
*
622+
* @return boolean false on empty param, true/false on given constant/int value
623+
* @param $flag int for example Context::SQL_MODE_ANSI_QUOTES
624+
*/
625+
public static function hasMode($flag = null)
626+
{
627+
if (empty($flag)) {
628+
return false;
629+
}
630+
return (self::$MODE & $flag) === $flag;
631+
}
607632
}
608633

609634
// Initializing the default context.

src/Lexer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -917,7 +917,7 @@ public function parseSymbol()
917917
$str = null;
918918

919919
if ($this->last < $this->len) {
920-
if (($str = $this->parseString('`')) === null) {
920+
if (($str = $this->parseString(Context::getIdentifierQuote())) === null) {
921921
if (($str = $this->parseUnknown()) === null) {
922922
$this->error(
923923
'Variable name was expected.',

src/Utils/CLI.php

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public function mergeLongOpts(&$params, &$longopts)
3636

3737
public function usageHighlight()
3838
{
39-
echo "Usage: highlight-query --query SQL [--format html|cli|text]\n";
39+
echo "Usage: highlight-query --query SQL [--format html|cli|text] [--ansi]\n";
4040
echo " cat file.sql | highlight-query\n";
4141
}
4242

@@ -51,9 +51,10 @@ public function parseHighlight()
5151
'help',
5252
'query:',
5353
'format:',
54+
'ansi'
5455
];
5556
$params = $this->getopt(
56-
'hq:f:',
57+
'hq:f:a',
5758
$longopts
5859
);
5960
if ($params === false) {
@@ -93,6 +94,9 @@ public function runHighlight()
9394
}
9495
}
9596

97+
if (isset($params['a'])) {
98+
Context::setMode('ANSI_QUOTES');
99+
}
96100
if (isset($params['q'])) {
97101
echo Formatter::format(
98102
$params['q'],
@@ -111,7 +115,7 @@ public function runHighlight()
111115

112116
public function usageLint()
113117
{
114-
echo "Usage: lint-query --query SQL\n";
118+
echo "Usage: lint-query --query SQL [--ansi]\n";
115119
echo " cat file.sql | lint-query\n";
116120
}
117121

@@ -121,9 +125,10 @@ public function parseLint()
121125
'help',
122126
'query:',
123127
'context:',
128+
'ansi'
124129
];
125130
$params = $this->getopt(
126-
'hq:c:',
131+
'hq:c:a',
127132
$longopts
128133
);
129134
$this->mergeLongOpts($params, $longopts);
@@ -137,38 +142,35 @@ public function runLint()
137142
if ($params === false) {
138143
return 1;
139144
}
140-
141145
if (isset($params['h'])) {
142146
$this->usageLint();
143147

144148
return 0;
145149
}
146-
147150
if (isset($params['c'])) {
148151
Context::load($params['c']);
149152
}
150-
151153
if (! isset($params['q'])) {
152154
if ($stdIn = $this->readStdin()) {
153155
$params['q'] = $stdIn;
154156
}
155157
}
156-
158+
if (isset($params['a'])) {
159+
Context::setMode('ANSI_QUOTES');
160+
}
157161
if (isset($params['q'])) {
158162
$lexer = new Lexer($params['q'], false);
159163
$parser = new Parser($lexer->list);
160164
$errors = Error::get([$lexer, $parser]);
161165
if (count($errors) === 0) {
162166
return 0;
163167
}
164-
165168
$output = Error::format($errors);
166169
echo implode("\n", $output);
167170
echo "\n";
168171

169172
return 10;
170173
}
171-
172174
echo "ERROR: Missing parameters!\n";
173175
$this->usageLint();
174176

@@ -177,7 +179,7 @@ public function runLint()
177179

178180
public function usageTokenize()
179181
{
180-
echo "Usage: tokenize-query --query SQL\n";
182+
echo "Usage: tokenize-query --query SQL [--ansi]\n";
181183
echo " cat file.sql | tokenize-query\n";
182184
}
183185

@@ -186,9 +188,10 @@ public function parseTokenize()
186188
$longopts = [
187189
'help',
188190
'query:',
191+
'ansi'
189192
];
190193
$params = $this->getopt(
191-
'hq:',
194+
'hq:a',
192195
$longopts
193196
);
194197
$this->mergeLongOpts($params, $longopts);
@@ -215,6 +218,9 @@ public function runTokenize()
215218
}
216219
}
217220

221+
if (isset($params['a'])) {
222+
Context::setMode('ANSI_QUOTES');
223+
}
218224
if (isset($params['q'])) {
219225
$lexer = new Lexer($params['q'], false);
220226
foreach ($lexer->list->tokens as $idx => $token) {

0 commit comments

Comments
 (0)