2004-02-19 20:40:09 +01:00
|
|
|
/*
|
|
|
|
* psql - the PostgreSQL interactive terminal
|
|
|
|
*
|
2016-01-02 19:33:40 +01:00
|
|
|
* Copyright (c) 2000-2016, PostgreSQL Global Development Group
|
2004-02-19 20:40:09 +01:00
|
|
|
*
|
2010-09-20 22:08:53 +02:00
|
|
|
* src/bin/psql/psqlscan.h
|
2004-02-19 20:40:09 +01:00
|
|
|
*/
|
|
|
|
#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;
|
|
|
|
|
2016-03-18 20:05:49 +01:00
|
|
|
/* Callback functions to be used by the lexer */
|
|
|
|
typedef struct PsqlScanCallbacks
|
|
|
|
{
|
|
|
|
/* Fetch value of a variable, as a pfree'able string; NULL if unknown */
|
|
|
|
/* This pointer can be NULL if no variable substitution is wanted */
|
|
|
|
char *(*get_variable) (const char *varname, bool escape, bool as_ident);
|
|
|
|
/* Print an error message someplace appropriate */
|
2016-03-19 15:59:20 +01:00
|
|
|
/* (very old gcc versions don't support attributes on function pointers) */
|
|
|
|
#if defined(__GNUC__) && __GNUC__ < 4
|
|
|
|
void (*write_error) (const char *fmt,...);
|
|
|
|
#else
|
2016-03-18 20:05:49 +01:00
|
|
|
void (*write_error) (const char *fmt,...) pg_attribute_printf(1, 2);
|
2016-03-19 15:59:20 +01:00
|
|
|
#endif
|
2016-03-18 20:05:49 +01:00
|
|
|
} PsqlScanCallbacks;
|
|
|
|
|
2004-02-19 20:40:09 +01:00
|
|
|
|
2016-03-18 20:05:49 +01:00
|
|
|
extern PsqlScanState psql_scan_create(const PsqlScanCallbacks *callbacks);
|
2004-02-19 20:40:09 +01:00
|
|
|
extern void psql_scan_destroy(PsqlScanState state);
|
|
|
|
|
|
|
|
extern void psql_scan_setup(PsqlScanState state,
|
2016-03-18 20:05:49 +01:00
|
|
|
const char *line, int line_len,
|
|
|
|
int encoding, bool std_strings);
|
2004-02-19 20:40:09 +01:00
|
|
|
extern void psql_scan_finish(PsqlScanState state);
|
|
|
|
|
|
|
|
extern PsqlScanResult psql_scan(PsqlScanState state,
|
2004-08-29 07:07:03 +02:00
|
|
|
PQExpBuffer query_buf,
|
|
|
|
promptStatus_t *prompt);
|
2004-02-19 20:40:09 +01:00
|
|
|
|
|
|
|
extern void psql_scan_reset(PsqlScanState state);
|
|
|
|
|
Split psql's lexer into two separate .l files for SQL and backslash cases.
This gets us to a point where psqlscan.l can be used by other frontend
programs for the same purpose psql uses it for, ie to detect when it's
collected a complete SQL command from input that is divided across
line boundaries. Moreover, other programs can supply their own lexers
for backslash commands of their own choosing. A follow-on patch will
use this in pgbench.
The end result here is roughly the same as in Kyotaro Horiguchi's
0001-Make-SQL-parser-part-of-psqlscan-independent-from-ps.patch, although
the details of the method for switching between lexers are quite different.
Basically, in this patch we share the entire PsqlScanState, YY_BUFFER_STATE
stack, *and* yyscan_t between different lexers. The only thing we need
to do to switch to a different lexer is to make sure the start_state is
valid for the new lexer. This works because flex doesn't keep any other
persistent state that depends on the specific lexing tables generated for
a particular .l file. (We are assuming that both lexers are built with
the same flex version, or at least versions that are compatible with
respect to the contents of yyscan_t; but that doesn't seem likely to
be a big problem in practice, considering how slowly flex changes.)
Aside from being more efficient than Horiguchi-san's original solution,
this avoids possible corner-case changes in semantics: the original code
was capable of popping the input buffer stack while still staying in
backslash-related parsing states. I'm not sure that that equates to any
useful user-visible behaviors, but I'm not sure it doesn't either, so
I'm loath to assume that we only need to consider the topmost buffer when
parsing a backslash command.
I've attempted to update the MSVC build scripts for the added .l file,
but will rely on the buildfarm to see if I missed anything.
Kyotaro Horiguchi and Tom Lane
2016-03-19 05:24:55 +01:00
|
|
|
extern void psql_scan_reselect_sql_lexer(PsqlScanState state);
|
2004-02-19 20:40:09 +01:00
|
|
|
|
Split psql's lexer into two separate .l files for SQL and backslash cases.
This gets us to a point where psqlscan.l can be used by other frontend
programs for the same purpose psql uses it for, ie to detect when it's
collected a complete SQL command from input that is divided across
line boundaries. Moreover, other programs can supply their own lexers
for backslash commands of their own choosing. A follow-on patch will
use this in pgbench.
The end result here is roughly the same as in Kyotaro Horiguchi's
0001-Make-SQL-parser-part-of-psqlscan-independent-from-ps.patch, although
the details of the method for switching between lexers are quite different.
Basically, in this patch we share the entire PsqlScanState, YY_BUFFER_STATE
stack, *and* yyscan_t between different lexers. The only thing we need
to do to switch to a different lexer is to make sure the start_state is
valid for the new lexer. This works because flex doesn't keep any other
persistent state that depends on the specific lexing tables generated for
a particular .l file. (We are assuming that both lexers are built with
the same flex version, or at least versions that are compatible with
respect to the contents of yyscan_t; but that doesn't seem likely to
be a big problem in practice, considering how slowly flex changes.)
Aside from being more efficient than Horiguchi-san's original solution,
this avoids possible corner-case changes in semantics: the original code
was capable of popping the input buffer stack while still staying in
backslash-related parsing states. I'm not sure that that equates to any
useful user-visible behaviors, but I'm not sure it doesn't either, so
I'm loath to assume that we only need to consider the topmost buffer when
parsing a backslash command.
I've attempted to update the MSVC build scripts for the added .l file,
but will rely on the buildfarm to see if I missed anything.
Kyotaro Horiguchi and Tom Lane
2016-03-19 05:24:55 +01:00
|
|
|
extern bool psql_scan_in_quote(PsqlScanState state);
|
2004-02-19 20:40:09 +01:00
|
|
|
|
|
|
|
#endif /* PSQLSCAN_H */
|