Commit 4b39aa3a authored by Tom Lane's avatar Tom Lane

Re-implement psql's input scanning to use a flex-generated lexer, as per

recent discussion.  The lexer is used for both SQL command text and
backslash commands.  The purpose of this change is to make it easier to
track the behavior of the backend's SQL lexer --- essentially identical
flex rules are now used by psql.  Also, this cleans up a lot of very
squirrelly code in mainloop.c and command.c.  The flex code is somewhat
bulkier than the removed code, but should be lots easier to maintain.
parent 737f1cd4
......@@ -5,7 +5,7 @@
# Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California
#
# $PostgreSQL: pgsql/src/bin/psql/Makefile,v 1.38 2003/11/29 19:52:06 pgsql Exp $
# $PostgreSQL: pgsql/src/bin/psql/Makefile,v 1.39 2004/02/19 19:40:08 tgl Exp $
#
#-------------------------------------------------------------------------
......@@ -19,7 +19,10 @@ override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS) -DFRONTEND
OBJS= command.o common.o help.o input.o stringutils.o mainloop.o copy.o \
startup.o prompt.o variables.o large_obj.o print.o describe.o \
tab-complete.o mbprint.o
psqlscan.o tab-complete.o mbprint.o
FLEXFLAGS = -Cfe
all: submake-libpq submake-libpgport psql
......@@ -36,6 +39,13 @@ $(srcdir)/sql_help.h:
@echo "*** Perl is needed to build psql help."
endif
$(srcdir)/psqlscan.c: psqlscan.l
ifdef FLEX
$(FLEX) $(FLEXFLAGS) -o'$@' $<
else
@$(missing) flex $< $@
endif
distprep: $(srcdir)/sql_help.h
install: all installdirs
......@@ -47,8 +57,9 @@ installdirs:
uninstall:
rm -f $(DESTDIR)$(bindir)/psql$(X)
# psqlscan.c is in the distribution tarball, so is not cleaned here
clean distclean:
rm -f psql$(X) $(OBJS)
maintainer-clean: distclean
rm -f $(srcdir)/sql_help.h
rm -f $(srcdir)/sql_help.h $(srcdir)/psqlscan.c
This diff is collapsed.
......@@ -3,15 +3,14 @@
*
* Copyright (c) 2000-2003, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/bin/psql/command.h,v 1.18 2003/11/29 19:52:06 pgsql Exp $
* $PostgreSQL: pgsql/src/bin/psql/command.h,v 1.19 2004/02/19 19:40:09 tgl Exp $
*/
#ifndef COMMAND_H
#define COMMAND_H
#include "pqexpbuffer.h"
#include "settings.h"
#include "print.h"
#include "psqlscan.h"
typedef enum _backslashResult
......@@ -26,10 +25,8 @@ typedef enum _backslashResult
} backslashResult;
extern backslashResult HandleSlashCmds(const char *line,
PQExpBuffer query_buf,
const char **end_of_cmd,
volatile int *paren_level);
extern backslashResult HandleSlashCmds(PsqlScanState scan_state,
PQExpBuffer query_buf);
extern int process_file(char *filename);
......
This diff is collapsed.
/*
* psql - the PostgreSQL interactive terminal
*
* Copyright (c) 2000-2003, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/bin/psql/psqlscan.h,v 1.1 2004/02/19 19:40:09 tgl Exp $
*/
#ifndef PSQLSCAN_H
#define PSQLSCAN_H
#include "pqexpbuffer.h"
#include "prompt.h"
/* Abstract type for lexer's internal state */
typedef struct PsqlScanStateData *PsqlScanState;
/* Termination states for psql_scan() */
typedef enum
{
PSCAN_SEMICOLON, /* found command-ending semicolon */
PSCAN_BACKSLASH, /* found backslash command */
PSCAN_INCOMPLETE, /* end of line, SQL statement incomplete */
PSCAN_EOL /* end of line, SQL possibly complete */
} PsqlScanResult;
/* Different ways for scan_slash_option to handle parameter words */
enum slash_option_type
{
OT_NORMAL, /* normal case */
OT_SQLID, /* treat as SQL identifier */
OT_SQLIDHACK, /* SQL identifier, but don't downcase */
OT_FILEPIPE, /* it's a filename or pipe */
OT_WHOLE_LINE /* just snarf the rest of the line */
};
extern PsqlScanState psql_scan_create(void);
extern void psql_scan_destroy(PsqlScanState state);
extern void psql_scan_setup(PsqlScanState state,
const char *line, int line_len);
extern void psql_scan_finish(PsqlScanState state);
extern PsqlScanResult psql_scan(PsqlScanState state,
PQExpBuffer query_buf,
promptStatus_t *prompt);
extern void psql_scan_reset(PsqlScanState state);
extern bool psql_scan_in_quote(PsqlScanState state);
extern char *psql_scan_slash_command(PsqlScanState state);
extern char *psql_scan_slash_option(PsqlScanState state,
enum slash_option_type type,
char *quote,
bool semicolon);
extern void psql_scan_slash_command_end(PsqlScanState state);
extern void psql_scan_slash_pushback(PsqlScanState state, const char *str);
#endif /* PSQLSCAN_H */
This diff is collapsed.
......@@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2003, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/bin/psql/startup.c,v 1.84 2004/02/12 19:58:16 momjian Exp $
* $PostgreSQL: pgsql/src/bin/psql/startup.c,v 1.85 2004/02/19 19:40:09 tgl Exp $
*/
#include "postgres_fe.h"
......@@ -238,11 +238,20 @@ main(int argc, char *argv[])
*/
else if (options.action == ACT_SINGLE_SLASH)
{
PsqlScanState scan_state;
if (VariableEquals(pset.vars, "ECHO", "all"))
puts(options.action_string);
successResult = HandleSlashCmds(options.action_string, NULL, NULL, NULL) != CMD_ERROR
scan_state = psql_scan_create();
psql_scan_setup(scan_state,
options.action_string,
strlen(options.action_string));
successResult = HandleSlashCmds(scan_state, NULL) != CMD_ERROR
? EXIT_SUCCESS : EXIT_FAILURE;
psql_scan_destroy(scan_state);
}
/*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment