|
7 | 7 | namespace PhpMyAdmin\SqlParser\Components; |
8 | 8 |
|
9 | 9 | use PhpMyAdmin\SqlParser\Component; |
| 10 | +use PhpMyAdmin\SqlParser\Context; |
10 | 11 | use PhpMyAdmin\SqlParser\Parser; |
11 | 12 | use PhpMyAdmin\SqlParser\Token; |
12 | 13 | use PhpMyAdmin\SqlParser\TokensList; |
@@ -55,6 +56,13 @@ class CaseExpression extends Component |
55 | 56 | */ |
56 | 57 | public $else_result; |
57 | 58 |
|
| 59 | + /** |
| 60 | + * The alias of this CASE statement |
| 61 | + * |
| 62 | + * @var string |
| 63 | + */ |
| 64 | + public $alias; |
| 65 | + |
58 | 66 | /** |
59 | 67 | * The sub-expression. |
60 | 68 | * |
@@ -94,6 +102,13 @@ public static function parse(Parser $parser, TokensList $list, array $options = |
94 | 102 | */ |
95 | 103 | $type = 0; |
96 | 104 |
|
| 105 | + /** |
| 106 | + * Whether an alias is expected |
| 107 | + * |
| 108 | + * @bool |
| 109 | + */ |
| 110 | + $alias = false; |
| 111 | + |
97 | 112 | ++$list->idx; // Skip 'CASE' |
98 | 113 |
|
99 | 114 | for (; $list->idx < $list->count; ++$list->idx) { |
@@ -201,6 +216,56 @@ public static function parse(Parser $parser, TokensList $list, array $options = |
201 | 216 | $list->tokens[$list->idx - 1] |
202 | 217 | ); |
203 | 218 | } else { |
| 219 | + |
| 220 | + // Parse alias for CASE statement |
| 221 | + for (; $list->idx < $list->count; ++$list->idx) { |
| 222 | + $token = $list->tokens[$list->idx]; |
| 223 | + |
| 224 | + // Skipping whitespaces and comments. |
| 225 | + if (($token->type === Token::TYPE_WHITESPACE) |
| 226 | + || ($token->type === Token::TYPE_COMMENT) |
| 227 | + ) { |
| 228 | + continue; |
| 229 | + } |
| 230 | + |
| 231 | + // |
| 232 | + if($token->type === Token::TYPE_KEYWORD |
| 233 | + && $token->keyword === 'AS'){ |
| 234 | + |
| 235 | + if ($alias) { |
| 236 | + $parser->error( |
| 237 | + 'An alias was expected.', |
| 238 | + $token |
| 239 | + ); |
| 240 | + break; |
| 241 | + } |
| 242 | + $alias = true; |
| 243 | + continue; |
| 244 | + } |
| 245 | + |
| 246 | + if ($alias){ |
| 247 | + |
| 248 | + // An alias is expected (the keyword `AS` was previously found). |
| 249 | + if (!empty($ret->alias)) { |
| 250 | + $parser->error('An alias was previously found.', $token); |
| 251 | + break; |
| 252 | + } |
| 253 | + $ret->alias = $token->value; |
| 254 | + $alias = false; |
| 255 | + |
| 256 | + continue; |
| 257 | + } |
| 258 | + |
| 259 | + break; |
| 260 | + } |
| 261 | + if ($alias) { |
| 262 | + $parser->error( |
| 263 | + 'An alias was expected.', |
| 264 | + $list->tokens[$list->idx - 1] |
| 265 | + ); |
| 266 | + } |
| 267 | + |
| 268 | + |
204 | 269 | $ret->expr = self::build($ret); |
205 | 270 | } |
206 | 271 |
|
@@ -241,6 +306,10 @@ public static function build($component, array $options = array()) |
241 | 306 | } |
242 | 307 | $ret .= 'END'; |
243 | 308 |
|
| 309 | + if ($component->alias) { |
| 310 | + $ret .= ' AS ' . Context::escape($component->alias); |
| 311 | + } |
| 312 | + |
244 | 313 | return $ret; |
245 | 314 | } |
246 | 315 | } |
0 commit comments