From 6ec6cc599678c0ac76f4559039ff3399f843b9b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20=C5=A0im=C3=A1nek?= Date: Fri, 15 Dec 2023 13:00:23 +0100 Subject: [PATCH] Add --syntax option to postgres. - it validates SQL on STDIN and reports back if valid/invalid --- src/backend/main/main.c | 45 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/backend/main/main.c b/src/backend/main/main.c index ed11e8be7fab7..eb7266f9d5d32 100644 --- a/src/backend/main/main.c +++ b/src/backend/main/main.c @@ -40,6 +40,7 @@ #include "utils/memutils.h" #include "utils/pg_locale.h" #include "utils/ps_status.h" +#include "parser/parser.h" const char *progname; @@ -50,6 +51,7 @@ static void startup_hacks(const char *progname); static void init_locale(const char *categoryname, int category, const char *locale); static void help(const char *progname); static void check_root(const char *progname); +static void check_syntax(void); /* @@ -153,6 +155,10 @@ main(int argc, char *argv[]) fputs(PG_BACKEND_VERSIONSTR, stdout); exit(0); } + if (strcmp(argv[1], "--syntax") == 0) + { + check_syntax(); + } /* * In addition to the above, we allow "--describe-config" and "-C var" @@ -347,6 +353,7 @@ help(const char *progname) printf(_(" -s show statistics after each query\n")); printf(_(" -S WORK-MEM set amount of memory for sorts (in kB)\n")); printf(_(" -V, --version output version information, then exit\n")); + printf(_(" --syntax checks SQL on STDIN is valid, then exit\n")); printf(_(" --NAME=VALUE set run-time parameter\n")); printf(_(" --describe-config describe configuration parameters, then exit\n")); printf(_(" -?, --help show this help, then exit\n")); @@ -422,6 +429,44 @@ check_root(const char *progname) #endif /* WIN32 */ } +static void +check_syntax() { + List *parsetree_list; + bool valid = false; + char buffer[1024 * 1024]; + char ch; + int i = 0; + + // TODO: check for buffer overflow + while ((ch = getchar()) != EOF) + { + buffer[i] = ch; + i++; + } + + PG_TRY(); + { + parsetree_list = raw_parser(buffer, RAW_PARSE_DEFAULT); + valid = true; + } + PG_CATCH(); + { + EmitErrorReport(); + FlushErrorState(); + valid = false; + } + PG_END_TRY(); + + // TODO: translate output + if (valid && parsetree_list) { + printf("Valid SQL\n"); + exit(0); + } else { + printf("Invalid SQL\n"); + exit(1); + } +} + /* * At least on linux, set_ps_display() breaks /proc/$pid/environ. The * sanitizer library uses /proc/$pid/environ to implement getenv() as it wants