PostgreSQL Source Code git master
psqlscanslash.h File Reference
Include dependency graph for psqlscanslash.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Enumerations

enum  slash_option_type {
  OT_NORMAL , OT_SQLID , OT_SQLIDHACK , OT_FILEPIPE ,
  OT_WHOLE_LINE
}
 

Functions

char * psql_scan_slash_command (PsqlScanState state)
 
char * psql_scan_slash_option (PsqlScanState state, enum slash_option_type type, char *quote, bool semicolon)
 
void psql_scan_slash_command_end (PsqlScanState state)
 
int psql_scan_get_paren_depth (PsqlScanState state)
 
void psql_scan_set_paren_depth (PsqlScanState state, int depth)
 
void dequote_downcase_identifier (char *str, bool downcase, int encoding)
 

Enumeration Type Documentation

◆ slash_option_type

Enumerator
OT_NORMAL 
OT_SQLID 
OT_SQLIDHACK 
OT_FILEPIPE 
OT_WHOLE_LINE 

Definition at line 15 of file psqlscanslash.h.

16{
17 OT_NORMAL, /* normal case */
18 OT_SQLID, /* treat as SQL identifier */
19 OT_SQLIDHACK, /* SQL identifier, but don't downcase */
20 OT_FILEPIPE, /* it's a filename or pipe */
21 OT_WHOLE_LINE, /* just snarf the rest of the line */
22};
@ OT_NORMAL
Definition: psqlscanslash.h:17
@ OT_SQLID
Definition: psqlscanslash.h:18
@ OT_SQLIDHACK
Definition: psqlscanslash.h:19
@ OT_FILEPIPE
Definition: psqlscanslash.h:20
@ OT_WHOLE_LINE
Definition: psqlscanslash.h:21

Function Documentation

◆ dequote_downcase_identifier()

void dequote_downcase_identifier ( char *  str,
bool  downcase,
int  encoding 
)

Definition at line 743 of file psqlscanslash.l.

744{
745 bool inquotes = false;
746 char *cp = str;
747
748 while (*cp)
749 {
750 if (*cp == '"')
751 {
752 if (inquotes && cp[1] == '"')
753 {
754 /* Keep the first quote, remove the second */
755 cp++;
756 }
757 else
758 inquotes = !inquotes;
759 /* Collapse out quote at *cp */
760 memmove(cp, cp + 1, strlen(cp));
761 /* do not advance cp */
762 }
763 else
764 {
765 if (downcase && !inquotes)
766 *cp = pg_tolower((unsigned char) *cp);
767 cp += PQmblenBounded(cp, encoding);
768 }
769 }
770}
int PQmblenBounded(const char *s, int encoding)
Definition: fe-misc.c:1243
const char * str
int32 encoding
Definition: pg_database.h:41
unsigned char pg_tolower(unsigned char ch)
Definition: pgstrcasecmp.c:122

References encoding, pg_tolower(), PQmblenBounded(), and str.

Referenced by indexOfColumn(), and psql_scan_slash_option().

◆ psql_scan_get_paren_depth()

int psql_scan_get_paren_depth ( PsqlScanState  state)

Definition at line 711 of file psqlscanslash.l.

712{
713 return state->paren_depth;
714}
Definition: regguts.h:323

Referenced by save_query_text_state().

◆ psql_scan_set_paren_depth()

void psql_scan_set_paren_depth ( PsqlScanState  state,
int  depth 
)

Definition at line 720 of file psqlscanslash.l.

721{
722 Assert(depth >= 0);
723 state->paren_depth = depth;
724}
Assert(PointerIsAligned(start, uint64))

References Assert().

Referenced by discard_query_text().

◆ psql_scan_slash_command()

char * psql_scan_slash_command ( PsqlScanState  state)

Definition at line 480 of file psqlscanslash.l.

481{
482 PQExpBufferData mybuf;
483
484 /* Must be scanning already */
485 Assert(state->scanbufhandle != NULL);
486
487 /* Build a local buffer that we'll return the data of */
488 initPQExpBuffer(&mybuf);
489
490 /* Set current output target */
491 state->output_buf = &mybuf;
492
493 /* Set input source */
494 if (state->buffer_stack != NULL)
495 yy_switch_to_buffer(state->buffer_stack->buf, state->scanner);
496 else
497 yy_switch_to_buffer(state->scanbufhandle, state->scanner);
498
499 /*
500 * Set lexer start state. Note that this is sufficient to switch
501 * state->scanner over to using the tables in this lexer file.
502 */
503 state->start_state = xslashcmd;
504
505 /* And lex. */
506 yylex(NULL, state->scanner);
507
508 /* There are no possible errors in this lex state... */
509
510 /*
511 * In case the caller returns to using the regular SQL lexer, reselect the
512 * appropriate initial state.
513 */
515
516 return mybuf.data;
517}
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
void psql_scan_reselect_sql_lexer(PsqlScanState state)
Definition: psqlscan.l:1303
int yylex(YYSTYPE *yylval_param, yyscan_t yyscanner)

References Assert(), PQExpBufferData::data, initPQExpBuffer(), psql_scan_reselect_sql_lexer(), and yylex().

Referenced by HandleSlashCmds().

◆ psql_scan_slash_command_end()

void psql_scan_slash_command_end ( PsqlScanState  state)

Definition at line 678 of file psqlscanslash.l.

679{
680 /* Must be scanning already */
681 Assert(state->scanbufhandle != NULL);
682
683 /* Set current output target */
684 state->output_buf = NULL; /* we won't output anything */
685
686 /* Set input source */
687 if (state->buffer_stack != NULL)
688 yy_switch_to_buffer(state->buffer_stack->buf, state->scanner);
689 else
690 yy_switch_to_buffer(state->scanbufhandle, state->scanner);
691
692 /* Set lexer start state */
693 state->start_state = xslashend;
694
695 /* And lex. */
696 yylex(NULL, state->scanner);
697
698 /* There are no possible errors in this lex state... */
699
700 /*
701 * We expect the caller to return to using the regular SQL lexer, so
702 * reselect the appropriate initial state.
703 */
705}

References Assert(), psql_scan_reselect_sql_lexer(), and yylex().

Referenced by HandleSlashCmds().

◆ psql_scan_slash_option()

char * psql_scan_slash_option ( PsqlScanState  state,
enum slash_option_type  type,
char *  quote,
bool  semicolon 
)

Definition at line 539 of file psqlscanslash.l.

