| 388 | |
| 389 | |
| 390 | int Parser::yylexAux() |
| 391 | { |
| 392 | thread_db* tdbb = JRD_get_thread_data(); |
| 393 | Database* const dbb = tdbb->getDatabase(); |
| 394 | MemoryPool& pool = *tdbb->getDefaultPool(); |
| 395 | |
| 396 | unsigned maxByteLength, maxCharLength; |
| 397 | |
| 398 | if (scratch->flags & DsqlCompilerScratch::FLAG_INTERNAL_REQUEST) |
| 399 | { |
| 400 | maxByteLength = MAX_SQL_IDENTIFIER_LEN; |
| 401 | maxCharLength = METADATA_IDENTIFIER_CHAR_LEN; |
| 402 | } |
| 403 | else |
| 404 | { |
| 405 | maxByteLength = dbb->dbb_config->getMaxIdentifierByteLength(); |
| 406 | maxCharLength = dbb->dbb_config->getMaxIdentifierCharLength(); |
| 407 | } |
| 408 | |
| 409 | SSHORT c = lex.ptr[-1]; |
| 410 | UCHAR tok_class = classes(c); |
| 411 | char string[MAX_TOKEN_LEN]; |
| 412 | |
| 413 | // Depending on tok_class of token, parse token |
| 414 | |
| 415 | lex.last_token = lex.ptr - 1; |
| 416 | |
| 417 | if (tok_class & CHR_INTRODUCER) |
| 418 | { |
| 419 | // The Introducer (_) is skipped, all other idents are copied |
| 420 | // to become the name of the character set. |
| 421 | char* p = string; |
| 422 | for (; lex.ptr < lex.end && (classes(*lex.ptr) & CHR_IDENT); lex.ptr++) |
| 423 | { |
| 424 | if (lex.ptr >= lex.end) |
| 425 | return -1; |
| 426 | |
| 427 | check_copy_incr(p, UPPER7(*lex.ptr), string); |
| 428 | } |
| 429 | |
| 430 | check_bound(p, string); |
| 431 | |
| 432 | if (p > string + maxByteLength || p > string + maxCharLength) |
| 433 | yyabandon(yyposn, -104, isc_dyn_name_longer); |
| 434 | |
| 435 | *p = 0; |
| 436 | |
| 437 | // make a string value to hold the name, the name is resolved in pass1_constant. |
| 438 | yylval.metaNamePtr = FB_NEW_POOL(pool) MetaName(pool, string, p - string); |
| 439 | |
| 440 | return TOK_INTRODUCER; |
| 441 | } |
| 442 | |
| 443 | // parse a quoted string, being sure to look for double quotes |
| 444 | |
| 445 | if (tok_class & CHR_QUOTE) |
| 446 | { |
| 447 | StrMark mark; |
nothing calls this directly
no test coverage detected