543{
544 PQExpBufferData mybuf;
545 int lexresult PG_USED_FOR_ASSERTS_ONLY;
546 int final_state;
547 char local_quote;
548
549 /* Must be scanning already */
550 Assert(state->scanbufhandle != NULL);
551
552 if (quote == NULL)
553 quote = &local_quote;
554 *quote = 0;
555
556 /* Build a local buffer that we'll return the data of */
557 initPQExpBuffer(&mybuf);
558
559 /* Set up static variables that will be used by yylex */
561 option_quote = quote;
563
564 /* Set current output target */
565 state->output_buf = &mybuf;
566
567 /* Set input source */
568 if (state->buffer_stack != NULL)
569 yy_switch_to_buffer(state->buffer_stack->buf, state->scanner);
570 else
571 yy_switch_to_buffer(state->scanbufhandle, state->scanner);
572
573 /* Set lexer start state */
574 if (type == OT_WHOLE_LINE)
575 state->start_state = xslashwholeline;
576 else
577 state->start_state = xslashargstart;
578
579 /* And lex. */
580 lexresult = yylex(NULL, state->scanner);
581
582 /* Save final state for a moment... */
583 final_state = state->start_state;
584
585 /*
586 * In case the caller returns to using the regular SQL lexer, reselect the
587 * appropriate initial state.
588 */
590
591 /*
592 * Check the lex result: we should have gotten back either LEXRES_OK or
593 * LEXRES_EOL (the latter indicating end of string). If we were inside a
594 * quoted string, as indicated by final_state, EOL is an error.
595 */
596 Assert(lexresult == LEXRES_EOL || lexresult == LEXRES_OK);
597
598 switch (final_state)
599 {
600 case xslashargstart:
601 /* empty arg */
602 break;
603 case xslasharg:
604 /* Strip any unquoted trailing semicolons if requested */
605 if (semicolon)
606 {
607 while (unquoted_option_chars-- > 0 &&
608 mybuf.len > 0 &&
609 mybuf.data[mybuf.len - 1] == ';')
610 {
611 mybuf.data[--mybuf.len] = '\0';
612 }
613 }
614
615 /*
616 * If SQL identifier processing was requested, then we strip out
617 * excess double quotes and optionally downcase unquoted letters.
618 */
619 if (type == OT_SQLID || type == OT_SQLIDHACK)
620 {
622 (type != OT_SQLIDHACK),
623 state->encoding);
624 /* update mybuf.len for possible shortening */
625 mybuf.len = strlen(mybuf.data);
626 }
627 break;
628 case xslashquote:
629 case xslashbackquote:
630 case xslashdquote:
631 /* must have hit EOL inside quotes */
632 pg_log_error("unterminated quoted string");
633 termPQExpBuffer(&mybuf);
634 return NULL;
635 case xslashwholeline:
636
637 /*
638 * In whole-line mode, we interpret semicolon = true as stripping
639 * trailing whitespace as well as semicolons; this gives the
640 * nearest equivalent to what semicolon = true does in normal
641 * mode. Note there's no concept of quoting in this mode.
642 */
643 if (semicolon)
644 {
645 while (mybuf.len > 0 &&
646 (mybuf.data[mybuf.len - 1] == ';' ||
647 (isascii((unsigned char) mybuf.data[mybuf.len - 1]) &&
648 isspace((unsigned char) mybuf.data[mybuf.len - 1]))))
649 {
650 mybuf.data[--mybuf.len] = '\0';
651 }
652 }
653 break;
654 default:
655 /* can't get here */
656 fprintf(stderr, "invalid YY_START\n");
657 exit(1);
658 }
659
660 /*
661 * An unquoted empty argument isn't possible unless we are at end of
662 * command. Return NULL instead.
663 */
664 if (mybuf.len == 0 && *quote == 0)
665 {
666 termPQExpBuffer(&mybuf);
667 return NULL;
668 }
669
670 /* Else return the completed string. */
671 return mybuf.data;
672}
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:224
#define fprintf(file, fmt, msg)
Definition: cubescan.l:21
#define semicolon
Definition: indent_codes.h:44
#define pg_log_error(...)
Definition: logging.h:106
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:129
static int unquoted_option_chars
Definition: psqlscanslash.l:47
static char * option_quote
Definition: psqlscanslash.l:46
static enum slash_option_type option_type
Definition: psqlscanslash.l:45
#define LEXRES_EOL
Definition: psqlscanslash.l:52
void dequote_downcase_identifier(char *str, bool downcase, int encoding)
#define LEXRES_OK
Definition: psqlscanslash.l:53
const char * type

References Assert(), PQExpBufferData::data, dequote_downcase_identifier(), fprintf, initPQExpBuffer(), PQExpBufferData::len, LEXRES_EOL, LEXRES_OK, option_quote, option_type, OT_SQLID, OT_SQLIDHACK, OT_WHOLE_LINE, pg_log_error, PG_USED_FOR_ASSERTS_ONLY, psql_scan_reselect_sql_lexer(), semicolon, termPQExpBuffer(), type, unquoted_option_chars, and yylex().

Referenced by exec_command_bind(), exec_command_bind_named(), exec_command_C(), exec_command_cd(), exec_command_close(), exec_command_copy(), exec_command_crosstabview(), exec_command_d(), exec_command_dfo(), exec_command_echo(), exec_command_edit(), exec_command_ef_ev(), exec_command_encoding(), exec_command_f(), exec_command_g(), exec_command_getenv(), exec_command_getresults(), exec_command_gset(), exec_command_help(), exec_command_include(), exec_command_list(), exec_command_lo(), exec_command_out(), exec_command_parse(), exec_command_password(), exec_command_prompt(), exec_command_pset(), exec_command_s(), exec_command_set(), exec_command_setenv(), exec_command_sf_sv(), exec_command_shell_escape(), exec_command_slash_command_help(), exec_command_t(), exec_command_T(), exec_command_timing(), exec_command_unset(), exec_command_watch(), exec_command_write(), exec_command_x(), exec_command_z(), gather_boolean_expression(), HandleSlashCmds(), ignore_slash_filepipe(), ignore_slash_options(), ignore_slash_whole_line(), process_command_g_options(), and read_connect_arg().