diff options
Diffstat (limited to 'src/bin/psql')
-rw-r--r-- | src/bin/psql/command.c | 1304 | ||||
-rw-r--r-- | src/bin/psql/command.h | 18 | ||||
-rw-r--r-- | src/bin/psql/common.c | 183 | ||||
-rw-r--r-- | src/bin/psql/common.h | 22 | ||||
-rw-r--r-- | src/bin/psql/copy.c | 138 | ||||
-rw-r--r-- | src/bin/psql/describe.c | 698 | ||||
-rw-r--r-- | src/bin/psql/describe.h | 20 | ||||
-rw-r--r-- | src/bin/psql/help.c | 143 | ||||
-rw-r--r-- | src/bin/psql/input.c | 47 | ||||
-rw-r--r-- | src/bin/psql/input.h | 42 | ||||
-rw-r--r-- | src/bin/psql/large_obj.c | 32 | ||||
-rw-r--r-- | src/bin/psql/mainloop.c | 414 | ||||
-rw-r--r-- | src/bin/psql/mainloop.h | 5 | ||||
-rw-r--r-- | src/bin/psql/print.c | 226 | ||||
-rw-r--r-- | src/bin/psql/print.h | 19 | ||||
-rw-r--r-- | src/bin/psql/prompt.c | 70 | ||||
-rw-r--r-- | src/bin/psql/prompt.h | 8 | ||||
-rw-r--r-- | src/bin/psql/settings.h | 14 | ||||
-rw-r--r-- | src/bin/psql/startup.c | 282 | ||||
-rw-r--r-- | src/bin/psql/stringutils.c | 4 | ||||
-rw-r--r-- | src/bin/psql/tab-complete.c | 1231 | ||||
-rw-r--r-- | src/bin/psql/tab-complete.h | 4 | ||||
-rw-r--r-- | src/bin/psql/variables.c | 4 | ||||
-rw-r--r-- | src/bin/psql/variables.h | 6 |
24 files changed, 2578 insertions, 2356 deletions
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index a66e9f4c73e..bc95e205065 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/command.c,v 1.27 2000/04/11 17:35:50 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/command.c,v 1.28 2000/04/12 17:16:22 momjian Exp $ */ #include "postgres.h" #include "command.h" @@ -46,12 +46,15 @@ static backslashResult exec_command(const char *cmd, const char *options_string, - const char ** continue_parse, + const char **continue_parse, PQExpBuffer query_buf); -enum option_type { OT_NORMAL, OT_SQLID }; -static char * scan_option(char ** string, enum option_type type, char * quote); -static char * unescape(const unsigned char *source, size_t len); +enum option_type +{ + OT_NORMAL, OT_SQLID +}; +static char *scan_option(char **string, enum option_type type, char *quote); +static char *unescape(const unsigned char *source, size_t len); static bool do_edit(const char *filename_arg, PQExpBuffer query_buf); static bool do_connect(const char *new_dbname, const char *new_user); @@ -84,35 +87,35 @@ HandleSlashCmds(const char *line, { backslashResult status = CMD_SKIP_LINE; char *my_line; - char *options_string = NULL; + char *options_string = NULL; size_t blank_loc; const char *continue_parse = NULL; /* tell the mainloop where the * backslash command ended */ #ifdef USE_ASSERT_CHECKING - assert(line); - assert(end_of_cmd); + assert(line); + assert(end_of_cmd); #endif my_line = xstrdup(line); /* - * Find the first whitespace. line[blank_loc] will now - * be the whitespace character or the \0 at the end - * - * Also look for a backslash, so stuff like \p\g works. + * Find the first whitespace. line[blank_loc] will now be the + * whitespace character or the \0 at the end + * + * Also look for a backslash, so stuff like \p\g works. */ blank_loc = strcspn(my_line, " \t\\"); - if (my_line[blank_loc] == '\\') - { - continue_parse = &my_line[blank_loc]; + if (my_line[blank_loc] == '\\') + { + continue_parse = &my_line[blank_loc]; my_line[blank_loc] = '\0'; - } + } /* do we have an option string? */ else if (my_line[blank_loc] != '\0') - { - options_string = &my_line[blank_loc + 1]; + { + options_string = &my_line[blank_loc + 1]; my_line[blank_loc] = '\0'; } @@ -120,11 +123,12 @@ HandleSlashCmds(const char *line, if (status == CMD_UNKNOWN) { + /* - * If the command was not recognized, try inserting a space after the - * first letter and call again. The one letter commands allow arguments - * to start immediately after the command, but that is no longer - * encouraged. + * If the command was not recognized, try inserting a space after + * the first letter and call again. The one letter commands allow + * arguments to start immediately after the command, but that is + * no longer encouraged. */ char new_cmd[2]; @@ -133,29 +137,29 @@ HandleSlashCmds(const char *line, status = exec_command(new_cmd, my_line + 1, &continue_parse, query_buf); - if (status != CMD_UNKNOWN && isalpha(new_cmd[0])) - psql_error("Warning: this syntax is deprecated\n"); + if (status != CMD_UNKNOWN && isalpha(new_cmd[0])) + psql_error("Warning: this syntax is deprecated\n"); } if (status == CMD_UNKNOWN) { - if (pset.cur_cmd_interactive) - fprintf(stderr, "Invalid command \\%s. Try \\? for help.\n", my_line); - else - psql_error("invalid command \\%s\n", my_line); + if (pset.cur_cmd_interactive) + fprintf(stderr, "Invalid command \\%s. Try \\? for help.\n", my_line); + else + psql_error("invalid command \\%s\n", my_line); status = CMD_ERROR; } if (continue_parse && *continue_parse && *(continue_parse + 1) == '\\') continue_parse += 2; - if (end_of_cmd) - { - if (continue_parse) - *end_of_cmd = line + (continue_parse - my_line); - else - *end_of_cmd = line + strlen(line); - } + if (end_of_cmd) + { + if (continue_parse) + *end_of_cmd = line + (continue_parse - my_line); + else + *end_of_cmd = line + strlen(line); + } free(my_line); @@ -167,25 +171,30 @@ HandleSlashCmds(const char *line, static backslashResult exec_command(const char *cmd, const char *options_string, - const char ** continue_parse, + const char **continue_parse, PQExpBuffer query_buf) { bool success = true; /* indicate here if the command ran ok or * failed */ bool quiet = QUIET(); backslashResult status = CMD_SKIP_LINE; - char *string, *string_cpy; - - /* - * The 'string' variable will be overwritten to point to the next token, - * hence we need an extra pointer so we can free this at the end. - */ - if (options_string) - string = string_cpy = xstrdup(options_string); - else - string = string_cpy = NULL; - - /* \a -- toggle field alignment This makes little sense but we keep it around. */ + char *string, + *string_cpy; + + /* + * The 'string' variable will be overwritten to point to the next + * token, hence we need an extra pointer so we can free this at the + * end. + */ + if (options_string) + string = string_cpy = xstrdup(options_string); + else + string = string_cpy = NULL; + + /* + * \a -- toggle field alignment This makes little sense but we keep it + * around. + */ if (strcmp(cmd, "a") == 0) { if (pset.popt.topt.format != PRINT_ALIGNED) @@ -196,51 +205,54 @@ exec_command(const char *cmd, /* \C -- override table title (formerly change HTML caption) */ else if (strcmp(cmd, "C") == 0) - { - char * opt = scan_option(&string, OT_NORMAL, NULL); + { + char *opt = scan_option(&string, OT_NORMAL, NULL); + success = do_pset("title", opt, &pset.popt, quiet); - free(opt); - } + free(opt); + } /*---------- * \c or \connect -- connect to new database or as different user * * \c foo bar connect to db "foo" as user "bar" - * \c foo [-] connect to db "foo" as current user - * \c - bar connect to current db as user "bar" - * \c connect to default db as default user - *---------- + * \c foo [-] connect to db "foo" as current user + * \c - bar connect to current db as user "bar" + * \c connect to default db as default user + *---------- */ else if (strcmp(cmd, "c") == 0 || strcmp(cmd, "connect") == 0) { - char *opt1, *opt2; - char opt1q, opt2q; + char *opt1, + *opt2; + char opt1q, + opt2q; - opt1 = scan_option(&string, OT_NORMAL, &opt1q); - opt2 = scan_option(&string, OT_NORMAL, &opt2q); + opt1 = scan_option(&string, OT_NORMAL, &opt1q); + opt2 = scan_option(&string, OT_NORMAL, &opt2q); if (opt2) /* gave username */ - success = do_connect(!opt1q && (strcmp(opt1, "-")==0 || strcmp(opt1, "")==0) ? "" : opt1, - !opt2q && (strcmp(opt2, "-")==0 || strcmp(opt2, "")==0) ? "" : opt2); + success = do_connect(!opt1q && (strcmp(opt1, "-") == 0 || strcmp(opt1, "") == 0) ? "" : opt1, + !opt2q && (strcmp(opt2, "-") == 0 || strcmp(opt2, "") == 0) ? "" : opt2); else if (opt1) - /* gave database name */ - success = do_connect(!opt1q && (strcmp(opt1, "-")==0 || strcmp(opt1, "")==0) ? "" : opt1, ""); - else - /* connect to default db as default user */ - success = do_connect(NULL, NULL); - - free(opt1); - free(opt2); + /* gave database name */ + success = do_connect(!opt1q && (strcmp(opt1, "-") == 0 || strcmp(opt1, "") == 0) ? "" : opt1, ""); + else + /* connect to default db as default user */ + success = do_connect(NULL, NULL); + + free(opt1); + free(opt2); } /* \copy */ else if (strcasecmp(cmd, "copy") == 0) - { + { success = do_copy(options_string); - if (options_string) - string += strlen(string); - } + if (options_string) + string += strlen(string); + } /* \copyright */ else if (strcmp(cmd, "copyright") == 0) @@ -249,20 +261,20 @@ exec_command(const char *cmd, /* \d* commands */ else if (cmd[0] == 'd') { - char * name; - bool show_verbose; + char *name; + bool show_verbose; - name = scan_option(&string, OT_SQLID, NULL); - show_verbose = strchr(cmd, '+') ? true : false; + name = scan_option(&string, OT_SQLID, NULL); + show_verbose = strchr(cmd, '+') ? true : false; switch (cmd[1]) { case '\0': - case '+': + case '+': if (name) success = describeTableDetails(name, show_verbose); else - /* standard listing of interesting things */ + /* standard listing of interesting things */ success = listTables("tvs", NULL, show_verbose); break; case 'a': @@ -299,7 +311,7 @@ exec_command(const char *cmd, default: status = CMD_UNKNOWN; } - free(name); + free(name); } @@ -308,63 +320,63 @@ exec_command(const char *cmd, * the query buffer */ else if (strcmp(cmd, "e") == 0 || strcmp(cmd, "edit") == 0) - { - char * fname; - - if (!query_buf) - { - psql_error("no query buffer\n"); - status = CMD_ERROR; - } - else - { - fname = scan_option(&string, OT_NORMAL, NULL); - status = do_edit(fname, query_buf) ? CMD_NEWEDIT : CMD_ERROR; - free(fname); - } - } + { + char *fname; + + if (!query_buf) + { + psql_error("no query buffer\n"); + status = CMD_ERROR; + } + else + { + fname = scan_option(&string, OT_NORMAL, NULL); + status = do_edit(fname, query_buf) ? CMD_NEWEDIT : CMD_ERROR; + free(fname); + } + } /* \echo and \qecho */ - else if (strcmp(cmd, "echo") == 0 || strcmp(cmd, "qecho")==0) + else if (strcmp(cmd, "echo") == 0 || strcmp(cmd, "qecho") == 0) { - char * value; - char quoted; - bool no_newline = false; - bool first = true; - FILE * fout; - - if (strcmp(cmd, "qecho")==0) - fout = pset.queryFout; - else - fout = stdout; - - while((value = scan_option(&string, OT_NORMAL, "ed))) - { - if (!quoted && strcmp(value, "-n")==0) - no_newline = true; - else - { - if (first) - first = false; - else - fputc(' ', fout); - fputs(value, fout); - } - free(value); - } - if (!no_newline) - fputs("\n", fout); + char *value; + char quoted; + bool no_newline = false; + bool first = true; + FILE *fout; + + if (strcmp(cmd, "qecho") == 0) + fout = pset.queryFout; + else + fout = stdout; + + while ((value = scan_option(&string, OT_NORMAL, "ed))) + { + if (!quoted && strcmp(value, "-n") == 0) + no_newline = true; + else + { + if (first) + first = false; + else + fputc(' ', fout); + fputs(value, fout); + } + free(value); + } + if (!no_newline) + fputs("\n", fout); } /* \encoding -- set/show client side encoding */ else if (strcmp(cmd, "encoding") == 0) { - char *encoding = scan_option(&string, OT_NORMAL, NULL); + char *encoding = scan_option(&string, OT_NORMAL, NULL); - if (!encoding) + if (!encoding) /* show encoding */ puts(pg_encoding_to_char(pset.encoding)); - else + else { #ifdef MULTIBYTE /* set encoding */ @@ -380,63 +392,66 @@ exec_command(const char *cmd, #else psql_error("\\%s: multi-byte support is not enabled\n", cmd); #endif - free(encoding); - } + free(encoding); + } } /* \f -- change field separator */ else if (strcmp(cmd, "f") == 0) - { - char * fname = scan_option(&string, OT_NORMAL, NULL); + { + char *fname = scan_option(&string, OT_NORMAL, NULL); + success = do_pset("fieldsep", fname, &pset.popt, quiet); - free(fname); - } + free(fname); + } /* \g means send query */ else if (strcmp(cmd, "g") == 0) { - char * fname = scan_option(&string, OT_NORMAL, NULL); + char *fname = scan_option(&string, OT_NORMAL, NULL); + if (!fname) pset.gfname = NULL; else pset.gfname = xstrdup(fname); - free(fname); + free(fname); status = CMD_SEND; } /* help */ else if (strcmp(cmd, "h") == 0 || strcmp(cmd, "help") == 0) - { + { helpSQL(options_string ? &options_string[strspn(options_string, " \t")] : NULL); - /* set pointer to end of line */ - if (string) - string += strlen(string); - } + /* set pointer to end of line */ + if (string) + string += strlen(string); + } /* HTML mode */ else if (strcmp(cmd, "H") == 0 || strcmp(cmd, "html") == 0) - { + { if (pset.popt.topt.format != PRINT_HTML) success = do_pset("format", "html", &pset.popt, quiet); else success = do_pset("format", "aligned", &pset.popt, quiet); - } + } /* \i is include file */ else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0) { - char * fname = scan_option(&string, OT_NORMAL, NULL); + char *fname = scan_option(&string, OT_NORMAL, NULL); + if (!fname) - { - psql_error("\\%s: missing required argument\n", cmd); + { + psql_error("\\%s: missing required argument\n", cmd); success = false; } else - { + { success = (process_file(fname) == EXIT_SUCCESS); - free (fname); - } + free(fname); + } } /* \l is list databases */ @@ -446,20 +461,21 @@ exec_command(const char *cmd, success = listAllDbs(true); /* - * large object things - */ + * large object things + */ else if (strncmp(cmd, "lo_", 3) == 0) { - char *opt1, *opt2; + char *opt1, + *opt2; - opt1 = scan_option(&string, OT_NORMAL, NULL); - opt2 = scan_option(&string, OT_NORMAL, NULL); + opt1 = scan_option(&string, OT_NORMAL, NULL); + opt2 = scan_option(&string, OT_NORMAL, NULL); if (strcmp(cmd + 3, "export") == 0) { if (!opt2) { - psql_error("\\%s: missing required argument\n", cmd); + psql_error("\\%s: missing required argument\n", cmd); success = false; } else @@ -470,7 +486,7 @@ exec_command(const char *cmd, { if (!opt1) { - psql_error("\\%s: missing required argument\n", cmd); + psql_error("\\%s: missing required argument\n", cmd); success = false; } else @@ -484,7 +500,7 @@ exec_command(const char *cmd, { if (!opt1) { - psql_error("\\%s: missing required argument\n", cmd); + psql_error("\\%s: missing required argument\n", cmd); success = false; } else @@ -494,18 +510,19 @@ exec_command(const char *cmd, else status = CMD_UNKNOWN; - free(opt1); - free(opt2); + free(opt1); + free(opt2); } /* \o -- set query output */ else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0) - { - char * fname = scan_option(&string, OT_NORMAL, NULL); + { + char *fname = scan_option(&string, OT_NORMAL, NULL); + success = setQFout(fname); - free(fname); - } + free(fname); + } /* \p prints the current query buffer */ else if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0) @@ -520,18 +537,19 @@ exec_command(const char *cmd, /* \pset -- set printing parameters */ else if (strcmp(cmd, "pset") == 0) { - char * opt0 = scan_option(&string, OT_NORMAL, NULL); - char * opt1 = scan_option(&string, OT_NORMAL, NULL); + char *opt0 = scan_option(&string, OT_NORMAL, NULL); + char *opt1 = scan_option(&string, OT_NORMAL, NULL); + if (!opt0) { - psql_error("\\%s: missing required argument\n", cmd); + psql_error("\\%s: missing required argument\n", cmd); success = false; } else success = do_pset(opt0, opt1, &pset.popt, quiet); - free(opt0); - free(opt1); + free(opt0); + free(opt1); } /* \q or \quit */ @@ -549,28 +567,27 @@ exec_command(const char *cmd, /* \s save history in a file or show it on the screen */ else if (strcmp(cmd, "s") == 0) { - char *fname = scan_option(&string, OT_NORMAL, NULL); + char *fname = scan_option(&string, OT_NORMAL, NULL); success = saveHistory(fname ? fname : "/dev/tty"); if (success && !quiet && fname) printf("Wrote history to %s.\n", fname); - free(fname); + free(fname); } /* \set -- generalized set variable/option command */ else if (strcmp(cmd, "set") == 0) { - char * opt0 = scan_option(&string, OT_NORMAL, NULL); + char *opt0 = scan_option(&string, OT_NORMAL, NULL); if (!opt0) { /* list all variables */ /* - * XXX - * This is in utter violation of the GetVariable abstraction, but I - * have not bothered to do it better. + * XXX This is in utter violation of the GetVariable + * abstraction, but I have not bothered to do it better. */ struct _variable *ptr; @@ -580,36 +597,37 @@ exec_command(const char *cmd, } else { - /* - * Set variable to the concatenation of the arguments. - */ - char * newval = NULL; - char * opt; - - opt = scan_option(&string, OT_NORMAL, NULL); - newval = xstrdup(opt ? opt : ""); - free(opt); - - while ((opt = scan_option(&string, OT_NORMAL, NULL))) - { - newval = realloc(newval, strlen(newval) + strlen(opt) + 1); - if (!newval) - { - psql_error("out of memory\n"); - exit(EXIT_FAILURE); - } - strcat(newval, opt); - free(opt); - } + + /* + * Set variable to the concatenation of the arguments. + */ + char *newval = NULL; + char *opt; + + opt = scan_option(&string, OT_NORMAL, NULL); + newval = xstrdup(opt ? opt : ""); + free(opt); + + while ((opt = scan_option(&string, OT_NORMAL, NULL))) + { + newval = realloc(newval, strlen(newval) + strlen(opt) + 1); + if (!newval) + { + psql_error("out of memory\n"); + exit(EXIT_FAILURE); + } + strcat(newval, opt); + free(opt); + } if (!SetVariable(pset.vars, opt0, newval)) { - psql_error("\\%s: error\n", cmd); + psql_error("\\%s: error\n", cmd); success = false; } - free(newval); + free(newval); } - free(opt0); + free(opt0); } /* \t -- turn off headers and row count */ @@ -619,67 +637,69 @@ exec_command(const char *cmd, /* \T -- define html <table ...> attributes */ else if (strcmp(cmd, "T") == 0) - { - char * value = scan_option(&string, OT_NORMAL, NULL); + { + char *value = scan_option(&string, OT_NORMAL, NULL); + success = do_pset("tableattr", value, &pset.popt, quiet); - free(value); - } - - /* \unset */ - else if (strcmp(cmd, "unset") == 0) - { - char * opt = scan_option(&string, OT_NORMAL, NULL); - if (!opt) - { - psql_error("\\%s: missing required argument\n", cmd); - success = false; - } - if (!SetVariable(pset.vars, opt, NULL)) - { - psql_error("\\%s: error\n", cmd); - success = false; - } - free(opt); - } + free(value); + } + + /* \unset */ + else if (strcmp(cmd, "unset") == 0) + { + char *opt = scan_option(&string, OT_NORMAL, NULL); + + if (!opt) + { + psql_error("\\%s: missing required argument\n", cmd); + success = false; + } + if (!SetVariable(pset.vars, opt, NULL)) + { + psql_error("\\%s: error\n", cmd); + success = false; + } + free(opt); + } /* \w -- write query buffer to file */ else if (strcmp(cmd, "w") == 0 || strcmp(cmd, "write") == 0) { FILE *fd = NULL; bool is_pipe = false; - char *fname = NULL; - - if (!query_buf) - { - psql_error("no query buffer\n"); - status = CMD_ERROR; - } - else - { - fname = scan_option(&string, OT_NORMAL, NULL); - - if (!fname) - { - psql_error("\\%s: missing required argument\n", cmd); - success = false; - } - else - { - if (fname[0] == '|') - { - is_pipe = true; - fd = popen(&fname[1], "w"); - } - else - fd = fopen(fname, "w"); - - if (!fd) - { - psql_error("%s: %s\n", fname, strerror(errno)); - success = false; - } - } - } + char *fname = NULL; + + if (!query_buf) + { + psql_error("no query buffer\n"); + status = CMD_ERROR; + } + else + { + fname = scan_option(&string, OT_NORMAL, NULL); + + if (!fname) + { + psql_error("\\%s: missing required argument\n", cmd); + success = false; + } + else + { + if (fname[0] == '|') + { + is_pipe = true; + fd = popen(&fname[1], "w"); + } + else + fd = fopen(fname, "w"); + + if (!fd) + { + psql_error("%s: %s\n", fname, strerror(errno)); + success = false; + } + } + } if (fd) { @@ -695,12 +715,12 @@ exec_command(const char *cmd, if (result == EOF) { - psql_error("%s: %s\n", fname, strerror(errno)); + psql_error("%s: %s\n", fname, strerror(errno)); success = false; } } - free(fname); + free(fname); } /* \x -- toggle expanded table representation */ @@ -710,41 +730,43 @@ exec_command(const char *cmd, /* \z -- list table rights (grant/revoke) */ else if (strcmp(cmd, "z") == 0) - { - char * opt = scan_option(&string, OT_SQLID, NULL); + { + char *opt = scan_option(&string, OT_SQLID, NULL); + success = permissionsList(opt); - free(opt); - } + free(opt); + } - /* \! -- shell escape */ + /* \! -- shell escape */ else if (strcmp(cmd, "!") == 0) - { + { success = do_shell(options_string); - /* wind pointer to end of line */ - if (string) - string += strlen(string); - } + /* wind pointer to end of line */ + if (string) + string += strlen(string); + } - /* \? -- slash command help */ + /* \? -- slash command help */ else if (strcmp(cmd, "?") == 0) slashUsage(); #if 0 - /* + + /* * These commands don't do anything. I just use them to test the * parser. */ else if (strcmp(cmd, "void") == 0 || strcmp(cmd, "#") == 0) { int i = 0; - char *value; + char *value; fprintf(stderr, "+ optstr = |%s|\n", options_string); - while((value = scan_option(&string, OT_NORMAL, NULL))) - { + while ((value = scan_option(&string, OT_NORMAL, NULL))) + { fprintf(stderr, "+ opt(%d) = |%s|\n", i++, value); - free(value); - } + free(value); + } } #endif @@ -754,12 +776,12 @@ exec_command(const char *cmd, if (!success) status = CMD_ERROR; - /* eat the rest of the options string */ - while(scan_option(&string, OT_NORMAL, NULL)) ; + /* eat the rest of the options string */ + while (scan_option(&string, OT_NORMAL, NULL)); - if (options_string && continue_parse) - *continue_parse = options_string + (string - string_cpy); - free(string_cpy); + if (options_string && continue_parse) + *continue_parse = options_string + (string - string_cpy); + free(string_cpy); return status; } @@ -770,268 +792,272 @@ exec_command(const char *cmd, * scan_option() */ static char * -scan_option(char ** string, enum option_type type, char * quote) +scan_option(char **string, enum option_type type, char *quote) { - unsigned int pos = 0; - char * options_string; - char * return_val; - - if (quote) - *quote = 0; - - if (!string || !(*string)) - return NULL; - - options_string = *string; - /* skip leading whitespace */ - pos += strspn(options_string+pos, " \t"); - - switch (options_string[pos]) - { - /* - * Double quoted string - */ - case '"': - { - unsigned int jj; - unsigned short int bslash_count = 0; - - /* scan for end of quote */ - for (jj = pos+1; options_string[jj]; jj += PQmblen(&options_string[jj], pset.encoding)) - { - if (options_string[jj] == '"' && bslash_count % 2 == 0) - break; - - if (options_string[jj] == '\\') - bslash_count++; - else - bslash_count=0; - } - - if (options_string[jj] == 0) - { - psql_error("parse error at end of line\n"); - *string = &options_string[jj]; - return NULL; - } - - return_val = malloc(jj-pos+2); - if (!return_val) - { - psql_error("out of memory\n"); - exit(EXIT_FAILURE); - } - - if (type == OT_NORMAL) - { - strncpy(return_val, &options_string[pos], jj-pos+1); - return_val[jj-pos+1] = '\0'; - } - /* - * If this is expected to be an SQL identifier like option - * then we strip out the double quotes - */ - else if (type == OT_SQLID) - { - unsigned int k, cc; - - bslash_count = 0; - cc = 0; - for (k = pos+1; options_string[k]; k += PQmblen(&options_string[k], pset.encoding)) - { - if (options_string[k] == '"' && bslash_count % 2 == 0) - break; - - if (options_string[jj] == '\\') - bslash_count++; - else - bslash_count=0; - - return_val[cc++] = options_string[k]; - } - return_val[cc] = '\0'; - } - - *string = options_string + jj+1; - if (quote) - *quote = '"'; - - return return_val; - } - - /* - * A single quote has a psql internal meaning, such as - * for delimiting file names, and it also allows for such - * escape sequences as \t. - */ - case '\'': - { - unsigned int jj; - unsigned short int bslash_count = 0; - - for (jj = pos+1; options_string[jj]; jj += PQmblen(&options_string[jj], pset.encoding)) - { - if (options_string[jj] == '\'' && bslash_count % 2 == 0) - break; - - if (options_string[jj] == '\\') - bslash_count++; - else - bslash_count=0; - } - - if (options_string[jj] == 0) - { - psql_error("parse error at end of line\n"); - *string = &options_string[jj]; - return NULL; - } - - return_val = unescape(&options_string[pos+1], jj-pos-1); - *string = &options_string[jj + 1]; - if (quote) - *quote = '\''; - return return_val; - } - - /* - * Backticks are for command substitution, like in shells - */ - case '`': - { - bool error = false; - FILE *fd = NULL; - char *file; - PQExpBufferData output; - char buf[512]; - size_t result, len; - - len = strcspn(options_string + pos + 1, "`"); - if (options_string[pos + 1 + len] == 0) - { - psql_error("parse error at end of line\n"); - *string = &options_string[pos + 1 + len]; - return NULL; - } - - options_string[pos + 1 + len] = '\0'; - file = options_string + pos + 1; - - fd = popen(file, "r"); - if (!fd) - { - psql_error("%s: %s\n", file, strerror(errno)); - error = true; - } - - if (!error) - { - initPQExpBuffer(&output); - - do - { - result = fread(buf, 1, 512, fd); - if (ferror(fd)) - { - psql_error("%s: %s\n", file, strerror(errno)); - error = true; - break; - } - appendBinaryPQExpBuffer(&output, buf, result); - } while (!feof(fd)); - appendPQExpBufferChar(&output, '\0'); - - if (pclose(fd) == -1) - { - psql_error("%s: %s\n", file, strerror(errno)); - error = true; - } - } - - if (!error) - { - if (output.data[strlen(output.data) - 1] == '\n') - output.data[strlen(output.data) - 1] = '\0'; - } - - if (!error) - return_val = output.data; - else - { - return_val = xstrdup(""); - termPQExpBuffer(&output); - } - options_string[pos + 1 + len] = '`'; - *string = options_string + pos + len + 2; - if (quote) - *quote = '`'; - return return_val; - } - - /* - * end of line - */ - case 0: - *string = &options_string[pos]; - return NULL; - - /* - * Variable substitution - */ - case ':': - { - size_t token_end; - const char * value; - char save_char; - - token_end = strcspn(&options_string[pos+1], " \t"); - save_char = options_string[pos+token_end+1]; - options_string[pos+token_end+1] = '\0'; - value = GetVariable(pset.vars, options_string+pos+1); - if (!value) - value = ""; - return_val = xstrdup(value); - options_string[pos+token_end+1] = save_char; - *string = &options_string[pos + token_end+1]; - return return_val; - } - - /* - * Next command - */ - case '\\': - *string = options_string + pos; - return NULL; - break; - - /* - * A normal word - */ - default: - { - size_t token_end; - char * cp; - - token_end = strcspn(&options_string[pos], " \t"); - return_val = malloc(token_end + 1); - if (!return_val) - { - psql_error("out of memory\n"); - exit(EXIT_FAILURE); - } - strncpy(return_val, &options_string[pos], token_end); - return_val[token_end] = 0; - - if (type == OT_SQLID) - for (cp = return_val; *cp; cp += PQmblen(cp, pset.encoding)) - if (isascii(*cp)) - *cp = tolower(*cp); - - *string = &options_string[pos+token_end]; - return return_val; - } - - } + unsigned int pos = 0; + char *options_string; + char *return_val; + + if (quote) + *quote = 0; + + if (!string || !(*string)) + return NULL; + + options_string = *string; + /* skip leading whitespace */ + pos += strspn(options_string + pos, " \t"); + + switch (options_string[pos]) + { + + /* + * Double quoted string + */ + case '"': + { + unsigned int jj; + unsigned short int bslash_count = 0; + + /* scan for end of quote */ + for (jj = pos + 1; options_string[jj]; jj += PQmblen(&options_string[jj], pset.encoding)) + { + if (options_string[jj] == '"' && bslash_count % 2 == 0) + break; + + if (options_string[jj] == '\\') + bslash_count++; + else + bslash_count = 0; + } + + if (options_string[jj] == 0) + { + psql_error("parse error at end of line\n"); + *string = &options_string[jj]; + return NULL; + } + + return_val = malloc(jj - pos + 2); + if (!return_val) + { + psql_error("out of memory\n"); + exit(EXIT_FAILURE); + } + + if (type == OT_NORMAL) + { + strncpy(return_val, &options_string[pos], jj - pos + 1); + return_val[jj - pos + 1] = '\0'; + } + + /* + * If this is expected to be an SQL identifier like option + * then we strip out the double quotes + */ + else if (type == OT_SQLID) + { + unsigned int k, + cc; + + bslash_count = 0; + cc = 0; + for (k = pos + 1; options_string[k]; k += PQmblen(&options_string[k], pset.encoding)) + { + if (options_string[k] == '"' && bslash_count % 2 == 0) + break; + + if (options_string[jj] == '\\') + bslash_count++; + else + bslash_count = 0; + + return_val[cc++] = options_string[k]; + } + return_val[cc] = '\0'; + } + + *string = options_string + jj + 1; + if (quote) + *quote = '"'; + + return return_val; + } + + /* + * A single quote has a psql internal meaning, such as for + * delimiting file names, and it also allows for such escape + * sequences as \t. + */ + case '\'': + { + unsigned int jj; + unsigned short int bslash_count = 0; + + for (jj = pos + 1; options_string[jj]; jj += PQmblen(&options_string[jj], pset.encoding)) + { + if (options_string[jj] == '\'' && bslash_count % 2 == 0) + break; + + if (options_string[jj] == '\\') + bslash_count++; + else + bslash_count = 0; + } + + if (options_string[jj] == 0) + { + psql_error("parse error at end of line\n"); + *string = &options_string[jj]; + return NULL; + } + + return_val = unescape(&options_string[pos + 1], jj - pos - 1); + *string = &options_string[jj + 1]; + if (quote) + *quote = '\''; + return return_val; + } + + /* + * Backticks are for command substitution, like in shells + */ + case '`': + { + bool error = false; + FILE *fd = NULL; + char *file; + PQExpBufferData output; + char buf[512]; + size_t result, + len; + + len = strcspn(options_string + pos + 1, "`"); + if (options_string[pos + 1 + len] == 0) + { + psql_error("parse error at end of line\n"); + *string = &options_string[pos + 1 + len]; + return NULL; + } + + options_string[pos + 1 + len] = '\0'; + file = options_string + pos + 1; + + fd = popen(file, "r"); + if (!fd) + { + psql_error("%s: %s\n", file, strerror(errno)); + error = true; + } + + if (!error) + { + initPQExpBuffer(&output); + + do + { + result = fread(buf, 1, 512, fd); + if (ferror(fd)) + { + psql_error("%s: %s\n", file, strerror(errno)); + error = true; + break; + } + appendBinaryPQExpBuffer(&output, buf, result); + } while (!feof(fd)); + appendPQExpBufferChar(&output, '\0'); + + if (pclose(fd) == -1) + { + psql_error("%s: %s\n", file, strerror(errno)); + error = true; + } + } + + if (!error) + { + if (output.data[strlen(output.data) - 1] == '\n') + output.data[strlen(output.data) - 1] = '\0'; + } + + if (!error) + return_val = output.data; + else + { + return_val = xstrdup(""); + termPQExpBuffer(&output); + } + options_string[pos + 1 + len] = '`'; + *string = options_string + pos + len + 2; + if (quote) + *quote = '`'; + return return_val; + } + + /* + * end of line + */ + case 0: + *string = &options_string[pos]; + return NULL; + + /* + * Variable substitution + */ + case ':': + { + size_t token_end; + const char *value; + char save_char; + + token_end = strcspn(&options_string[pos + 1], " \t"); + save_char = options_string[pos + token_end + 1]; + options_string[pos + token_end + 1] = '\0'; + value = GetVariable(pset.vars, options_string + pos + 1); + if (!value) + value = ""; + return_val = xstrdup(value); + options_string[pos + token_end + 1] = save_char; + *string = &options_string[pos + token_end + 1]; + return return_val; + } + + /* + * Next command + */ + case '\\': + *string = options_string + pos; + return NULL; + break; + + /* + * A normal word + */ + default: + { + size_t token_end; + char *cp; + + token_end = strcspn(&options_string[pos], " \t"); + return_val = malloc(token_end + 1); + if (!return_val) + { + psql_error("out of memory\n"); + exit(EXIT_FAILURE); + } + strncpy(return_val, &options_string[pos], token_end); + return_val[token_end] = 0; + + if (type == OT_SQLID) + for (cp = return_val; *cp; cp += PQmblen(cp, pset.encoding)) + if (isascii(*cp)) + *cp = tolower(*cp); + + *string = &options_string[pos + token_end]; + return return_val; + } + + } } @@ -1066,7 +1092,7 @@ unescape(const unsigned char *source, size_t len) exit(EXIT_FAILURE); } - for (p = source; p-source < len && *p; p += PQmblen(p, pset.encoding)) + for (p = source; p - source < len && *p; p += PQmblen(p, pset.encoding)) { if (esc) { @@ -1152,12 +1178,12 @@ do_connect(const char *new_dbname, const char *new_user) bool need_pass; bool success = false; - /* Delete variables (in case we fail before setting them anew) */ - SetVariable(pset.vars, "DBNAME", NULL); - SetVariable(pset.vars, "USER", NULL); - SetVariable(pset.vars, "HOST", NULL); - SetVariable(pset.vars, "PORT", NULL); - SetVariable(pset.vars, "ENCODING", NULL); + /* Delete variables (in case we fail before setting them anew) */ + SetVariable(pset.vars, "DBNAME", NULL); + SetVariable(pset.vars, "USER", NULL); + SetVariable(pset.vars, "HOST", NULL); + SetVariable(pset.vars, "PORT", NULL); + SetVariable(pset.vars, "ENCODING", NULL); /* If dbname is "" then use old name, else new one (even if NULL) */ if (oldconn && new_dbname && PQdb(oldconn) && strcmp(new_dbname, "") == 0) @@ -1166,7 +1192,7 @@ do_connect(const char *new_dbname, const char *new_user) dbparam = new_dbname; /* If user is "" then use the old one */ - if (new_user && PQuser(oldconn) && strcmp(new_user, "")==0) + if (new_user && PQuser(oldconn) && strcmp(new_user, "") == 0) userparam = PQuser(oldconn); else userparam = new_user; @@ -1187,7 +1213,7 @@ do_connect(const char *new_dbname, const char *new_user) { need_pass = false; pset.db = PQsetdbLogin(PQhost(oldconn), PQport(oldconn), - NULL, NULL, dbparam, userparam, pwparam); + NULL, NULL, dbparam, userparam, pwparam); if (PQstatus(pset.db) == CONNECTION_BAD && strcmp(PQerrorMessage(pset.db), "fe_sendauth: no password supplied\n") == 0) @@ -1207,27 +1233,30 @@ do_connect(const char *new_dbname, const char *new_user) */ if (!pset.db || PQstatus(pset.db) == CONNECTION_BAD) { - if (pset.cur_cmd_interactive) - { - psql_error("%s", PQerrorMessage(pset.db)); - PQfinish(pset.db); - if (oldconn) - { - fputs("Previous connection kept\n", stderr); - pset.db = oldconn; - } - else - pset.db = NULL; - } - else - { - /* we don't want unpredictable things to - * happen in scripting mode */ - psql_error("\\connect: %s", PQerrorMessage(pset.db)); - PQfinish(pset.db); + if (pset.cur_cmd_interactive) + { + psql_error("%s", PQerrorMessage(pset.db)); + PQfinish(pset.db); + if (oldconn) + { + fputs("Previous connection kept\n", stderr); + pset.db = oldconn; + } + else + pset.db = NULL; + } + else + { + + /* + * we don't want unpredictable things to happen in scripting + * mode + */ + psql_error("\\connect: %s", PQerrorMessage(pset.db)); + PQfinish(pset.db); if (oldconn) PQfinish(oldconn); - pset.db = NULL; + pset.db = NULL; } } else @@ -1238,7 +1267,8 @@ do_connect(const char *new_dbname, const char *new_user) printf("You are now connected to database %s.\n", dbparam); else if (dbparam != new_dbname) /* no new db */ printf("You are now connected as new user %s.\n", new_user); - else /* both new */ + else +/* both new */ printf("You are now connected to database %s as user %s.\n", PQdb(pset.db), PQuser(pset.db)); } @@ -1249,17 +1279,17 @@ do_connect(const char *new_dbname, const char *new_user) success = true; } - PQsetNoticeProcessor(pset.db, NoticeProcessor, NULL); - pset.encoding = PQclientEncoding(pset.db); + PQsetNoticeProcessor(pset.db, NoticeProcessor, NULL); + pset.encoding = PQclientEncoding(pset.db); - /* Update variables */ - SetVariable(pset.vars, "DBNAME", PQdb(pset.db)); - SetVariable(pset.vars, "USER", PQuser(pset.db)); - SetVariable(pset.vars, "HOST", PQhost(pset.db)); - SetVariable(pset.vars, "PORT", PQport(pset.db)); - SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding)); + /* Update variables */ + SetVariable(pset.vars, "DBNAME", PQdb(pset.db)); + SetVariable(pset.vars, "USER", PQuser(pset.db)); + SetVariable(pset.vars, "HOST", PQhost(pset.db)); + SetVariable(pset.vars, "PORT", PQport(pset.db)); + SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding)); - pset.issuper = test_superuser(PQuser(pset.db)); + pset.issuper = test_superuser(PQuser(pset.db)); return success; } @@ -1271,25 +1301,25 @@ do_connect(const char *new_dbname, const char *new_user) * (Is used to set up the prompt right.) */ bool -test_superuser(const char * username) +test_superuser(const char *username) { - PGresult *res; - char buf[64 + NAMEDATALEN]; - bool answer; - - if (!username) - return false; - - sprintf(buf, "SELECT usesuper FROM pg_user WHERE usename = '%.*s'", NAMEDATALEN, username); - res = PSQLexec(buf); - - answer = - (PQntuples(res)>0 && PQnfields(res)>0 - && !PQgetisnull(res,0,0) - && PQgetvalue(res,0,0) - && strcmp(PQgetvalue(res,0,0), "t")==0); - PQclear(res); - return answer; + PGresult *res; + char buf[64 + NAMEDATALEN]; + bool answer; + + if (!username) + return false; + + sprintf(buf, "SELECT usesuper FROM pg_user WHERE usename = '%.*s'", NAMEDATALEN, username); + res = PSQLexec(buf); + + answer = + (PQntuples(res) > 0 && PQnfields(res) > 0 + && !PQgetisnull(res, 0, 0) + && PQgetvalue(res, 0, 0) + && strcmp(PQgetvalue(res, 0, 0), "t") == 0); + PQclear(res); + return answer; } @@ -1330,8 +1360,8 @@ editFile(const char *fname) sprintf(sys, "exec %s %s", editorName, fname); result = system(sys); if (result == -1) - psql_error("could not start editor %s\n", editorName); - else if (result == 127) + psql_error("could not start editor %s\n", editorName); + else if (result == 127) psql_error("could not start /bin/sh\n"); free(sys); @@ -1362,11 +1392,11 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf) /* make a temp file to edit */ #ifndef WIN32 mode_t oldumask; - const char *tmpdirenv = getenv("TMPDIR"); + const char *tmpdirenv = getenv("TMPDIR"); sprintf(fnametmp, "%s/psql.edit.%ld.%ld", - tmpdirenv ? tmpdirenv : "/tmp", - (long) geteuid(), (long) getpid()); + tmpdirenv ? tmpdirenv : "/tmp", + (long) geteuid(), (long) getpid()); #else GetTempFileName(".", "psql", 0, fnametmp); #endif @@ -1382,7 +1412,7 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf) if (!stream) { - psql_error("couldn't open temp file %s: %s\n", fname, strerror(errno)); + psql_error("couldn't open temp file %s: %s\n", fname, strerror(errno)); error = true; } else @@ -1397,7 +1427,7 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf) if (fwrite(query_buf->data, 1, ql, stream) != ql) { - psql_error("%s: %s\n", fname, strerror(errno)); + psql_error("%s: %s\n", fname, strerror(errno)); fclose(stream); remove(fname); error = true; @@ -1410,7 +1440,7 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf) #ifndef WIN32 if (!error && stat(fname, &before) != 0) { - psql_error("%s: %s\n", fname, strerror(errno)); + psql_error("%s: %s\n", fname, strerror(errno)); error = true; } #endif @@ -1422,7 +1452,7 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf) #ifndef WIN32 if (!error && stat(fname, &after) != 0) { - psql_error("%s: %s\n", fname, strerror(errno)); + psql_error("%s: %s\n", fname, strerror(errno)); error = true; } @@ -1435,7 +1465,7 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf) stream = fopen(fname, "r"); if (!stream) { - psql_error("%s: %s\n", fname, strerror(errno)); + psql_error("%s: %s\n", fname, strerror(errno)); error = true; } else @@ -1444,29 +1474,29 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf) char line[1024]; resetPQExpBuffer(query_buf); - while (fgets(line, 1024, stream)) + while (fgets(line, 1024, stream)) appendPQExpBufferStr(query_buf, line); - if (ferror(stream)) - { - psql_error("%s: %s\n", fname, strerror(errno)); - error = true; - } + if (ferror(stream)) + { + psql_error("%s: %s\n", fname, strerror(errno)); + error = true; + } fclose(stream); } - } + } - /* remove temp file */ + /* remove temp file */ if (!filename_arg) - { - if (remove(fname)==-1) - { - psql_error("%s: %s\n", fname, strerror(errno)); - error=true; - } - } + { + if (remove(fname) == -1) + { + psql_error("%s: %s\n", fname, strerror(errno)); + error = true; + } + } return !error; } @@ -1484,7 +1514,7 @@ process_file(char *filename) { FILE *fd; int result; - char *oldfilename; + char *oldfilename; if (!filename) return false; @@ -1493,12 +1523,12 @@ process_file(char *filename) if (!fd) { - psql_error("%s: %s\n", filename, strerror(errno)); + psql_error("%s: %s\n", filename, strerror(errno)); return false; } - oldfilename = pset.inputfile; - pset.inputfile = filename; + oldfilename = pset.inputfile; + pset.inputfile = filename; result = MainLoop(fd); fclose(fd); pset.inputfile = oldfilename; @@ -1537,7 +1567,7 @@ _align2string(enum printFormat in) bool -do_pset(const char *param, const char *value, printQueryOpt * popt, bool quiet) +do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet) { size_t vallen = 0; @@ -1624,12 +1654,13 @@ do_pset(const char *param, const char *value, printQueryOpt * popt, bool quiet) free(popt->topt.recordSep); popt->topt.recordSep = xstrdup(value); } - if (!quiet) { - if (strcmp(popt->topt.recordSep, "\n")==0) - printf("Record separator is <newline>."); - else - printf("Record separator is '%s'.\n", popt->topt.recordSep); - } + if (!quiet) + { + if (strcmp(popt->topt.recordSep, "\n") == 0) + printf("Record separator is <newline>."); + else + printf("Record separator is '%s'.\n", popt->topt.recordSep); + } } /* toggle between full and barebones format */ @@ -1723,13 +1754,14 @@ do_shell(const char *command) shellName = DEFAULT_SHELL; sys = malloc(strlen(shellName) + 16); - if (!sys) { - psql_error("out of memory\n"); - if (pset.cur_cmd_interactive) - return false; - else - exit(EXIT_FAILURE); - } + if (!sys) + { + psql_error("out of memory\n"); + if (pset.cur_cmd_interactive) + return false; + else + exit(EXIT_FAILURE); + } sprintf(sys, "exec %s", shellName); result = system(sys); free(sys); @@ -1739,7 +1771,7 @@ do_shell(const char *command) if (result == 127 || result == -1) { - psql_error("\\!: failed\n"); + psql_error("\\!: failed\n"); return false; } return true; diff --git a/src/bin/psql/command.h b/src/bin/psql/command.h index 1fec5346faa..f719d2aa206 100644 --- a/src/bin/psql/command.h +++ b/src/bin/psql/command.h @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/command.h,v 1.9 2000/02/20 14:28:20 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/command.h,v 1.10 2000/04/12 17:16:22 momjian Exp $ */ #ifndef COMMAND_H #define COMMAND_H @@ -23,24 +23,22 @@ typedef enum _backslashResult CMD_NEWEDIT, /* query buffer was changed (e.g., via \e) */ CMD_ERROR /* the execution of the backslash command * resulted in an error */ -} backslashResult; +} backslashResult; -backslashResult -HandleSlashCmds(const char *line, +backslashResult HandleSlashCmds(const char *line, PQExpBuffer query_buf, const char **end_of_cmd); int -process_file(char *filename); + process_file(char *filename); bool -test_superuser(const char * username); + test_superuser(const char *username); -bool -do_pset(const char *param, +bool do_pset(const char *param, const char *value, - printQueryOpt * popt, + printQueryOpt *popt, bool quiet); -#endif /* COMMAND_H */ +#endif /* COMMAND_H */ diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c index fbf6950ffd3..d3551c5accc 100644 --- a/src/bin/psql/common.c +++ b/src/bin/psql/common.c @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/common.c,v 1.19 2000/03/05 13:30:19 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/common.c,v 1.20 2000/04/12 17:16:22 momjian Exp $ */ #include "postgres.h" #include "common.h" @@ -21,7 +21,7 @@ #include <unistd.h> /* for write() */ #include <setjmp.h> #else -#include <io.h> /* for _write() */ +#include <io.h> /* for _write() */ #include <win32.h> #endif @@ -49,13 +49,13 @@ xstrdup(const char *string) if (!string) { fprintf(stderr, "%s: xstrdup: cannot duplicate null pointer (internal error)\n", - pset.progname); + pset.progname); exit(EXIT_FAILURE); } tmp = strdup(string); if (!tmp) { - psql_error("out of memory\n"); + psql_error("out of memory\n"); exit(EXIT_FAILURE); } return tmp; @@ -125,23 +125,23 @@ setQFout(const char *fname) /* * Error reporting for scripts. Errors should look like - * psql:filename:lineno: message + * psql:filename:lineno: message * */ void -psql_error(const char *fmt, ...) +psql_error(const char *fmt,...) { - va_list ap; + va_list ap; - fflush(stdout); - if (pset.queryFout!=stdout) - fflush(pset.queryFout); + fflush(stdout); + if (pset.queryFout != stdout) + fflush(pset.queryFout); - if (pset.inputfile) - fprintf(stderr, "%s:%s:%u: ", pset.progname, pset.inputfile, pset.lineno); - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); + if (pset.inputfile) + fprintf(stderr, "%s:%s:%u: ", pset.progname, pset.inputfile, pset.lineno); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); } @@ -150,10 +150,10 @@ psql_error(const char *fmt, ...) * for backend NOTICES */ void -NoticeProcessor(void * arg, const char * message) +NoticeProcessor(void *arg, const char *message) { - (void)arg; /* not used */ - psql_error("%s", message); + (void) arg; /* not used */ + psql_error("%s", message); } @@ -181,6 +181,7 @@ simple_prompt(const char *prompt, int maxlen, bool echo) #ifdef HAVE_TERMIOS_H struct termios t_orig, t; + #endif destination = (char *) malloc(maxlen + 2); @@ -189,7 +190,7 @@ simple_prompt(const char *prompt, int maxlen, bool echo) if (prompt) fputs(prompt, stderr); - prompt_state = true; + prompt_state = true; #ifdef HAVE_TERMIOS_H if (!echo) @@ -211,7 +212,7 @@ simple_prompt(const char *prompt, int maxlen, bool echo) } #endif - prompt_state = false; + prompt_state = false; length = strlen(destination); if (length > 0 && destination[length - 1] != '\n') @@ -244,7 +245,7 @@ simple_prompt(const char *prompt, int maxlen, bool echo) * facilities in a signal handler. */ -PGconn *cancelConn; +PGconn *cancelConn; volatile bool cancel_pressed; #ifndef WIN32 @@ -254,14 +255,14 @@ volatile bool cancel_pressed; void handle_sigint(SIGNAL_ARGS) { - /* Don't muck around if copying in or prompting for a password. */ - if ((copy_in_state && pset.cur_cmd_interactive) || prompt_state) - return; + /* Don't muck around if copying in or prompting for a password. */ + if ((copy_in_state && pset.cur_cmd_interactive) || prompt_state) + return; if (cancelConn == NULL) - siglongjmp(main_loop_jmp, 1); + siglongjmp(main_loop_jmp, 1); - cancel_pressed = true; + cancel_pressed = true; if (PQrequestCancel(cancelConn)) write_stderr("Cancel request sent\n"); @@ -271,7 +272,8 @@ handle_sigint(SIGNAL_ARGS) write_stderr(PQerrorMessage(cancelConn)); } } -#endif /* not WIN32 */ + +#endif /* not WIN32 */ /* @@ -288,7 +290,7 @@ PSQLexec(const char *query) if (!pset.db) { - psql_error("You are currently not connected to a database.\n"); + psql_error("You are currently not connected to a database.\n"); return NULL; } @@ -304,19 +306,19 @@ PSQLexec(const char *query) cancelConn = pset.db; res = PQexec(pset.db, query); - if (PQresultStatus(res) == PGRES_COPY_IN) - copy_in_state = true; - /* keep cancel connection for copy out state */ - if (PQresultStatus(res) != PGRES_COPY_OUT) - cancelConn = NULL; + if (PQresultStatus(res) == PGRES_COPY_IN) + copy_in_state = true; + /* keep cancel connection for copy out state */ + if (PQresultStatus(res) != PGRES_COPY_OUT) + cancelConn = NULL; if (PQstatus(pset.db) == CONNECTION_BAD) { - if (!pset.cur_cmd_interactive) - { - psql_error("connection to server was lost\n"); - exit(EXIT_BADCONN); - } + if (!pset.cur_cmd_interactive) + { + psql_error("connection to server was lost\n"); + exit(EXIT_BADCONN); + } fputs("The connection to the server was lost. Attempting reset: ", stderr); PQreset(pset.db); if (PQstatus(pset.db) == CONNECTION_BAD) @@ -325,11 +327,11 @@ PSQLexec(const char *query) PQfinish(pset.db); PQclear(res); pset.db = NULL; - SetVariable(pset.vars, "DBNAME", NULL); - SetVariable(pset.vars, "HOST", NULL); - SetVariable(pset.vars, "PORT", NULL); - SetVariable(pset.vars, "USER", NULL); - SetVariable(pset.vars, "ENCODING", NULL); + SetVariable(pset.vars, "DBNAME", NULL); + SetVariable(pset.vars, "HOST", NULL); + SetVariable(pset.vars, "PORT", NULL); + SetVariable(pset.vars, "USER", NULL); + SetVariable(pset.vars, "ENCODING", NULL); return NULL; } else @@ -344,7 +346,7 @@ PSQLexec(const char *query) return res; else { - psql_error("%s", PQerrorMessage(pset.db)); + psql_error("%s", PQerrorMessage(pset.db)); PQclear(res); return NULL; } @@ -373,7 +375,7 @@ SendQuery(const char *query) if (!pset.db) { - psql_error("You are currently not connected to a database.\n"); + psql_error("You are currently not connected to a database.\n"); return false; } @@ -382,28 +384,29 @@ SendQuery(const char *query) char buf[3]; printf("***(Single step mode: Verify query)*********************************************\n" - "%s\n" - "***(press return to proceed or enter x and return to cancel)********************\n", - query); + "%s\n" + "***(press return to proceed or enter x and return to cancel)********************\n", + query); fflush(stdout); fgets(buf, 3, stdin); if (buf[0] == 'x') return false; } - else - { - const char * var = GetVariable(pset.vars, "ECHO"); - if (var && strncmp(var, "queries", strlen(var))==0) - puts(query); - } + else + { + const char *var = GetVariable(pset.vars, "ECHO"); + + if (var && strncmp(var, "queries", strlen(var)) == 0) + puts(query); + } cancelConn = pset.db; results = PQexec(pset.db, query); - if (PQresultStatus(results) == PGRES_COPY_IN) - copy_in_state = true; - /* keep cancel connection for copy out state */ - if (PQresultStatus(results) != PGRES_COPY_OUT) - cancelConn = NULL; + if (PQresultStatus(results) == PGRES_COPY_IN) + copy_in_state = true; + /* keep cancel connection for copy out state */ + if (PQresultStatus(results) != PGRES_COPY_OUT) + cancelConn = NULL; if (results == NULL) { @@ -415,14 +418,16 @@ SendQuery(const char *query) switch (PQresultStatus(results)) { case PGRES_TUPLES_OK: - /* write output to \g argument, if any */ + /* write output to \g argument, if any */ if (pset.gfname) { - FILE * queryFout_copy = pset.queryFout; - bool queryFoutPipe_copy = pset.queryFoutPipe; - pset.queryFout = NULL; /* so it doesn't get closed */ + FILE *queryFout_copy = pset.queryFout; + bool queryFoutPipe_copy = pset.queryFoutPipe; - /* open file/pipe */ + pset.queryFout = NULL; /* so it doesn't get + * closed */ + + /* open file/pipe */ if (!setQFout(pset.gfname)) { success = false; @@ -438,7 +443,7 @@ SendQuery(const char *query) pset.gfname = NULL; pset.queryFout = queryFout_copy; - pset.queryFoutPipe = queryFoutPipe_copy; + pset.queryFoutPipe = queryFoutPipe_copy; success = true; break; @@ -453,16 +458,16 @@ SendQuery(const char *query) success = true; break; case PGRES_COMMAND_OK: - { - char buf[10]; + { + char buf[10]; - success = true; - sprintf(buf, "%u", (unsigned int)PQoidValue(results)); - if (!QUIET()) - fprintf(pset.queryFout, "%s\n", PQcmdStatus(results)); - SetVariable(pset.vars, "LASTOID", buf); - break; - } + success = true; + sprintf(buf, "%u", (unsigned int) PQoidValue(results)); + if (!QUIET()) + fprintf(pset.queryFout, "%s\n", PQcmdStatus(results)); + SetVariable(pset.vars, "LASTOID", buf); + break; + } case PGRES_COPY_OUT: success = handleCopyOut(pset.db, pset.queryFout); break; @@ -480,19 +485,19 @@ SendQuery(const char *query) case PGRES_FATAL_ERROR: case PGRES_BAD_RESPONSE: success = false; - psql_error("%s", PQerrorMessage(pset.db)); + psql_error("%s", PQerrorMessage(pset.db)); break; } - fflush(pset.queryFout); + fflush(pset.queryFout); if (PQstatus(pset.db) == CONNECTION_BAD) { - if (!pset.cur_cmd_interactive) - { - psql_error("connection to server was lost\n"); - exit(EXIT_BADCONN); - } + if (!pset.cur_cmd_interactive) + { + psql_error("connection to server was lost\n"); + exit(EXIT_BADCONN); + } fputs("The connection to the server was lost. Attempting reset: ", stderr); PQreset(pset.db); if (PQstatus(pset.db) == CONNECTION_BAD) @@ -501,29 +506,29 @@ SendQuery(const char *query) PQfinish(pset.db); PQclear(results); pset.db = NULL; - SetVariable(pset.vars, "DBNAME", NULL); - SetVariable(pset.vars, "HOST", NULL); - SetVariable(pset.vars, "PORT", NULL); - SetVariable(pset.vars, "USER", NULL); - SetVariable(pset.vars, "ENCODING", NULL); + SetVariable(pset.vars, "DBNAME", NULL); + SetVariable(pset.vars, "HOST", NULL); + SetVariable(pset.vars, "PORT", NULL); + SetVariable(pset.vars, "USER", NULL); + SetVariable(pset.vars, "ENCODING", NULL); return false; } else fputs("Succeeded.\n", stderr); } - + /* check for asynchronous notification returns */ while ((notify = PQnotifies(pset.db)) != NULL) { fprintf(pset.queryFout, "Asynchronous NOTIFY '%s' from backend with pid '%d' received.\n", notify->relname, notify->be_pid); free(notify); - fflush(pset.queryFout); + fflush(pset.queryFout); } if (results) PQclear(results); - } + } return success; } diff --git a/src/bin/psql/common.h b/src/bin/psql/common.h index 2f343e425a6..b2600060e1a 100644 --- a/src/bin/psql/common.h +++ b/src/bin/psql/common.h @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/common.h,v 1.9 2000/03/05 13:30:19 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/common.h,v 1.10 2000/04/12 17:16:22 momjian Exp $ */ #ifndef COMMON_H #define COMMON_H @@ -13,28 +13,32 @@ #include "pqsignal.h" #include "libpq-fe.h" -char * xstrdup(const char *string); +char *xstrdup(const char *string); bool setQFout(const char *fname); #ifndef __GNUC__ -void psql_error(const char *fmt, ...); +void psql_error(const char *fmt,...); + #else /* This checks the format string for consistency. */ -void psql_error(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); +void psql_error(const char *fmt,...) __attribute__((format(printf, 1, 2))); + #endif -void NoticeProcessor(void * arg, const char * message); +void NoticeProcessor(void *arg, const char *message); -char * simple_prompt(const char *prompt, int maxlen, bool echo); +char *simple_prompt(const char *prompt, int maxlen, bool echo); extern volatile bool cancel_pressed; extern PGconn *cancelConn; + #ifndef WIN32 -void handle_sigint(SIGNAL_ARGS); -#endif /* not WIN32 */ +void handle_sigint(SIGNAL_ARGS); + +#endif /* not WIN32 */ -PGresult * PSQLexec(const char *query); +PGresult *PSQLexec(const char *query); bool SendQuery(const char *query); diff --git a/src/bin/psql/copy.c b/src/bin/psql/copy.c index 9f338979f18..7e08a1d6b16 100644 --- a/src/bin/psql/copy.c +++ b/src/bin/psql/copy.c @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/copy.c,v 1.12 2000/03/01 21:09:58 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/copy.c,v 1.13 2000/04/12 17:16:22 momjian Exp $ */ #include "postgres.h" #include "copy.h" @@ -28,7 +28,7 @@ #define strcasecmp(x,y) stricmp(x,y) #endif -bool copy_in_state; +bool copy_in_state; /* * parse_slash_copy @@ -43,12 +43,12 @@ bool copy_in_state; struct copy_options { char *table; - char *file; /* NULL = stdin/stdout */ + char *file; /* NULL = stdin/stdout */ bool from; bool binary; bool oids; char *delim; - char *null; + char *null; }; @@ -60,7 +60,7 @@ free_copy_options(struct copy_options * ptr) free(ptr->table); free(ptr->file); free(ptr->delim); - free(ptr->null); + free(ptr->null); free(ptr); } @@ -88,8 +88,8 @@ parse_slash_copy(const char *args) else { #ifdef NOT_USED - /* this is not implemented yet */ - if (!quote && strcasecmp(token, "binary") == 0) + /* this is not implemented yet */ + if (!quote && strcasecmp(token, "binary") == 0) { result->binary = true; token = strtokx(NULL, " \t", "\"", '\\', "e, NULL, pset.encoding); @@ -142,9 +142,9 @@ parse_slash_copy(const char *args) token = strtokx(NULL, " \t", "'", '\\', "e, NULL, pset.encoding); if (!token) error = true; - else if (!quote && (strcasecmp(token, "stdin")==0 || strcasecmp(token, "stdout")==0)) - result->file = NULL; - else + else if (!quote && (strcasecmp(token, "stdin") == 0 || strcasecmp(token, "stdout") == 0)) + result->file = NULL; + else result->file = xstrdup(token); } @@ -162,36 +162,36 @@ parse_slash_copy(const char *args) { token = strtokx(NULL, " \t", "'", '\\', NULL, NULL, pset.encoding); if (token) - { + { result->delim = xstrdup(token); - token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, pset.encoding); - } + token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, pset.encoding); + } else error = true; } } - if (!error && token) - { - if (strcasecmp(token, "with") == 0) - { - token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, pset.encoding); - if (!token || strcasecmp(token, "null") != 0) - error = true; - else - { - token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, pset.encoding); - if (!token || strcasecmp(token, "as") != 0) - error = true; - else - { - token = strtokx(NULL, " \t", "'", '\\', NULL, NULL, pset.encoding); - if (token) - result->null = xstrdup(token); - } - } - } - } + if (!error && token) + { + if (strcasecmp(token, "with") == 0) + { + token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, pset.encoding); + if (!token || strcasecmp(token, "null") != 0) + error = true; + else + { + token = strtokx(NULL, " \t", NULL, '\\', NULL, NULL, pset.encoding); + if (!token || strcasecmp(token, "as") != 0) + error = true; + else + { + token = strtokx(NULL, " \t", "'", '\\', NULL, NULL, pset.encoding); + if (token) + result->null = xstrdup(token); + } + } + } + } } } @@ -199,10 +199,10 @@ parse_slash_copy(const char *args) if (error) { - psql_error("\\copy: parse error at %s%s%s\n", - token ? "'" : "", - token ? token : "end of line", - token ? "'" : ""); + psql_error("\\copy: parse error at %s%s%s\n", + token ? "'" : "", + token ? token : "end of line", + token ? "'" : ""); free_copy_options(result); return NULL; } @@ -234,7 +234,7 @@ do_copy(const char *args) strcpy(query, "COPY "); if (options->binary) - strcat(query, "BINARY "); + strcat(query, "BINARY "); strcat(query, "\""); strncat(query, options->table, NAMEDATALEN); @@ -255,32 +255,32 @@ do_copy(const char *args) strcat(query, "'"); } - if (options->null) - { + if (options->null) + { strcat(query, " WITH NULL AS '"); strcat(query, options->null); strcat(query, "'"); } if (options->from) - { - if (options->file) - copystream = fopen(options->file, "r"); - else - copystream = stdin; - } + { + if (options->file) + copystream = fopen(options->file, "r"); + else + copystream = stdin; + } else - { - if (options->file) - copystream = fopen(options->file, "w"); - else - copystream = stdout; - } + { + if (options->file) + copystream = fopen(options->file, "w"); + else + copystream = stdout; + } if (!copystream) { - psql_error("%s: %s\n", - options->file, strerror(errno)); + psql_error("%s: %s\n", + options->file, strerror(errno)); free_copy_options(options); return false; } @@ -299,7 +299,7 @@ do_copy(const char *args) case PGRES_FATAL_ERROR: case PGRES_BAD_RESPONSE: success = false; - psql_error("\\copy: %s", PQerrorMessage(pset.db)); + psql_error("\\copy: %s", PQerrorMessage(pset.db)); break; default: success = false; @@ -308,8 +308,8 @@ do_copy(const char *args) PQclear(result); - if (copystream != stdout && copystream != stdin) - fclose(copystream); + if (copystream != stdout && copystream != stdin) + fclose(copystream); free_copy_options(options); return success; } @@ -335,7 +335,7 @@ handleCopyOut(PGconn *conn, FILE *copystream) char copybuf[COPYBUFSIZ]; int ret; - assert(cancelConn); + assert(cancelConn); while (!copydone) { @@ -365,8 +365,8 @@ handleCopyOut(PGconn *conn, FILE *copystream) } fflush(copystream); ret = !PQendcopy(conn); - cancelConn = NULL; - return ret; + cancelConn = NULL; + return ret; } @@ -394,15 +394,15 @@ handleCopyIn(PGconn *conn, FILE *copystream, const char *prompt) char *s; int bufleft; int c = 0; - int ret; + int ret; #ifdef USE_ASSERT_CHECKING - assert(copy_in_state); + assert(copy_in_state); #endif if (prompt) /* disable prompt if not interactive */ { - if (! isatty(fileno(copystream))) + if (!isatty(fileno(copystream))) prompt = NULL; } @@ -419,7 +419,7 @@ handleCopyIn(PGconn *conn, FILE *copystream, const char *prompt) while (!linedone) { /* for each bufferload in line ... */ s = copybuf; - for (bufleft = COPYBUFSIZ-1; bufleft > 0; bufleft--) + for (bufleft = COPYBUFSIZ - 1; bufleft > 0; bufleft--) { c = getc(copystream); if (c == '\n' || c == EOF) @@ -434,8 +434,8 @@ handleCopyIn(PGconn *conn, FILE *copystream, const char *prompt) { PQputline(conn, "\\."); copydone = true; - if (pset.cur_cmd_interactive) - puts("\\."); + if (pset.cur_cmd_interactive) + puts("\\."); break; } PQputline(conn, copybuf); @@ -452,6 +452,6 @@ handleCopyIn(PGconn *conn, FILE *copystream, const char *prompt) PQputline(conn, "\n"); } ret = !PQendcopy(conn); - copy_in_state = false; - return ret; + copy_in_state = false; + return ret; } diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index 631a04b336d..75c9df37143 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.18 2000/02/26 18:31:25 tgl Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.19 2000/04/12 17:16:22 momjian Exp $ */ #include "postgres.h" #include "describe.h" @@ -45,10 +45,10 @@ describeAggregates(const char *name) */ strcpy(buf, "SELECT a.aggname AS \"Name\", t.typname AS \"Type\",\n" - " obj_description(a.oid) as \"Description\"\n" - "FROM pg_aggregate a, pg_type t\n" - "WHERE a.aggbasetype = t.oid\n" - ); + " obj_description(a.oid) as \"Description\"\n" + "FROM pg_aggregate a, pg_type t\n" + "WHERE a.aggbasetype = t.oid\n" + ); if (name) { @@ -60,10 +60,10 @@ describeAggregates(const char *name) strcat(buf, "UNION\n" "SELECT a.aggname AS \"Name\", '(all types)' as \"Type\",\n" - " obj_description(a.oid) as \"Description\"\n" + " obj_description(a.oid) as \"Description\"\n" "FROM pg_aggregate a\n" - "WHERE a.aggbasetype = 0\n" - ); + "WHERE a.aggbasetype = 0\n" + ); if (name) { @@ -103,21 +103,21 @@ describeFunctions(const char *name, bool verbose) * arguments, but have no types defined for those arguments */ strcpy(buf, - "SELECT t.typname as \"Result\", p.proname as \"Function\",\n" + "SELECT t.typname as \"Result\", p.proname as \"Function\",\n" " oidvectortypes(p.proargtypes) as \"Arguments\""); - if (verbose) - strcat(buf, ",\n u.usename as \"Owner\", l.lanname as \"Language\", p.prosrc as \"Source\",\n" - " obj_description(p.oid) as \"Description\""); + if (verbose) + strcat(buf, ",\n u.usename as \"Owner\", l.lanname as \"Language\", p.prosrc as \"Source\",\n" + " obj_description(p.oid) as \"Description\""); - if (!verbose) - strcat(buf, - "\nFROM pg_proc p, pg_type t\n" - "WHERE p.prorettype = t.oid and (pronargs = 0 or oidvectortypes(p.proargtypes) != '')\n"); - else - strcat(buf, - "\nFROM pg_proc p, pg_type t, pg_language l, pg_user u\n" - "WHERE p.prorettype = t.oid AND p.prolang = l.oid AND p.proowner = u.usesysid\n" - " AND (pronargs = 0 or oidvectortypes(p.proargtypes) != '')\n"); + if (!verbose) + strcat(buf, + "\nFROM pg_proc p, pg_type t\n" + "WHERE p.prorettype = t.oid and (pronargs = 0 or oidvectortypes(p.proargtypes) != '')\n"); + else + strcat(buf, + "\nFROM pg_proc p, pg_type t, pg_language l, pg_user u\n" + "WHERE p.prorettype = t.oid AND p.prolang = l.oid AND p.proowner = u.usesysid\n" + " AND (pronargs = 0 or oidvectortypes(p.proargtypes) != '')\n"); if (name) { @@ -154,13 +154,14 @@ describeTypes(const char *name, bool verbose) printQueryOpt myopt = pset.popt; strcpy(buf, "SELECT t.typname AS \"Type\""); - if (verbose) - strcat(buf, ",\n (CASE WHEN t.typlen = -1 THEN 'var'::text ELSE t.typlen::text END) as \"Size\""); + if (verbose) + strcat(buf, ",\n (CASE WHEN t.typlen = -1 THEN 'var'::text ELSE t.typlen::text END) as \"Size\""); strcat(buf, ",\n obj_description(t.oid) as \"Description\""); - /* - * do not include array types (start with underscore), - * do not include user relations (typrelid!=0) - */ + + /* + * do not include array types (start with underscore), do not include + * user relations (typrelid!=0) + */ strcat(buf, "\nFROM pg_type t\nWHERE t.typrelid = 0 AND t.typname !~ '^_.*'\n"); if (name) @@ -196,12 +197,12 @@ describeOperators(const char *name) printQueryOpt myopt = pset.popt; strcpy(buf, - "SELECT o.oprname AS \"Op\",\n" + "SELECT o.oprname AS \"Op\",\n" " t1.typname AS \"Left arg\",\n" " t2.typname AS \"Right arg\",\n" " t0.typname AS \"Result\",\n" " obj_description(p.oid) as \"Description\"\n" - "FROM pg_proc p, pg_type t0,\n" + "FROM pg_proc p, pg_type t0,\n" " pg_type t1, pg_type t2,\n" " pg_operator o\n" "WHERE p.prorettype = t0.oid AND\n" @@ -221,8 +222,8 @@ describeOperators(const char *name) " ''::name AS \"Left arg\",\n" " t1.typname AS \"Right arg\",\n" " t0.typname AS \"Result\",\n" - " obj_description(p.oid) as \"Description\"\n" - "FROM pg_operator o, pg_proc p, pg_type t0, pg_type t1\n" + " obj_description(p.oid) as \"Description\"\n" + "FROM pg_operator o, pg_proc p, pg_type t0, pg_type t1\n" "WHERE RegprocToOid(o.oprcode) = p.oid AND\n" " o.oprresult = t0.oid AND\n" " o.oprkind = 'l' AND\n" @@ -239,8 +240,8 @@ describeOperators(const char *name) " t1.typname AS \"Left arg\",\n" " ''::name AS \"Right arg\",\n" " t0.typname AS \"Result\",\n" - " obj_description(p.oid) as \"Description\"\n" - "FROM pg_operator o, pg_proc p, pg_type t0, pg_type t1\n" + " obj_description(p.oid) as \"Description\"\n" + "FROM pg_operator o, pg_proc p, pg_type t0, pg_type t1\n" "WHERE RegprocToOid(o.oprcode) = p.oid AND\n" " o.oprresult = t0.oid AND\n" " o.oprkind = 'r' AND\n" @@ -280,7 +281,7 @@ listAllDbs(bool desc) printQueryOpt myopt = pset.popt; strcpy(buf, - "SELECT pg_database.datname as \"Database\",\n" + "SELECT pg_database.datname as \"Database\",\n" " pg_user.usename as \"Owner\""); #ifdef MULTIBYTE strcat(buf, @@ -291,11 +292,11 @@ listAllDbs(bool desc) strcat(buf, "FROM pg_database, pg_user\n" "WHERE pg_database.datdba = pg_user.usesysid\n"); - /* Also include databases that have no valid owner. */ - strcat(buf, "\nUNION\n\n"); + /* Also include databases that have no valid owner. */ + strcat(buf, "\nUNION\n\n"); strcat(buf, - "SELECT pg_database.datname as \"Database\",\n" + "SELECT pg_database.datname as \"Database\",\n" " NULL as \"Owner\""); #ifdef MULTIBYTE strcat(buf, @@ -304,9 +305,9 @@ listAllDbs(bool desc) if (desc) strcat(buf, ",\n obj_description(pg_database.oid) as \"Description\"\n"); strcat(buf, "FROM pg_database\n" - "WHERE pg_database.datdba NOT IN (SELECT usesysid FROM pg_user)\n"); + "WHERE pg_database.datdba NOT IN (SELECT usesysid FROM pg_user)\n"); - strcat(buf, "ORDER BY \"Database\""); + strcat(buf, "ORDER BY \"Database\""); res = PSQLexec(buf); if (!res) @@ -352,11 +353,11 @@ permissionsList(const char *name) if (!res) return false; - myopt.nullPrint = NULL; - sprintf(descbuf, "Access permissions for database \"%s\"", PQdb(pset.db)); - myopt.title = descbuf; + myopt.nullPrint = NULL; + sprintf(descbuf, "Access permissions for database \"%s\"", PQdb(pset.db)); + myopt.title = descbuf; - printQuery(res, &myopt, pset.queryFout); + printQuery(res, &myopt, pset.queryFout); PQclear(res); return true; @@ -408,7 +409,7 @@ objectDescription(const char *object) strcat(descbuf, "\nUNION ALL\n\n"); strcat(descbuf, "SELECT DISTINCT o.oprname as \"Name\", 'operator'::text as \"Object\", d.description as \"Description\"\n" "FROM pg_operator o, pg_description d\n" - /* must get comment via associated function */ + /* must get comment via associated function */ "WHERE RegprocToOid(o.oprcode) = d.objoid\n"); if (object) { @@ -521,25 +522,34 @@ describeTableDetails(const char *name, bool desc) char **footers = NULL; char **ptr; unsigned int cols; - struct { bool hasindex; char relkind; int16 checks; int16 triggers; bool hasrules; } tableinfo; - bool error = false; + struct + { + bool hasindex; + char relkind; + int16 checks; + int16 triggers; + bool hasrules; + } tableinfo; + bool error = false; + + /* truncate table name */ + if (strlen(name) > NAMEDATALEN) + { + char *my_name = xmalloc(NAMEDATALEN + 1); - /* truncate table name */ - if (strlen(name) > NAMEDATALEN) { - char *my_name = xmalloc(NAMEDATALEN+1); - strncpy(my_name, name, NAMEDATALEN); - my_name[NAMEDATALEN] = '\0'; - name = my_name; - } + strncpy(my_name, name, NAMEDATALEN); + my_name[NAMEDATALEN] = '\0'; + name = my_name; + } /* Get general table info */ - sprintf(buf, - "SELECT relhasindex, relkind, relchecks, reltriggers, relhasrules\n" - "FROM pg_class WHERE relname='%s'", - name); - res = PSQLexec(buf); - if (!res) - return false; + sprintf(buf, + "SELECT relhasindex, relkind, relchecks, reltriggers, relhasrules\n" + "FROM pg_class WHERE relname='%s'", + name); + res = PSQLexec(buf); + if (!res) + return false; /* Did we get anything? */ if (PQntuples(res) == 0) @@ -550,35 +560,35 @@ describeTableDetails(const char *name, bool desc) return false; } - /* FIXME: check for null pointers here? */ - tableinfo.hasindex = strcmp(PQgetvalue(res,0,0),"t")==0; - tableinfo.relkind = *(PQgetvalue(res,0,1)); - tableinfo.checks = atoi(PQgetvalue(res,0,2)); - tableinfo.triggers = atoi(PQgetvalue(res,0,3)); - tableinfo.hasrules = strcmp(PQgetvalue(res,0,4),"t")==0; - PQclear(res); + /* FIXME: check for null pointers here? */ + tableinfo.hasindex = strcmp(PQgetvalue(res, 0, 0), "t") == 0; + tableinfo.relkind = *(PQgetvalue(res, 0, 1)); + tableinfo.checks = atoi(PQgetvalue(res, 0, 2)); + tableinfo.triggers = atoi(PQgetvalue(res, 0, 3)); + tableinfo.hasrules = strcmp(PQgetvalue(res, 0, 4), "t") == 0; + PQclear(res); headers[0] = "Attribute"; headers[1] = "Type"; cols = 2; - if (tableinfo.relkind == 'r') - { - cols++; - headers[cols-1] = "Modifier"; - } + if (tableinfo.relkind == 'r') + { + cols++; + headers[cols - 1] = "Modifier"; + } if (desc) { - cols++; - headers[cols-1] = "Description"; + cols++; + headers[cols - 1] = "Description"; } - headers[cols] = NULL; + headers[cols] = NULL; - /* Get column info */ + /* Get column info */ strcpy(buf, "SELECT a.attname, t.typname, a.attlen, a.atttypmod, a.attnotnull, a.atthasdef, a.attnum"); if (desc) strcat(buf, ", obj_description(a.oid)"); @@ -593,55 +603,58 @@ describeTableDetails(const char *name, bool desc) return false; /* Check if table is a view */ - if (tableinfo.hasrules) { - PGresult *result; - sprintf(buf, "SELECT definition FROM pg_views WHERE viewname = '%s'", name); - result = PSQLexec(buf); - if (!result) - { - PQclear(res); - PQclear(result); - return false; - } - - if (PQntuples(result) > 0) - view_def = xstrdup(PQgetvalue(result, 0, 0)); - PQclear(result); - } + if (tableinfo.hasrules) + { + PGresult *result; + + sprintf(buf, "SELECT definition FROM pg_views WHERE viewname = '%s'", name); + result = PSQLexec(buf); + if (!result) + { + PQclear(res); + PQclear(result); + return false; + } + + if (PQntuples(result) > 0) + view_def = xstrdup(PQgetvalue(result, 0, 0)); + PQclear(result); + } /* Generate table cells to be printed */ cells = xmalloc((PQntuples(res) * cols + 1) * sizeof(*cells)); - cells[PQntuples(res) * cols] = NULL; /* end of list */ + cells[PQntuples(res) * cols] = NULL; /* end of list */ for (i = 0; i < PQntuples(res); i++) { int4 attypmod = atoi(PQgetvalue(res, i, 3)); const char *attype = PQgetvalue(res, i, 1); - const char *typename; - bool isarray = false; + const char *typename; + bool isarray = false; /* Name */ - cells[i * cols + 0] = PQgetvalue(res, i, 0); /* don't free this afterwards */ + cells[i * cols + 0] = PQgetvalue(res, i, 0); /* don't free this + * afterwards */ /* Type */ - if (attype[0] == '_') - { - isarray = true; - attype++; - } - /* (convert some internal type names to SQL'ish) */ - if (strcmp(attype, "int2")==0) - typename = "smallint"; - else if (strcmp(attype, "int4")==0) - typename = "integer"; - else if (strcmp(attype, "int8")==0) - typename = "bigint"; - else if (strcmp(attype, "bool")==0) - typename = "boolean"; - else - typename = attype; - /* more might need to be added when date/time types are sorted out */ + if (attype[0] == '_') + { + isarray = true; + attype++; + } + /* (convert some internal type names to SQL'ish) */ + if (strcmp(attype, "int2") == 0) + typename = "smallint"; + else if (strcmp(attype, "int4") == 0) + typename = "integer"; + else if (strcmp(attype, "int8") == 0) + typename = "bigint"; + else if (strcmp(attype, "bool") == 0) + typename = "boolean"; + else + typename = attype; + /* more might need to be added when date/time types are sorted out */ cells[i * cols + 1] = xmalloc(NAMEDATALEN + 16); if (strcmp(typename, "bpchar") == 0) @@ -667,100 +680,101 @@ describeTableDetails(const char *name, bool desc) else strcpy(cells[i * cols + 1], typename); - if (isarray) + if (isarray) strcat(cells[i * cols + 1], "[]"); /* Extra: not null and default */ /* (I'm cutting off the 'default' string at 128) */ - if (tableinfo.relkind == 'r') - { - cells[i * cols + 2] = xmalloc(128 + 128); - cells[i * cols + 2][0] = '\0'; - if (strcmp(PQgetvalue(res, i, 4), "t") == 0) - strcat(cells[i * cols + 2], "not null"); - - /* handle "default" here */ - if (strcmp(PQgetvalue(res, i, 5), "t") == 0) - { - PGresult *result; - - sprintf(buf, "SELECT substring(d.adsrc for 128) FROM pg_attrdef d, pg_class c\n" - "WHERE c.relname = '%s' AND c.oid = d.adrelid AND d.adnum = %s", - name, PQgetvalue(res, i, 6)); - - result = PSQLexec(buf); - if (!result) - error = true; - else - { - if (cells[i * cols + 2][0]) - strcat(cells[i * cols + 2], " "); - strcat(cells[i * cols + 2], "default "); - strcat(cells[i * cols + 2], PQgetvalue(result, 0, 0)); - PQclear(result); - } - } - } - - if (error) - break; - + if (tableinfo.relkind == 'r') + { + cells[i * cols + 2] = xmalloc(128 + 128); + cells[i * cols + 2][0] = '\0'; + if (strcmp(PQgetvalue(res, i, 4), "t") == 0) + strcat(cells[i * cols + 2], "not null"); + + /* handle "default" here */ + if (strcmp(PQgetvalue(res, i, 5), "t") == 0) + { + PGresult *result; + + sprintf(buf, "SELECT substring(d.adsrc for 128) FROM pg_attrdef d, pg_class c\n" + "WHERE c.relname = '%s' AND c.oid = d.adrelid AND d.adnum = %s", + name, PQgetvalue(res, i, 6)); + + result = PSQLexec(buf); + if (!result) + error = true; + else + { + if (cells[i * cols + 2][0]) + strcat(cells[i * cols + 2], " "); + strcat(cells[i * cols + 2], "default "); + strcat(cells[i * cols + 2], PQgetvalue(result, 0, 0)); + PQclear(result); + } + } + } + + if (error) + break; + /* Description */ if (desc) - cells[i * cols + cols-1] = PQgetvalue(res, i, 7); + cells[i * cols + cols - 1] = PQgetvalue(res, i, 7); } /* Make title */ title = xmalloc(22 + strlen(name)); - switch (tableinfo.relkind) { - case 'r': - if (view_def) - sprintf(title, "View \"%s\"", name); - else - sprintf(title, "Table \"%s\"", name); - break; - case 'S': - sprintf(title, "Sequence \"%s\"", name); - break; - case 'i': - sprintf(title, "Index \"%s\"", name); - break; - case 's': - sprintf(title, "Special relation \"%s\"", name); - break; - default: - sprintf(title, "?%c?", tableinfo.relkind); - } + switch (tableinfo.relkind) + { + case 'r': + if (view_def) + sprintf(title, "View \"%s\"", name); + else + sprintf(title, "Table \"%s\"", name); + break; + case 'S': + sprintf(title, "Sequence \"%s\"", name); + break; + case 'i': + sprintf(title, "Index \"%s\"", name); + break; + case 's': + sprintf(title, "Special relation \"%s\"", name); + break; + default: + sprintf(title, "?%c?", tableinfo.relkind); + } /* Make footers */ - /* Information about the index */ - if (tableinfo.relkind == 'i') - { - PGresult * result; - - sprintf(buf, "SELECT i.indisunique, i.indisprimary, a.amname\n" - "FROM pg_index i, pg_class c, pg_am a\n" - "WHERE i.indexrelid = c.oid AND c.relname = '%s' AND c.relam = a.oid", - name); - - result = PSQLexec(buf); - if (!result) - error = true; - else - { - footers = xmalloc(2 * sizeof(*footers)); - footers[0] = xmalloc(NAMEDATALEN + 32); - sprintf(footers[0], "%s%s", - strcmp(PQgetvalue(result, 0, 0), "t")==0 ? "unique " : "", - PQgetvalue(result, 0, 2) - ); - if (strcmp(PQgetvalue(result, 0, 1), "t")==0) - strcat(footers[0], " (primary key)"); - footers[1] = NULL; - } - } - /* Information about the view */ + /* Information about the index */ + if (tableinfo.relkind == 'i') + { + PGresult *result; + + sprintf(buf, "SELECT i.indisunique, i.indisprimary, a.amname\n" + "FROM pg_index i, pg_class c, pg_am a\n" + "WHERE i.indexrelid = c.oid AND c.relname = '%s' AND c.relam = a.oid", + name); + + result = PSQLexec(buf); + if (!result) + error = true; + else + { + footers = xmalloc(2 * sizeof(*footers)); + footers[0] = xmalloc(NAMEDATALEN + 32); + sprintf(footers[0], "%s%s", + strcmp(PQgetvalue(result, 0, 0), "t") == 0 ? "unique " : "", + PQgetvalue(result, 0, 2) + ); + if (strcmp(PQgetvalue(result, 0, 1), "t") == 0) + strcat(footers[0], " (primary key)"); + footers[1] = NULL; + } + } + /* Information about the view */ else if (tableinfo.relkind == 'r' && view_def) { footers = xmalloc(2 * sizeof(*footers)); @@ -769,137 +783,143 @@ describeTableDetails(const char *name, bool desc) footers[1] = NULL; } - /* Information about the table */ + /* Information about the table */ else if (tableinfo.relkind == 'r') { - PGresult *result1=NULL, *result2=NULL, *result3=NULL, *result4=NULL; - int index_count=0, constr_count=0, rule_count=0, trigger_count=0; - int count_footers=0; + PGresult *result1 = NULL, + *result2 = NULL, + *result3 = NULL, + *result4 = NULL; + int index_count = 0, + constr_count = 0, + rule_count = 0, + trigger_count = 0; + int count_footers = 0; /* count indices */ - if (!error && tableinfo.hasindex) - { - sprintf(buf, "SELECT c2.relname\n" - "FROM pg_class c, pg_class c2, pg_index i\n" - "WHERE c.relname = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n" - "ORDER BY c2.relname", - name); - result1 = PSQLexec(buf); - if (!result1) - error = true; - else - index_count = PQntuples(result1); - } - - /* count table (and column) constraints */ - if (!error && tableinfo.checks) - { - sprintf(buf, "SELECT rcsrc\n" - "FROM pg_relcheck r, pg_class c\n" - "WHERE c.relname='%s' AND c.oid = r.rcrelid", - name); - result2 = PSQLexec(buf); - if (!result2) - error = true; - else - constr_count = PQntuples(result2); - } - - /* count rules */ - if (!error && tableinfo.hasrules) - { - sprintf(buf, - "SELECT r.rulename\n" - "FROM pg_rewrite r, pg_class c\n" - "WHERE c.relname='%s' AND c.oid = r.ev_class", - name); - result3 = PSQLexec(buf); - if (!result3) - error = true; - else - rule_count = PQntuples(result3); - } - - /* count triggers */ - if (!error && tableinfo.hasrules) - { - sprintf(buf, - "SELECT t.tgname\n" - "FROM pg_trigger t, pg_class c\n" - "WHERE c.relname='%s' AND c.oid = t.tgrelid", - name); - result4 = PSQLexec(buf); - if (!result4) - error = true; - else - trigger_count = PQntuples(result4); - } - - footers = xmalloc((index_count + constr_count + rule_count + trigger_count + 1) - * sizeof(*footers)); - - /* print indices */ - for (i = 0; i < index_count; i++) - { - sprintf(buf, "%s %s", - index_count==1 ? "Index:" : (i==0 ? "Indices:" : " "), - PQgetvalue(result1, i, 0) - ); - if (i < index_count-1) - strcat(buf, ","); - - footers[count_footers++] = xstrdup(buf); - } - - /* print contraints */ - for (i = 0; i < constr_count; i++) - { - sprintf(buf, "%s %s", - constr_count==1 ? "Constraint:" : (i==0 ? "Constraints:" : " "), - PQgetvalue(result2, i, 0) - ); - footers[count_footers++] = xstrdup(buf); - } - - /* print rules */ - for (i = 0; i < rule_count; i++) - { - sprintf(buf, "%s %s", - rule_count==1 ? "Rule:" : (i==0 ? "Rules:" : " "), - PQgetvalue(result3, i, 0) - ); - if (i < rule_count-1) - strcat(buf, ","); - - footers[count_footers++] = xstrdup(buf); - } - - /* print triggers */ - for (i = 0; i < trigger_count; i++) - { - sprintf(buf, "%s %s", - trigger_count==1 ? "Trigger:" : (i==0 ? "Triggers:" : " "), - PQgetvalue(result4, i, 0) - ); - if (i < trigger_count-1) - strcat(buf, ","); - - footers[count_footers++] = xstrdup(buf); - } - - /* end of list marker */ - footers[count_footers] = NULL; - - PQclear(result1); - PQclear(result2); - PQclear(result3); - PQclear(result4); + if (!error && tableinfo.hasindex) + { + sprintf(buf, "SELECT c2.relname\n" + "FROM pg_class c, pg_class c2, pg_index i\n" + "WHERE c.relname = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n" + "ORDER BY c2.relname", + name); + result1 = PSQLexec(buf); + if (!result1) + error = true; + else + index_count = PQntuples(result1); + } + + /* count table (and column) constraints */ + if (!error && tableinfo.checks) + { + sprintf(buf, "SELECT rcsrc\n" + "FROM pg_relcheck r, pg_class c\n" + "WHERE c.relname='%s' AND c.oid = r.rcrelid", + name); + result2 = PSQLexec(buf); + if (!result2) + error = true; + else + constr_count = PQntuples(result2); + } + + /* count rules */ + if (!error && tableinfo.hasrules) + { + sprintf(buf, + "SELECT r.rulename\n" + "FROM pg_rewrite r, pg_class c\n" + "WHERE c.relname='%s' AND c.oid = r.ev_class", + name); + result3 = PSQLexec(buf); + if (!result3) + error = true; + else + rule_count = PQntuples(result3); + } + + /* count triggers */ + if (!error && tableinfo.hasrules) + { + sprintf(buf, + "SELECT t.tgname\n" + "FROM pg_trigger t, pg_class c\n" + "WHERE c.relname='%s' AND c.oid = t.tgrelid", + name); + result4 = PSQLexec(buf); + if (!result4) + error = true; + else + trigger_count = PQntuples(result4); + } + + footers = xmalloc((index_count + constr_count + rule_count + trigger_count + 1) + * sizeof(*footers)); + + /* print indices */ + for (i = 0; i < index_count; i++) + { + sprintf(buf, "%s %s", + index_count == 1 ? "Index:" : (i == 0 ? "Indices:" : " "), + PQgetvalue(result1, i, 0) + ); + if (i < index_count - 1) + strcat(buf, ","); + + footers[count_footers++] = xstrdup(buf); + } + + /* print contraints */ + for (i = 0; i < constr_count; i++) + { + sprintf(buf, "%s %s", + constr_count == 1 ? "Constraint:" : (i == 0 ? "Constraints:" : " "), + PQgetvalue(result2, i, 0) + ); + footers[count_footers++] = xstrdup(buf); + } + + /* print rules */ + for (i = 0; i < rule_count; i++) + { + sprintf(buf, "%s %s", + rule_count == 1 ? "Rule:" : (i == 0 ? "Rules:" : " "), + PQgetvalue(result3, i, 0) + ); + if (i < rule_count - 1) + strcat(buf, ","); + + footers[count_footers++] = xstrdup(buf); + } + + /* print triggers */ + for (i = 0; i < trigger_count; i++) + { + sprintf(buf, "%s %s", + trigger_count == 1 ? "Trigger:" : (i == 0 ? "Triggers:" : " "), + PQgetvalue(result4, i, 0) + ); + if (i < trigger_count - 1) + strcat(buf, ","); + + footers[count_footers++] = xstrdup(buf); + } + + /* end of list marker */ + footers[count_footers] = NULL; + + PQclear(result1); + PQclear(result2); + PQclear(result3); + PQclear(result4); } - if (!error) - printTable(title, headers, - (const char**)cells, (const char**)footers, - "llll", &myopt, pset.queryFout); + if (!error) + printTable(title, headers, + (const char **) cells, (const char **) footers, + "llll", &myopt, pset.queryFout); /* clean up */ free(title); @@ -907,8 +927,8 @@ describeTableDetails(const char *name, bool desc) for (i = 0; i < PQntuples(res); i++) { free(cells[i * cols + 1]); - if (tableinfo.relkind == 'r') - free(cells[i * cols + 2]); + if (tableinfo.relkind == 'r') + free(cells[i * cols + 2]); } free(cells); @@ -972,14 +992,14 @@ listTables(const char *infotype, const char *name, bool desc) strcat(buf, "'\n"); } - strcat(buf, "UNION\n"); + strcat(buf, "UNION\n"); strcat(buf, "SELECT c.relname as \"Name\", 'table'::text as \"Type\", NULL as \"Owner\""); if (desc) strcat(buf, ", obj_description(c.oid) as \"Description\""); strcat(buf, "\nFROM pg_class c\n" "WHERE c.relkind = 'r'\n" " AND not exists (select 1 from pg_views where viewname = c.relname)\n" - " AND not exists (select 1 from pg_user where usesysid = c.relowner)\n"); + " AND not exists (select 1 from pg_user where usesysid = c.relowner)\n"); strcat(buf, showSystem ? " AND c.relname ~ '^pg_'\n" : " AND c.relname !~ '^pg_'\n"); if (name) { @@ -1009,14 +1029,14 @@ listTables(const char *infotype, const char *name, bool desc) strcat(buf, "'\n"); } - strcat(buf, "UNION\n"); + strcat(buf, "UNION\n"); strcat(buf, "SELECT c.relname as \"Name\", 'view'::text as \"Type\", NULL as \"Owner\""); if (desc) strcat(buf, ", obj_description(c.oid) as \"Description\""); strcat(buf, "\nFROM pg_class c\n" "WHERE c.relkind = 'r'\n" " AND exists (select 1 from pg_views where viewname = c.relname)\n" - " AND not exists (select 1 from pg_user where usesysid = c.relowner)\n"); + " AND not exists (select 1 from pg_user where usesysid = c.relowner)\n"); strcat(buf, showSystem ? " AND c.relname ~ '^pg_'\n" : " AND c.relname !~ '^pg_'\n"); if (name) { @@ -1033,10 +1053,10 @@ listTables(const char *infotype, const char *name, bool desc) strcat(buf, "\nUNION\n\n"); strcat(buf, - "SELECT c.relname as \"Name\",\n" + "SELECT c.relname as \"Name\",\n" " (CASE WHEN relkind = 'S' THEN 'sequence'::text ELSE 'index'::text END) as \"Type\",\n" - " u.usename as \"Owner\"" - ); + " u.usename as \"Owner\"" + ); if (desc) strcat(buf, ", obj_description(c.oid) as \"Description\""); strcat(buf, "\nFROM pg_class c, pg_user u\n" @@ -1061,12 +1081,12 @@ listTables(const char *infotype, const char *name, bool desc) strcat(buf, "'\n"); } - strcat(buf, "UNION\n"); + strcat(buf, "UNION\n"); strcat(buf, - "SELECT c.relname as \"Name\",\n" + "SELECT c.relname as \"Name\",\n" " (CASE WHEN relkind = 'S' THEN 'sequence'::text ELSE 'index'::text END) as \"Type\",\n" - " NULL as \"Owner\"" - ); + " NULL as \"Owner\"" + ); if (desc) strcat(buf, ", obj_description(c.oid) as \"Description\""); strcat(buf, "\nFROM pg_class c\n" @@ -1110,13 +1130,13 @@ listTables(const char *infotype, const char *name, bool desc) strcat(buf, "'\n"); } - strcat(buf, "UNION\n"); + strcat(buf, "UNION\n"); strcat(buf, "SELECT c.relname as \"Name\", 'special'::text as \"Type\", NULL as \"Owner\""); if (desc) strcat(buf, ", obj_description(c.oid) as \"Description\""); strcat(buf, "\nFROM pg_class c\n" "WHERE c.relkind = 's'\n" - " AND not exists (select 1 from pg_user where usesysid = c.relowner)"); + " AND not exists (select 1 from pg_user where usesysid = c.relowner)"); if (name) { strcat(buf, " AND c.relname ~ '^"); @@ -1133,12 +1153,12 @@ listTables(const char *infotype, const char *name, bool desc) return false; if (PQntuples(res) == 0 && !QUIET()) - { - if (name) - fprintf(pset.queryFout, "No matching relations found.\n"); - else - fprintf(pset.queryFout, "No relations found.\n"); - } + { + if (name) + fprintf(pset.queryFout, "No matching relations found.\n"); + else + fprintf(pset.queryFout, "No relations found.\n"); + } else { myopt.nullPrint = NULL; diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h index 673f3fe4865..7383ea6fa66 100644 --- a/src/bin/psql/describe.h +++ b/src/bin/psql/describe.h @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/describe.h,v 1.8 2000/02/16 13:15:26 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/describe.h,v 1.9 2000/04/12 17:16:22 momjian Exp $ */ #ifndef DESCRIBE_H #define DESCRIBE_H @@ -11,30 +11,30 @@ #include "settings.h" /* \da */ -bool describeAggregates(const char *name); +bool describeAggregates(const char *name); /* \df */ -bool describeFunctions(const char *name, bool verbose); +bool describeFunctions(const char *name, bool verbose); /* \dT */ -bool describeTypes(const char *name, bool verbose); +bool describeTypes(const char *name, bool verbose); /* \do */ -bool describeOperators(const char *name); +bool describeOperators(const char *name); /* \z (or \dp) */ -bool permissionsList(const char *name); +bool permissionsList(const char *name); /* \dd */ -bool objectDescription(const char *object); +bool objectDescription(const char *object); /* \d foo */ -bool describeTableDetails(const char *name, bool desc); +bool describeTableDetails(const char *name, bool desc); /* \l */ -bool listAllDbs(bool desc); +bool listAllDbs(bool desc); /* \dt, \di, \ds, \dS, etc. */ -bool listTables(const char *infotype, const char *name, bool desc); +bool listTables(const char *infotype, const char *name, bool desc); #endif /* DESCRIBE_H */ diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c index a1bff8a31b1..8c960723fc0 100644 --- a/src/bin/psql/help.c +++ b/src/bin/psql/help.c @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/help.c,v 1.24 2000/03/05 13:30:19 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/help.c,v 1.25 2000/04/12 17:16:22 momjian Exp $ */ #include "postgres.h" #include "help.h" @@ -52,6 +52,7 @@ usage(void) #ifndef WIN32 struct passwd *pw = NULL; + #endif /* Find default user, in case we need it. */ @@ -73,13 +74,13 @@ usage(void) } /* If this " is the start of the string then it ought to end there to fit in 80 columns >> " */ - puts( "This is psql, the PostgreSQL interactive terminal.\n"); - puts( "Usage:"); - puts( " psql [options] [dbname [username]]\n"); - puts( "Options:"); - puts( " -a Echo all input from script"); - puts( " -A Unaligned table output mode (-P format=unaligned)"); - puts( " -c <query> Run only single query (or slash command) and exit"); + puts("This is psql, the PostgreSQL interactive terminal.\n"); + puts("Usage:"); + puts(" psql [options] [dbname [username]]\n"); + puts("Options:"); + puts(" -a Echo all input from script"); + puts(" -A Unaligned table output mode (-P format=unaligned)"); + puts(" -c <query> Run only single query (or slash command) and exit"); /* Display default database */ env = getenv("PGDATABASE"); @@ -87,10 +88,10 @@ usage(void) env = user; printf(" -d <dbname> Specify database name to connect to (default: %s)\n", env); - puts( " -e Echo queries sent to backend"); - puts( " -E Display queries that internal commands generate"); - puts( " -f <filename> Execute queries from file, then exit"); - puts( " -F <string> Set field separator (default: \"" DEFAULT_FIELD_SEP "\") (-P fieldsep=)"); + puts(" -e Echo queries sent to backend"); + puts(" -E Display queries that internal commands generate"); + puts(" -f <filename> Execute queries from file, then exit"); + puts(" -F <string> Set field separator (default: \"" DEFAULT_FIELD_SEP "\") (-P fieldsep=)"); /* Display default host */ env = getenv("PGHOST"); @@ -101,22 +102,22 @@ usage(void) fputs("domain socket", stdout); puts(")"); - puts( " -H HTML table output mode (-P format=html)"); - puts( " -l List available databases, then exit"); - puts( " -o <filename> Send query output to filename (or |pipe)"); + puts(" -H HTML table output mode (-P format=html)"); + puts(" -l List available databases, then exit"); + puts(" -o <filename> Send query output to filename (or |pipe)"); /* Display default port */ env = getenv("PGPORT"); printf(" -p <port> Specify database server port (default: %s)\n", - env ? env : "hardwired"); + env ? env : "hardwired"); - puts( " -P var[=arg] Set printing option 'var' to 'arg' (see \\pset command)"); - puts( " -q Run quietly (no messages, only query output)"); - puts( " -R <string> Set record separator (default: newline) (-P recordsep=)"); - puts( " -s Single step mode (confirm each query)"); - puts( " -S Single line mode (newline terminates query)"); - puts( " -t Don't print headings and row count (-P tuples_only)"); - puts( " -T text Set HTML table tag options (width, border) (-P tableattr=)"); + puts(" -P var[=arg] Set printing option 'var' to 'arg' (see \\pset command)"); + puts(" -q Run quietly (no messages, only query output)"); + puts(" -R <string> Set record separator (default: newline) (-P recordsep=)"); + puts(" -s Single step mode (confirm each query)"); + puts(" -S Single line mode (newline terminates query)"); + puts(" -t Don't print headings and row count (-P tuples_only)"); + puts(" -T text Set HTML table tag options (width, border) (-P tableattr=)"); /* Display default user */ env = getenv("PGUSER"); @@ -124,17 +125,17 @@ usage(void) env = user; printf(" -U <username> Specify database username (default: %s)\n", env); - puts( " -v name=val Set psql variable 'name' to 'value'"); - puts( " -V Show version information and exit"); - puts( " -W Prompt for password (should happen automatically)"); - puts( " -x Turn on expanded table output (-P expanded)"); - puts( " -X Do not read startup file (~/.psqlrc)"); + puts(" -v name=val Set psql variable 'name' to 'value'"); + puts(" -V Show version information and exit"); + puts(" -W Prompt for password (should happen automatically)"); + puts(" -x Turn on expanded table output (-P expanded)"); + puts(" -X Do not read startup file (~/.psqlrc)"); - puts( "\nFor more information, type \"\\?\" (for internal commands) or \"\\help\""); - puts( "(for SQL commands) from within psql, or consult the psql section in"); - puts( "the PostgreSQL manual, which accompanies the distribution and is also"); - puts( "available at <http://www.postgresql.org>."); - puts( "Report bugs to <pgsql-bugs@postgresql.org>."); + puts("\nFor more information, type \"\\?\" (for internal commands) or \"\\help\""); + puts("(for SQL commands) from within psql, or consult the psql section in"); + puts("the PostgreSQL manual, which accompanies the distribution and is also"); + puts("available at <http://www.postgresql.org>."); + puts("Report bugs to <pgsql-bugs@postgresql.org>."); #ifndef WIN32 if (pw) @@ -195,9 +196,9 @@ slashUsage(void) fout = stdout; /* if you add/remove a line here, change the row test above */ - fprintf(fout, " \\a toggle between unaligned and aligned mode\n"); + fprintf(fout, " \\a toggle between unaligned and aligned mode\n"); fprintf(fout, " \\c[onnect] [dbname|- [user]]\n" - " connect to new database (currently '%s')\n", PQdb(pset.db)); + " connect to new database (currently '%s')\n", PQdb(pset.db)); fprintf(fout, " \\copy ... perform SQL COPY with data stream to the client machine\n"); fprintf(fout, " \\copyright show PostgreSQL usage and distribution terms\n"); fprintf(fout, " \\d <table> describe table (or view, index, sequence)\n"); @@ -210,19 +211,19 @@ slashUsage(void) fprintf(fout, " \\e [fname] edit the current query buffer or <fname> with external editor\n"); fprintf(fout, " \\echo <text> write text to stdout\n"); fprintf(fout, " \\encoding <encoding> set client encoding\n"); - fprintf(fout, " \\f <sep> change field separator\n"); + fprintf(fout, " \\f <sep> change field separator\n"); fprintf(fout, " \\g [fname] send query to backend (and results in <fname> or |pipe)\n"); fprintf(fout, " \\h [cmd] help on syntax of sql commands, * for all commands\n"); - fprintf(fout, " \\H toggle HTML mode (currently %s)\n", - ON(pset.popt.topt.format==PRINT_HTML)); + fprintf(fout, " \\H toggle HTML mode (currently %s)\n", + ON(pset.popt.topt.format == PRINT_HTML)); fprintf(fout, " \\i <fname> read and execute queries from filename\n"); fprintf(fout, " \\l list all databases\n"); fprintf(fout, " \\lo_export, \\lo_import, \\lo_list, \\lo_unlink\n" - " large object operations\n"); + " large object operations\n"); fprintf(fout, " \\o [fname] send all query results to <fname>, or |pipe\n"); fprintf(fout, " \\p show the content of the current query buffer\n"); fprintf(fout, " \\pset {format|border|expanded|fieldsep|recordsep|tuples_only|title|tableattr\n" - " |pager} set table output options\n"); + " |pager} set table output options\n"); fprintf(fout, " \\q quit psql\n"); fprintf(fout, " \\qecho <text> write text to query output stream (see \\o)\n"); fprintf(fout, " \\r reset (clear) the query buffer\n"); @@ -258,19 +259,19 @@ helpSQL(const char *topic) if (!topic || strlen(topic) == 0) { int i; - int items_per_column = (QL_HELP_COUNT + 2)/3; + int items_per_column = (QL_HELP_COUNT + 2) / 3; puts("Available help:"); - for (i = 0; i < items_per_column; i++) + for (i = 0; i < items_per_column; i++) { - printf(" %-25s%-25s%-25s\n", - VALUE_OR_NULL(QL_HELP[i].cmd), - VALUE_OR_NULL(QL_HELP[i + items_per_column].cmd), - VALUE_OR_NULL(QL_HELP[i + 2*items_per_column].cmd) - ); + printf(" %-25s%-25s%-25s\n", + VALUE_OR_NULL(QL_HELP[i].cmd), + VALUE_OR_NULL(QL_HELP[i + items_per_column].cmd), + VALUE_OR_NULL(QL_HELP[i + 2 * items_per_column].cmd) + ); } - putc('\n', stdout); + putc('\n', stdout); } else @@ -285,9 +286,9 @@ helpSQL(const char *topic) { help_found = true; printf("Command: %s\n" - "Description: %s\n" - "Syntax:\n%s\n\n", - QL_HELP[i].cmd, QL_HELP[i].help, QL_HELP[i].syntax); + "Description: %s\n" + "Syntax:\n%s\n\n", + QL_HELP[i].cmd, QL_HELP[i].help, QL_HELP[i].syntax); } } @@ -302,24 +303,24 @@ void print_copyright(void) { puts( - "PostgreSQL Data Base Management System\n\n" - "Portions Copyright (c) 1996-2000, PostgreSQL, Inc\n\n" - "This software is based on Postgres95, formerly known as Postgres, which\n" - "contains the following notice:\n\n" - "Portions Copyright(c) 1994 - 7 Regents of the University of California\n\n" - "Permission to use, copy, modify, and distribute this software and its\n" - "documentation for any purpose, without fee, and without a written agreement\n" - "is hereby granted, provided that the above copyright notice and this paragraph\n" - "and the following two paragraphs appear in all copies.\n\n" - "IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR\n" - "DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST\n" - "PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF\n" - "THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH\n" - "DAMAGE.\n\n" - "THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,\n" - "BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\n" - "PARTICULAR PURPOSE.THE SOFTWARE PROVIDED HEREUNDER IS ON AN \"AS IS\" BASIS,\n" - "AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE,\n" - "SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." - ); + "PostgreSQL Data Base Management System\n\n" + "Portions Copyright (c) 1996-2000, PostgreSQL, Inc\n\n" + "This software is based on Postgres95, formerly known as Postgres, which\n" + "contains the following notice:\n\n" + "Portions Copyright(c) 1994 - 7 Regents of the University of California\n\n" + "Permission to use, copy, modify, and distribute this software and its\n" + "documentation for any purpose, without fee, and without a written agreement\n" + "is hereby granted, provided that the above copyright notice and this paragraph\n" + "and the following two paragraphs appear in all copies.\n\n" + "IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR\n" + "DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST\n" + "PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF\n" + "THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH\n" + "DAMAGE.\n\n" + "THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,\n" + "BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\n" + "PARTICULAR PURPOSE.THE SOFTWARE PROVIDED HEREUNDER IS ON AN \"AS IS\" BASIS,\n" + "AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE,\n" + "SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." + ); } diff --git a/src/bin/psql/input.c b/src/bin/psql/input.c index 6d7143467c0..86200ad0522 100644 --- a/src/bin/psql/input.c +++ b/src/bin/psql/input.c @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/input.c,v 1.12 2000/02/20 14:28:20 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/input.c,v 1.13 2000/04/12 17:16:22 momjian Exp $ */ #include "postgres.h" #include "input.h" @@ -37,9 +37,11 @@ char * gets_interactive(char *prompt) { char *s; + #ifdef USE_HISTORY - const char *var; - static char * prev_hist = NULL; + const char *var; + static char *prev_hist = NULL; + #endif #ifdef USE_READLINE @@ -56,19 +58,19 @@ gets_interactive(char *prompt) #endif #ifdef USE_HISTORY - if (useHistory && s && s[0] != '\0') - { - var = GetVariable(pset.vars, "HISTCONTROL"); - if (!var || (var - && !((strcmp(var, "ignorespace") == 0 || strcmp(var, "ignoreboth") ==0) && s[0] == ' ' ) - && !((strcmp(var, "ignoredups") == 0 || strcmp(var, "ignoreboth") ==0) && prev_hist && strcmp(s, prev_hist) == 0) - )) - { - free(prev_hist); - prev_hist = strdup(s); - add_history(s); - } - } + if (useHistory && s && s[0] != '\0') + { + var = GetVariable(pset.vars, "HISTCONTROL"); + if (!var || (var + && !((strcmp(var, "ignorespace") == 0 || strcmp(var, "ignoreboth") == 0) && s[0] == ' ') + && !((strcmp(var, "ignoredups") == 0 || strcmp(var, "ignoreboth") == 0) && prev_hist && strcmp(s, prev_hist) == 0) + )) + { + free(prev_hist); + prev_hist = strdup(s); + add_history(s); + } + } #endif return s; @@ -122,7 +124,7 @@ initializeInput(int flags) if (flags == 1) { useReadline = true; - initialize_readline(); + initialize_readline(); } #endif @@ -132,7 +134,7 @@ initializeInput(int flags) const char *home; useHistory = true; - SetVariable(pset.vars, "HISTSIZE", "500"); + SetVariable(pset.vars, "HISTSIZE", "500"); using_history(); home = getenv("HOME"); if (home) @@ -149,7 +151,7 @@ initializeInput(int flags) } #endif - atexit(finishInput); + atexit(finishInput); } @@ -191,9 +193,10 @@ finishInput(void) psql_history = (char *) malloc(strlen(home) + 20); if (psql_history) { - const char * var = GetVariable(pset.vars, "HISTSIZE"); - if (var) - stifle_history(atoi(var)); + const char *var = GetVariable(pset.vars, "HISTSIZE"); + + if (var) + stifle_history(atoi(var)); sprintf(psql_history, "%s/.psql_history", home); write_history(psql_history); free(psql_history); diff --git a/src/bin/psql/input.h b/src/bin/psql/input.h index c141d1658cd..557179113b9 100644 --- a/src/bin/psql/input.h +++ b/src/bin/psql/input.h @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/input.h,v 1.9 2000/03/08 01:58:22 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/input.h,v 1.10 2000/04/12 17:16:22 momjian Exp $ */ #ifndef INPUT_H #define INPUT_H @@ -15,30 +15,30 @@ * USE_READLINE and USE_HISTORY are the definite pointers regarding existence or not. */ #ifdef HAVE_LIBREADLINE -# if defined(HAVE_READLINE_READLINE_H) -# include <readline/readline.h> -# define USE_READLINE 1 -# elif defined(HAVE_READLINE_H) -# include <readline.h> -# define USE_READLINE 1 -# endif +#if defined(HAVE_READLINE_READLINE_H) +#include <readline/readline.h> +#define USE_READLINE 1 +#elif defined(HAVE_READLINE_H) +#include <readline.h> +#define USE_READLINE 1 +#endif #endif #if defined(HAVE_LIBHISTORY) || (defined(HAVE_LIBREADLINE) && defined(HAVE_HISTORY_IN_READLINE)) -# if defined(HAVE_READLINE_HISTORY_H) -# include <readline/history.h> -# define USE_HISTORY 1 -# elif defined(HAVE_HISTORY_H) -# include <history.h> -# define USE_HISTORY 1 -# endif +#if defined(HAVE_READLINE_HISTORY_H) +#include <readline/history.h> +#define USE_HISTORY 1 +#elif defined(HAVE_HISTORY_H) +#include <history.h> +#define USE_HISTORY 1 +#endif #endif -char * gets_interactive(char *prompt); -char * gets_fromFile(FILE *source); +char *gets_interactive(char *prompt); +char *gets_fromFile(FILE *source); -void initializeInput(int flags); -bool saveHistory(char *fname); -void finishInput(void); +void initializeInput(int flags); +bool saveHistory(char *fname); +void finishInput(void); -#endif /* INPUT_H */ +#endif /* INPUT_H */ diff --git a/src/bin/psql/large_obj.c b/src/bin/psql/large_obj.c index c5b4a634779..020b0173eb4 100644 --- a/src/bin/psql/large_obj.c +++ b/src/bin/psql/large_obj.c @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/large_obj.c,v 1.9 2000/02/16 13:15:26 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/large_obj.c,v 1.10 2000/04/12 17:16:22 momjian Exp $ */ #include "postgres.h" #include "large_obj.h" @@ -92,8 +92,8 @@ do_lo_export(const char *loid_arg, const char *filename_arg) if (!pset.db) { - if (!pset.cur_cmd_interactive) - fprintf(stderr, "%s: ", pset.progname); + if (!pset.cur_cmd_interactive) + fprintf(stderr, "%s: ", pset.progname); fputs("\\lo_export: not connected to a database\n", stderr); return false; } @@ -161,8 +161,8 @@ do_lo_import(const char *filename_arg, const char *comment_arg) if (!pset.db) { - if (!pset.cur_cmd_interactive) - fprintf(stderr, "%s: ", pset.progname); + if (!pset.cur_cmd_interactive) + fprintf(stderr, "%s: ", pset.progname); fputs("\\lo_import: not connected to a database\n", stderr); return false; } @@ -226,8 +226,8 @@ do_lo_import(const char *filename_arg, const char *comment_arg) fprintf(pset.queryFout, "lo_import %d\n", loid); - sprintf(buf, "%u", (unsigned int)loid); - SetVariable(pset.vars, "LASTOID", buf); + sprintf(buf, "%u", (unsigned int) loid); + SetVariable(pset.vars, "LASTOID", buf); return true; } @@ -254,8 +254,8 @@ do_lo_unlink(const char *loid_arg) if (!pset.db) { - if (!pset.cur_cmd_interactive) - fprintf(stderr, "%s: ", pset.progname); + if (!pset.cur_cmd_interactive) + fprintf(stderr, "%s: ", pset.progname); fputs("\\lo_unlink: not connected to a database\n", stderr); return false; } @@ -328,14 +328,14 @@ do_lo_list(void) printQueryOpt myopt = pset.popt; strcpy(buf, - "SELECT usename as \"Owner\", substring(relname from 5) as \"ID\",\n" - " obj_description(pg_class.oid) as \"Description\"\n" - "FROM pg_class, pg_user\n" + "SELECT usename as \"Owner\", substring(relname from 5) as \"ID\",\n" + " obj_description(pg_class.oid) as \"Description\"\n" + "FROM pg_class, pg_user\n" "WHERE usesysid = relowner AND relkind = 'l'\n" - "UNION\n" - "SELECT NULL as \"Owner\", substring(relname from 5) as \"ID\",\n" - " obj_description(pg_class.oid) as \"Description\"\n" - "FROM pg_class\n" + "UNION\n" + "SELECT NULL as \"Owner\", substring(relname from 5) as \"ID\",\n" + " obj_description(pg_class.oid) as \"Description\"\n" + "FROM pg_class\n" "WHERE not exists (select 1 from pg_user where usesysid = relowner) AND relkind = 'l'\n" "ORDER BY \"ID\""); diff --git a/src/bin/psql/mainloop.c b/src/bin/psql/mainloop.c index b27d344a781..a6f9d90c842 100644 --- a/src/bin/psql/mainloop.c +++ b/src/bin/psql/mainloop.c @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/mainloop.c,v 1.27 2000/03/27 21:11:37 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/mainloop.c,v 1.28 2000/04/12 17:16:22 momjian Exp $ */ #include "postgres.h" #include "mainloop.h" @@ -19,7 +19,8 @@ #ifndef WIN32 #include <setjmp.h> -sigjmp_buf main_loop_jmp; +sigjmp_buf main_loop_jmp; + #endif @@ -36,8 +37,8 @@ int MainLoop(FILE *source) { PQExpBuffer query_buf; /* buffer for query being accumulated */ - PQExpBuffer previous_buf; /* if there isn't anything in the new buffer - yet, use this one for \e, etc. */ + PQExpBuffer previous_buf; /* if there isn't anything in the new + * buffer yet, use this one for \e, etc. */ char *line; /* current line of input */ int len; /* length of the line */ volatile int successResult = EXIT_SUCCESS; @@ -48,9 +49,9 @@ MainLoop(FILE *source) volatile bool xcomment; /* in extended comment */ volatile int paren_level; unsigned int query_start; - volatile int count_eof = 0; - const char *var; - volatile unsigned int bslash_count = 0; + volatile int count_eof = 0; + const char *var; + volatile unsigned int bslash_count = 0; int i, prevlen, @@ -60,7 +61,7 @@ MainLoop(FILE *source) FILE *prev_cmd_source; bool prev_cmd_interactive; - unsigned int prev_lineno; + unsigned int prev_lineno; volatile bool die_on_error = false; @@ -74,10 +75,10 @@ MainLoop(FILE *source) query_buf = createPQExpBuffer(); - previous_buf = createPQExpBuffer(); + previous_buf = createPQExpBuffer(); if (!query_buf || !previous_buf) { - psql_error("out of memory\n"); + psql_error("out of memory\n"); exit(EXIT_FAILURE); } @@ -85,59 +86,62 @@ MainLoop(FILE *source) in_quote = 0; paren_level = 0; slashCmdStatus = CMD_UNKNOWN; /* set default */ - prev_lineno = pset.lineno; - pset.lineno = 0; + prev_lineno = pset.lineno; + pset.lineno = 0; /* main loop to get queries and execute them */ while (1) { #ifndef WIN32 - /* - * Welcome code for Control-C - */ - if (cancel_pressed) - { - if (!pset.cur_cmd_interactive) - { - /* - * You get here if you stopped a script with Ctrl-C and a query - * cancel was issued. In that case we don't do the longjmp, so - * the query routine can finish nicely. - */ - successResult = EXIT_USER; - break; - } - - cancel_pressed = false; - } - - if (sigsetjmp(main_loop_jmp, 1) != 0) - { - /* got here with longjmp */ - - if (pset.cur_cmd_interactive) - { - fputc('\n', stdout); - resetPQExpBuffer(query_buf); - - /* reset parsing state */ - xcomment = false; - in_quote = 0; - paren_level = 0; - count_eof = 0; - slashCmdStatus = CMD_UNKNOWN; - } - else - { - successResult = EXIT_USER; - break; - } - } -#endif /* not WIN32 */ + + /* + * Welcome code for Control-C + */ + if (cancel_pressed) + { + if (!pset.cur_cmd_interactive) + { + + /* + * You get here if you stopped a script with Ctrl-C and a + * query cancel was issued. In that case we don't do the + * longjmp, so the query routine can finish nicely. + */ + successResult = EXIT_USER; + break; + } + + cancel_pressed = false; + } + + if (sigsetjmp(main_loop_jmp, 1) != 0) + { + /* got here with longjmp */ + + if (pset.cur_cmd_interactive) + { + fputc('\n', stdout); + resetPQExpBuffer(query_buf); + + /* reset parsing state */ + xcomment = false; + in_quote = 0; + paren_level = 0; + count_eof = 0; + slashCmdStatus = CMD_UNKNOWN; + } + else + { + successResult = EXIT_USER; + break; + } + } +#endif /* not WIN32 */ if (slashCmdStatus == CMD_NEWEDIT) { + /* * just returned from editing the line? then just copy to the * input buffer @@ -148,11 +152,12 @@ MainLoop(FILE *source) xcomment = false; in_quote = 0; paren_level = 0; - slashCmdStatus = CMD_UNKNOWN; + slashCmdStatus = CMD_UNKNOWN; } else { - fflush(stdout); + fflush(stdout); + /* * otherwise, set interactive prompt if necessary and get * another line @@ -167,8 +172,8 @@ MainLoop(FILE *source) prompt_status = PROMPT_DOUBLEQUOTE; else if (xcomment) prompt_status = PROMPT_COMMENT; - else if (paren_level) - prompt_status = PROMPT_PAREN; + else if (paren_level) + prompt_status = PROMPT_PAREN; else if (query_buf->len > 0) prompt_status = PROMPT_CONTINUE; else @@ -195,51 +200,54 @@ MainLoop(FILE *source) if (line == NULL) { if (pset.cur_cmd_interactive) - { - bool getout = true; - - /* This tries to mimic bash's IGNOREEOF feature. */ - const char * val = GetVariable(pset.vars, "IGNOREEOF"); - if (val) - { - long int maxeof; - char * endptr; - - if (*val == '\0') - maxeof = 10; - else - { - maxeof = strtol(val, &endptr, 0); - if (*endptr != '\0') /* string not valid as a number */ - maxeof = 10; - } - - if (count_eof++ != maxeof) - getout = false; /* not quite there yet */ - } - - if (getout) - { - if (QUIET()) - putc('\n', stdout); - else - puts("\\q"); - break; - } - else - { - if (!QUIET()) - printf("Use \"\\q\" to leave %s.\n", pset.progname); - continue; - } - } - else /* not interactive */ - break; + { + bool getout = true; + + /* This tries to mimic bash's IGNOREEOF feature. */ + const char *val = GetVariable(pset.vars, "IGNOREEOF"); + + if (val) + { + long int maxeof; + char *endptr; + + if (*val == '\0') + maxeof = 10; + else + { + maxeof = strtol(val, &endptr, 0); + if (*endptr != '\0') /* string not valid as a + * number */ + maxeof = 10; + } + + if (count_eof++ != maxeof) + getout = false; /* not quite there yet */ + } + + if (getout) + { + if (QUIET()) + putc('\n', stdout); + else + puts("\\q"); + break; + } + else + { + if (!QUIET()) + printf("Use \"\\q\" to leave %s.\n", pset.progname); + continue; + } + } + else +/* not interactive */ + break; } - else - count_eof = 0; + else + count_eof = 0; - pset.lineno++; + pset.lineno++; /* strip trailing backslashes, they don't have a clear meaning */ while (1) @@ -260,10 +268,10 @@ MainLoop(FILE *source) } /* echo back if flag is set */ - var = GetVariable(pset.vars, "ECHO"); - if (!pset.cur_cmd_interactive && var && strcmp(var, "all")==0) - puts(line); - fflush(stdout); + var = GetVariable(pset.vars, "ECHO"); + if (!pset.cur_cmd_interactive && var && strcmp(var, "all") == 0) + puts(line); + fflush(stdout); len = strlen(line); query_start = 0; @@ -278,15 +286,16 @@ MainLoop(FILE *source) success = true; for (i = 0, prevlen = 0, thislen = (len > 0) ? PQmblen(line, pset.encoding) : 0; - i < len; - ADVANCE_1) + i < len; + ADVANCE_1) { /* was the previous character a backslash? */ - bool was_bslash = (i > 0 && line[i - prevlen] == '\\'); - if (was_bslash) - bslash_count++; - else - bslash_count = 0; + bool was_bslash = (i > 0 && line[i - prevlen] == '\\'); + + if (was_bslash) + bslash_count++; + else + bslash_count = 0; /* in quote? */ if (in_quote) @@ -331,53 +340,57 @@ MainLoop(FILE *source) else if (line[i] == ')' && paren_level > 0) paren_level--; - /* colon -> substitute variable */ - /* we need to be on the watch for the '::' operator */ - else if (line[i] == ':' && !was_bslash - && strspn(line+i+thislen, VALID_VARIABLE_CHARS)>0 - && !(prevlen>0 && line[i-prevlen] == ':') - ) - { + /* colon -> substitute variable */ + /* we need to be on the watch for the '::' operator */ + else if (line[i] == ':' && !was_bslash + && strspn(line + i + thislen, VALID_VARIABLE_CHARS) > 0 + && !(prevlen > 0 && line[i - prevlen] == ':') + ) + { size_t in_length, out_length; const char *value; char *new; - char after; /* the character after the variable name - will be temporarily overwritten */ + char after; /* the character after the + * variable name will be + * temporarily overwritten */ in_length = strspn(&line[i + thislen], VALID_VARIABLE_CHARS); after = line[i + thislen + in_length]; line[i + thislen + in_length] = '\0'; - /* if the variable doesn't exist we'll leave the string as is */ + /* + * if the variable doesn't exist we'll leave the string as + * is + */ value = GetVariable(pset.vars, &line[i + thislen]); - if (value) - { - out_length = strlen(value); - - new = malloc(len + out_length - (1 + in_length) + 1); - if (!new) - { - psql_error("out of memory\n"); - exit(EXIT_FAILURE); - } - - sprintf(new, "%.*s%s%c", i, line, value, after); - if (after) - strcat(new, line + i + 1 + in_length + 1); - - free(line); - line = new; - len = strlen(new); - continue; /* reparse the just substituted */ - } - else - { - /* restore overwritten character */ - line[i + thislen + in_length] = after; - /* move on ... */ - } - } + if (value) + { + out_length = strlen(value); + + new = malloc(len + out_length - (1 + in_length) + 1); + if (!new) + { + psql_error("out of memory\n"); + exit(EXIT_FAILURE); + } + + sprintf(new, "%.*s%s%c", i, line, value, after); + if (after) + strcat(new, line + i + 1 + in_length + 1); + + free(line); + line = new; + len = strlen(new); + continue; /* reparse the just substituted */ + } + else + { + /* restore overwritten character */ + line[i + thislen + in_length] = after; + /* move on ... */ + } + } /* semicolon? then send query */ else if (line[i] == ';' && !was_bslash && !paren_level) @@ -386,6 +399,7 @@ MainLoop(FILE *source) /* is there anything else on the line? */ if (line[query_start + strspn(line + query_start, " \t")] != '\0') { + /* * insert a cosmetic newline, if this is not the first * line in the buffer @@ -394,27 +408,29 @@ MainLoop(FILE *source) appendPQExpBufferChar(query_buf, '\n'); /* append the line to the query buffer */ appendPQExpBufferStr(query_buf, line + query_start); - appendPQExpBufferChar(query_buf, ';'); + appendPQExpBufferChar(query_buf, ';'); } /* execute query */ success = SendQuery(query_buf->data); - slashCmdStatus = success ? CMD_SEND : CMD_ERROR; + slashCmdStatus = success ? CMD_SEND : CMD_ERROR; - resetPQExpBuffer(previous_buf); - appendPQExpBufferStr(previous_buf, query_buf->data); - resetPQExpBuffer(query_buf); + resetPQExpBuffer(previous_buf); + appendPQExpBufferStr(previous_buf, query_buf->data); + resetPQExpBuffer(query_buf); query_start = i + thislen; } - /* if you have a burning need to send a semicolon or colon to - the backend ... */ - else if (was_bslash && (line[i] == ';' || line[i] == ':')) - { - /* remove the backslash */ - memmove(line + i - prevlen, line + i, len - i + 1); - len--; - } + /* + * if you have a burning need to send a semicolon or colon to + * the backend ... + */ + else if (was_bslash && (line[i] == ';' || line[i] == ':')) + { + /* remove the backslash */ + memmove(line + i - prevlen, line + i, len - i + 1); + len--; + } /* backslash command */ else if (was_bslash) @@ -427,6 +443,7 @@ MainLoop(FILE *source) /* is there anything else on the line for the command? */ if (line[query_start + strspn(line + query_start, " \t")] != '\0') { + /* * insert a cosmetic newline, if this is not the first * line in the buffer @@ -437,40 +454,41 @@ MainLoop(FILE *source) appendPQExpBufferStr(query_buf, line + query_start); } - /* handle backslash command */ - slashCmdStatus = HandleSlashCmds(&line[i], - query_buf->len>0 ? query_buf : previous_buf, - &end_of_cmd); + /* handle backslash command */ + slashCmdStatus = HandleSlashCmds(&line[i], + query_buf->len > 0 ? query_buf : previous_buf, + &end_of_cmd); success = slashCmdStatus != CMD_ERROR; - if ((slashCmdStatus == CMD_SEND || slashCmdStatus == CMD_NEWEDIT) && - query_buf->len == 0) { - /* copy previous buffer to current for for handling */ - appendPQExpBufferStr(query_buf, previous_buf->data); - } + if ((slashCmdStatus == CMD_SEND || slashCmdStatus == CMD_NEWEDIT) && + query_buf->len == 0) + { + /* copy previous buffer to current for for handling */ + appendPQExpBufferStr(query_buf, previous_buf->data); + } if (slashCmdStatus == CMD_SEND) { success = SendQuery(query_buf->data); query_start = i + thislen; - resetPQExpBuffer(previous_buf); - appendPQExpBufferStr(previous_buf, query_buf->data); - resetPQExpBuffer(query_buf); + resetPQExpBuffer(previous_buf); + appendPQExpBufferStr(previous_buf, query_buf->data); + resetPQExpBuffer(query_buf); } /* process anything left after the backslash command */ - i += end_of_cmd - &line[i]; - query_start = i; + i += end_of_cmd - &line[i]; + query_start = i; } - /* stop the script after error */ + /* stop the script after error */ if (!success && die_on_error) break; - } /* for (line) */ + } /* for (line) */ if (slashCmdStatus == CMD_TERMINATE) @@ -495,10 +513,10 @@ MainLoop(FILE *source) if (query_buf->data[0] != '\0' && GetVariableBool(pset.vars, "SINGLELINE")) { success = SendQuery(query_buf->data); - slashCmdStatus = success ? CMD_SEND : CMD_ERROR; - resetPQExpBuffer(previous_buf); - appendPQExpBufferStr(previous_buf, query_buf->data); - resetPQExpBuffer(query_buf); + slashCmdStatus = success ? CMD_SEND : CMD_ERROR; + resetPQExpBuffer(previous_buf); + appendPQExpBufferStr(previous_buf, query_buf->data); + resetPQExpBuffer(query_buf); } @@ -515,27 +533,27 @@ MainLoop(FILE *source) successResult = EXIT_BADCONN; break; } - } /* while !endoffile/session */ - - /* - * Process query at the end of file without a semicolon - */ - if (query_buf->len > 0 && !pset.cur_cmd_interactive) - { - success = SendQuery(query_buf->data); - - if (!success && die_on_error) - successResult = EXIT_USER; - else if (pset.db == NULL) - successResult = EXIT_BADCONN; - } - + } /* while !endoffile/session */ + + /* + * Process query at the end of file without a semicolon + */ + if (query_buf->len > 0 && !pset.cur_cmd_interactive) + { + success = SendQuery(query_buf->data); + + if (!success && die_on_error) + successResult = EXIT_USER; + else if (pset.db == NULL) + successResult = EXIT_BADCONN; + } + destroyPQExpBuffer(query_buf); destroyPQExpBuffer(previous_buf); pset.cur_cmd_source = prev_cmd_source; pset.cur_cmd_interactive = prev_cmd_interactive; - pset.lineno = prev_lineno; + pset.lineno = prev_lineno; return successResult; } /* MainLoop() */ diff --git a/src/bin/psql/mainloop.h b/src/bin/psql/mainloop.h index a9cc61b7f66..d8bdf3087cd 100644 --- a/src/bin/psql/mainloop.h +++ b/src/bin/psql/mainloop.h @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/mainloop.h,v 1.8 2000/02/20 14:28:20 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/mainloop.h,v 1.9 2000/04/12 17:16:22 momjian Exp $ */ #ifndef MAINLOOP_H #define MAINLOOP_H @@ -14,8 +14,9 @@ #include <setjmp.h> extern sigjmp_buf main_loop_jmp; + #endif -int MainLoop(FILE *source); +int MainLoop(FILE *source); #endif /* MAINLOOP_H */ diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c index 82cb64b7cfe..b94b90ba36f 100644 --- a/src/bin/psql/print.c +++ b/src/bin/psql/print.c @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/print.c,v 1.12 2000/02/16 13:15:26 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/print.c,v 1.13 2000/04/12 17:16:22 momjian Exp $ */ #include "postgres.h" #include "print.h" @@ -35,20 +35,20 @@ static void -print_unaligned_text(const char *title, const char * const * headers, - const char * const * cells, const char * const * footers, - const char *opt_fieldsep, const char *opt_recordsep, bool opt_barebones, - FILE *fout) +print_unaligned_text(const char *title, const char *const * headers, + const char *const * cells, const char *const * footers, + const char *opt_fieldsep, const char *opt_recordsep, bool opt_barebones, + FILE *fout) { unsigned int col_count = 0; unsigned int i; - const char * const * ptr; - bool need_recordsep = false; + const char *const * ptr; + bool need_recordsep = false; if (!opt_fieldsep) opt_fieldsep = ""; - if (!opt_recordsep) - opt_recordsep = ""; + if (!opt_recordsep) + opt_recordsep = ""; /* print title */ if (!opt_barebones && title) @@ -66,22 +66,22 @@ print_unaligned_text(const char *title, const char * const * headers, } } if (!opt_barebones) - need_recordsep = true; + need_recordsep = true; /* print cells */ i = 0; for (ptr = cells; *ptr; ptr++) { - if (need_recordsep) - { + if (need_recordsep) + { fputs(opt_recordsep, fout); - need_recordsep = false; - } + need_recordsep = false; + } fputs(*ptr, fout); if ((i + 1) % col_count) fputs(opt_fieldsep, fout); else - need_recordsep = true; + need_recordsep = true; i++; } @@ -89,41 +89,41 @@ print_unaligned_text(const char *title, const char * const * headers, if (!opt_barebones && footers) for (ptr = footers; *ptr; ptr++) - { - if (need_recordsep) - { - fputs(opt_recordsep, fout); - need_recordsep = false; - } + { + if (need_recordsep) + { + fputs(opt_recordsep, fout); + need_recordsep = false; + } fputs(*ptr, fout); - need_recordsep = true; - } + need_recordsep = true; + } - /* the last record needs to be concluded with a newline */ - if (need_recordsep) - fputc('\n', fout); + /* the last record needs to be concluded with a newline */ + if (need_recordsep) + fputc('\n', fout); } static void -print_unaligned_vertical(const char *title, const char * const * headers, - const char * const * cells, const char * const * footers, - const char *opt_fieldsep, const char *opt_recordsep, bool opt_barebones, - FILE *fout) +print_unaligned_vertical(const char *title, const char *const * headers, + const char *const * cells, const char *const * footers, + const char *opt_fieldsep, const char *opt_recordsep, bool opt_barebones, + FILE *fout) { unsigned int col_count = 0; unsigned int i; - const char * const * ptr; + const char *const * ptr; if (!opt_fieldsep) opt_fieldsep = ""; - if (!opt_recordsep) - opt_recordsep = ""; + if (!opt_recordsep) + opt_recordsep = ""; /* print title */ if (!opt_barebones && title) - fputs(title, fout); + fputs(title, fout); /* count columns */ for (ptr = headers; *ptr; ptr++) @@ -132,30 +132,30 @@ print_unaligned_vertical(const char *title, const char * const * headers, /* print records */ for (i = 0, ptr = cells; *ptr; i++, ptr++) { - if (i!=0 || (!opt_barebones && title)) - { - fputs(opt_recordsep, fout); - if (i % col_count == 0) - fputs(opt_recordsep, fout); /* another one */ - } - - fputs(headers[i % col_count], fout); - fputs(opt_fieldsep, fout); - fputs(*ptr, fout); + if (i != 0 || (!opt_barebones && title)) + { + fputs(opt_recordsep, fout); + if (i % col_count == 0) + fputs(opt_recordsep, fout); /* another one */ + } + + fputs(headers[i % col_count], fout); + fputs(opt_fieldsep, fout); + fputs(*ptr, fout); } /* print footers */ if (!opt_barebones && footers && *footers) { - fputs(opt_recordsep, fout); + fputs(opt_recordsep, fout); for (ptr = footers; *ptr; ptr++) - { - fputs(opt_recordsep, fout); - fputs(*ptr, fout); - } + { + fputs(opt_recordsep, fout); + fputs(*ptr, fout); + } } - fputc('\n', fout); + fputc('\n', fout); } @@ -202,17 +202,17 @@ _print_horizontal_line(const unsigned int col_count, const unsigned int *widths, static void -print_aligned_text(const char *title, const char * const * headers, - const char * const * cells, const char * const * footers, - const char *opt_align, bool opt_barebones, unsigned short int opt_border, - FILE *fout) +print_aligned_text(const char *title, const char *const * headers, + const char *const * cells, const char *const * footers, +const char *opt_align, bool opt_barebones, unsigned short int opt_border, + FILE *fout) { unsigned int col_count = 0; unsigned int i, tmp; unsigned int *widths, total_w; - const char * const * ptr; + const char *const * ptr; /* count columns */ for (ptr = headers; *ptr; ptr++) @@ -268,8 +268,8 @@ print_aligned_text(const char *title, const char * const * headers, { /* centered */ fprintf(fout, "%-*s%s%-*s", - (int) floor((widths[i] - strlen(headers[i])) / 2.0), "", - headers[i], (int) ceil((widths[i] - strlen(headers[i])) / 2.0), ""); + (int) floor((widths[i] - strlen(headers[i])) / 2.0), "", + headers[i], (int) ceil((widths[i] - strlen(headers[i])) / 2.0), ""); if (i < col_count - 1) { @@ -346,24 +346,25 @@ print_aligned_text(const char *title, const char * const * headers, static void -print_aligned_vertical(const char *title, const char * const * headers, - const char * const * cells, const char * const * footers, - bool opt_barebones, unsigned short int opt_border, - FILE *fout) +print_aligned_vertical(const char *title, const char *const * headers, + const char *const * cells, const char *const * footers, + bool opt_barebones, unsigned short int opt_border, + FILE *fout) { unsigned int col_count = 0; unsigned int record = 1; - const char * const *ptr; + const char *const * ptr; unsigned int i, tmp, hwidth = 0, dwidth = 0; char *divider; - if (cells[0] == NULL) { - puts("(No rows)\n"); - return; - } + if (cells[0] == NULL) + { + puts("(No rows)\n"); + return; + } /* count columns and find longest header */ for (ptr = headers; *ptr; ptr++) @@ -427,20 +428,21 @@ print_aligned_vertical(const char *title, const char * const * headers, record_str_len = strlen(record_str); if (record_str_len + opt_border > strlen(divider)) - fprintf(fout, "%.*s%s\n", opt_border, divider, record_str); - else - { - char *div_copy = strdup(divider); - - if (!div_copy) { - perror("malloc"); - exit(EXIT_FAILURE); - } - - strncpy(div_copy + opt_border, record_str, record_str_len); - fprintf(fout, "%s\n", div_copy); - free(div_copy); - } + fprintf(fout, "%.*s%s\n", opt_border, divider, record_str); + else + { + char *div_copy = strdup(divider); + + if (!div_copy) + { + perror("malloc"); + exit(EXIT_FAILURE); + } + + strncpy(div_copy + opt_border, record_str, record_str_len); + fprintf(fout, "%s\n", div_copy); + free(div_copy); + } free(record_str); } else if (i != 0 || opt_border == 2) @@ -517,15 +519,15 @@ html_escaped_print(const char *in, FILE *fout) static void -print_html_text(const char *title, const char * const * headers, - const char * const * cells, const char * const * footers, - const char *opt_align, bool opt_barebones, unsigned short int opt_border, - const char *opt_table_attr, - FILE *fout) +print_html_text(const char *title, const char *const * headers, + const char *const * cells, const char *const * footers, +const char *opt_align, bool opt_barebones, unsigned short int opt_border, + const char *opt_table_attr, + FILE *fout) { unsigned int col_count = 0; unsigned int i; - const char * const *ptr; + const char *const * ptr; fprintf(fout, "<table border=%d", opt_border); if (opt_table_attr) @@ -591,16 +593,16 @@ print_html_text(const char *title, const char * const * headers, static void -print_html_vertical(const char *title, const char * const * headers, - const char * const * cells, const char * const * footers, - const char *opt_align, bool opt_barebones, unsigned short int opt_border, - const char *opt_table_attr, +print_html_vertical(const char *title, const char *const * headers, + const char *const * cells, const char *const * footers, +const char *opt_align, bool opt_barebones, unsigned short int opt_border, + const char *opt_table_attr, FILE *fout) { unsigned int col_count = 0; unsigned int i; unsigned int record = 1; - const char * const *ptr; + const char *const * ptr; fprintf(fout, "<table border=%d", opt_border); if (opt_table_attr) @@ -700,15 +702,15 @@ latex_escaped_print(const char *in, FILE *fout) static void -print_latex_text(const char *title, const char * const * headers, - const char * const * cells, const char * const * footers, - const char *opt_align, bool opt_barebones, unsigned short int opt_border, - FILE *fout) +print_latex_text(const char *title, const char *const * headers, + const char *const * cells, const char *const * footers, +const char *opt_align, bool opt_barebones, unsigned short int opt_border, + FILE *fout) { unsigned int col_count = 0; unsigned int i; const char *cp; - const char * const *ptr; + const char *const * ptr; /* print title */ @@ -796,14 +798,14 @@ print_latex_text(const char *title, const char * const * headers, static void -print_latex_vertical(const char *title, const char * const * headers, - const char * const * cells, const char * const * footers, - const char *opt_align, bool opt_barebones, unsigned short int opt_border, - FILE *fout) +print_latex_vertical(const char *title, const char *const * headers, + const char *const * cells, const char *const * footers, +const char *opt_align, bool opt_barebones, unsigned short int opt_border, + FILE *fout) { unsigned int col_count = 0; unsigned int i; - const char * const *ptr; + const char *const * ptr; unsigned int record = 1; (void) opt_align; /* currently unused parameter */ @@ -884,11 +886,11 @@ print_latex_vertical(const char *title, const char * const * headers, void printTable(const char *title, - const char * const * headers, - const char * const * cells, - const char * const * footers, - const char *align, - const printTableOpt * opt, FILE *fout) + const char *const * headers, + const char *const * cells, + const char *const * footers, + const char *align, + const printTableOpt *opt, FILE *fout) { const char *default_footer[] = {NULL}; unsigned short int border = opt->border; @@ -921,7 +923,7 @@ printTable(const char *title, unsigned int col_count = 0, row_count = 0, lines; - const char * const *ptr; + const char *const * ptr; int result; struct winsize screen_size; @@ -1010,13 +1012,13 @@ printTable(const char *title, void -printQuery(const PGresult *result, const printQueryOpt * opt, FILE *fout) +printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout) { int nfields; const char **headers; const char **cells; - char **footers; - char *align; + char **footers; + char *align; int i; /* extract headers */ @@ -1102,8 +1104,8 @@ printQuery(const PGresult *result, const printQueryOpt * opt, FILE *fout) /* call table printer */ printTable(opt->title, headers, cells, - footers ? (const char * const *)footers : (const char * const *)(opt->footers), - align, &opt->topt, fout); + footers ? (const char *const *) footers : (const char *const *) (opt->footers), + align, &opt->topt, fout); free(headers); free(cells); diff --git a/src/bin/psql/print.h b/src/bin/psql/print.h index 4706b8fba02..d2c8980ba78 100644 --- a/src/bin/psql/print.h +++ b/src/bin/psql/print.h @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/print.h,v 1.7 2000/02/16 13:15:26 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/print.h,v 1.8 2000/04/12 17:16:23 momjian Exp $ */ #ifndef PRINT_H #define PRINT_H @@ -32,9 +32,10 @@ typedef struct _printTableOpt unsigned short int border; /* Print a border around the table. * 0=none, 1=dividing lines, 2=full */ char *fieldSep; /* field separator for unaligned text mode */ - char *recordSep; /* record separator for unaligned text mode */ + char *recordSep; /* record separator for unaligned text + * mode */ char *tableAttr; /* attributes for HTML <table ...> */ -} printTableOpt; +} printTableOpt; /* @@ -48,10 +49,10 @@ typedef struct _printTableOpt * - align is an 'l' or an 'r' for every column, if the output format needs it. * (You must specify this long enough. Otherwise anything could happen.) */ -void printTable(const char *title, const char * const * headers, - const char * const * cells, const char * const * footers, - const char *align, - const printTableOpt * opt, FILE *fout); +void printTable(const char *title, const char *const * headers, + const char *const * cells, const char *const * footers, + const char *align, + const printTableOpt *opt, FILE *fout); @@ -63,7 +64,7 @@ typedef struct _printQueryOpt char *title; /* override title */ char **footers; /* override footer (default is "(xx * rows)") */ -} printQueryOpt; +} printQueryOpt; /* * Use this to print query results @@ -71,7 +72,7 @@ typedef struct _printQueryOpt * It calls the printTable above with all the things set straight. */ void -printQuery(const PGresult *result, const printQueryOpt * opt, FILE *fout); + printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout); #endif /* PRINT_H */ diff --git a/src/bin/psql/prompt.c b/src/bin/psql/prompt.c index b8b59eb15c5..9901b21652b 100644 --- a/src/bin/psql/prompt.c +++ b/src/bin/psql/prompt.c @@ -3,8 +3,8 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/prompt.c,v 1.11 2000/03/11 13:56:24 petere Exp $ - */ + * $Header: /cvsroot/pgsql/src/bin/psql/prompt.c,v 1.12 2000/04/12 17:16:23 momjian Exp $ + */ #include "postgres.h" #include "prompt.h" @@ -32,9 +32,9 @@ * (might not be completely multibyte safe) * * Defined interpolations are: - * %M - database server "hostname.domainname" (or "localhost" if this + * %M - database server "hostname.domainname" (or "localhost" if this * information is not available) - * %m - like %M, but hostname only (before first dot) + * %m - like %M, but hostname only (before first dot) * %> - database server port number * %n - database user name * %/ - current database @@ -62,47 +62,48 @@ */ /* - * We need hostname information, only if connection is via UNIX socket + * We need hostname information, only if connection is via UNIX socket */ #if !defined(WIN32) && !defined(__CYGWIN32__) && !defined(__QNX__) #define DOMAINNAME 1 #define HOSTNAME 2 -/* - * Return full hostname for localhost. +/* + * Return full hostname for localhost. * - informations are init only in firts time - not queries DNS or NIS - * for every localhost() call + * for every localhost() call */ static char * -localhost(int type, char *buf, int siz) -{ - static struct hostent *hp = NULL; - static int err = 0; - - if (hp==NULL && err==0) - { - char hname[256]; - +localhost(int type, char *buf, int siz) +{ + static struct hostent *hp = NULL; + static int err = 0; + + if (hp == NULL && err == 0) + { + char hname[256]; + if (gethostname(hname, 256) == 0) { if (!(hp = gethostbyname(hname))) - err = 1; + err = 1; } else - err = 1; + err = 1; } - - if (hp==NULL) + + if (hp == NULL) return strncpy(buf, "localhost", siz); - + strncpy(buf, hp->h_name, siz); /* full aaa.bbb.ccc */ - - if (type==HOSTNAME) + + if (type == HOSTNAME) buf[strcspn(buf, ".")] = '\0'; - - return buf; + + return buf; } + #endif char * @@ -172,20 +173,21 @@ get_prompt(promptStatus_t status) buf[strcspn(buf, ".")] = '\0'; } /* UNIX socket */ -#if !defined(WIN32) && !defined(__CYGWIN32__) && !defined(__QNX__) - else { - if (*p == 'm') +#if !defined(WIN32) && !defined(__CYGWIN32__) && !defined(__QNX__) + else + { + if (*p == 'm') localhost(HOSTNAME, buf, MAX_PROMPT_SIZE); else localhost(DOMAINNAME, buf, MAX_PROMPT_SIZE); } -#endif +#endif } break; /* DB server port number */ case '>': if (pset.db && PQport(pset.db)) - strncpy(buf, PQport(pset.db), MAX_PROMPT_SIZE); + strncpy(buf, PQport(pset.db), MAX_PROMPT_SIZE); break; /* DB server user name */ case 'n': @@ -236,9 +238,9 @@ get_prompt(promptStatus_t status) case PROMPT_COMMENT: buf[0] = '*'; break; - case PROMPT_PAREN: - buf[0] = '('; - break; + case PROMPT_PAREN: + buf[0] = '('; + break; default: buf[0] = '\0'; break; diff --git a/src/bin/psql/prompt.h b/src/bin/psql/prompt.h index 46d3dab93ba..0c0c209ff30 100644 --- a/src/bin/psql/prompt.h +++ b/src/bin/psql/prompt.h @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/prompt.h,v 1.7 2000/02/16 13:15:26 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/prompt.h,v 1.8 2000/04/12 17:16:23 momjian Exp $ */ #ifndef PROMPT_H #define PROMPT_H @@ -15,10 +15,10 @@ typedef enum _promptStatus PROMPT_COMMENT, PROMPT_SINGLEQUOTE, PROMPT_DOUBLEQUOTE, - PROMPT_PAREN, + PROMPT_PAREN, PROMPT_COPY -} promptStatus_t; +} promptStatus_t; -char *get_prompt(promptStatus_t status); +char *get_prompt(promptStatus_t status); #endif /* PROMPT_H */ diff --git a/src/bin/psql/settings.h b/src/bin/psql/settings.h index d56b0c77e9b..d5d306b1586 100644 --- a/src/bin/psql/settings.h +++ b/src/bin/psql/settings.h @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/settings.h,v 1.9 2000/02/16 13:15:26 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/settings.h,v 1.10 2000/04/12 17:16:23 momjian Exp $ */ #ifndef SETTINGS_H #define SETTINGS_H @@ -25,7 +25,7 @@ typedef struct _psqlSettings { PGconn *db; /* connection to backend */ - int encoding; + int encoding; FILE *queryFout; /* where to send the query results */ bool queryFoutPipe; /* queryFout is from a popen() */ @@ -44,12 +44,12 @@ typedef struct _psqlSettings * loop */ bool cur_cmd_interactive; - char *progname; /* in case you renamed psql */ - char *inputfile; /* for error reporting */ - unsigned lineno; /* also for error reporting */ + char *progname; /* in case you renamed psql */ + char *inputfile; /* for error reporting */ + unsigned lineno; /* also for error reporting */ - bool issuper; /* is the current user a superuser? - (used to form the prompt) */ + bool issuper; /* is the current user a superuser? (used + * to form the prompt) */ } PsqlSettings; extern PsqlSettings pset; diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c index e0e3ea4a1c2..74a3d216fc9 100644 --- a/src/bin/psql/startup.c +++ b/src/bin/psql/startup.c @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/startup.c,v 1.28 2000/03/18 22:48:29 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/startup.c,v 1.29 2000/04/12 17:16:23 momjian Exp $ */ #include "postgres.h" @@ -11,11 +11,11 @@ #ifndef WIN32 #include <unistd.h> -#else /* WIN32 */ +#else /* WIN32 */ #include <io.h> #include <windows.h> #include <win32.h> -#endif /* WIN32 */ +#endif /* WIN32 */ #ifdef HAVE_GETOPT_H #include <getopt.h> @@ -70,17 +70,17 @@ struct adhoc_opts enum _actions action; char *action_string; bool no_readline; - bool no_psqlrc; + bool no_psqlrc; }; static void -parse_psql_options(int argc, char *argv[], struct adhoc_opts * options); + parse_psql_options(int argc, char *argv[], struct adhoc_opts * options); static void -process_psqlrc(void); + process_psqlrc(void); static void -showVersion(void); + showVersion(void); @@ -99,27 +99,27 @@ main(int argc, char *argv[]) char *password = NULL; bool need_pass; - if (!strrchr(argv[0], SEP_CHAR)) - pset.progname = argv[0]; - else - pset.progname = strrchr(argv[0], SEP_CHAR) + 1; + if (!strrchr(argv[0], SEP_CHAR)) + pset.progname = argv[0]; + else + pset.progname = strrchr(argv[0], SEP_CHAR) + 1; pset.cur_cmd_source = stdin; pset.cur_cmd_interactive = false; - pset.encoding = PQenv2encoding(); + pset.encoding = PQenv2encoding(); pset.vars = CreateVariableSpace(); - if (!pset.vars) - { - fprintf(stderr, "%s: out of memory\n", pset.progname); - exit(EXIT_FAILURE); - } + if (!pset.vars) + { + fprintf(stderr, "%s: out of memory\n", pset.progname); + exit(EXIT_FAILURE); + } pset.popt.topt.format = PRINT_ALIGNED; pset.queryFout = stdout; pset.popt.topt.border = 1; pset.popt.topt.pager = true; - SetVariable(pset.vars, "VERSION", PG_VERSION_STR); + SetVariable(pset.vars, "VERSION", PG_VERSION_STR); pset.notty = (!isatty(fileno(stdin)) || !isatty(fileno(stdout))); @@ -132,18 +132,19 @@ main(int argc, char *argv[]) parse_psql_options(argc, argv, &options); - if (!pset.popt.topt.fieldSep) - pset.popt.topt.fieldSep = xstrdup(DEFAULT_FIELD_SEP); - if (!pset.popt.topt.recordSep) - pset.popt.topt.recordSep = xstrdup(DEFAULT_RECORD_SEP); + if (!pset.popt.topt.fieldSep) + pset.popt.topt.fieldSep = xstrdup(DEFAULT_FIELD_SEP); + if (!pset.popt.topt.recordSep) + pset.popt.topt.recordSep = xstrdup(DEFAULT_RECORD_SEP); if (options.username) { - /* - * The \001 is a hack to support the deprecated -u option which issues - * a username prompt. The recommended option is -U followed by the name - * on the command line. - */ + + /* + * The \001 is a hack to support the deprecated -u option which + * issues a username prompt. The recommended option is -U followed + * by the name on the command line. + */ if (strcmp(options.username, "\001") == 0) username = simple_prompt("Username: ", 100, true); else @@ -158,8 +159,8 @@ main(int argc, char *argv[]) { need_pass = false; pset.db = PQsetdbLogin(options.host, options.port, NULL, NULL, - options.action == ACT_LIST_DB ? "template1" : options.dbname, - username, password); + options.action == ACT_LIST_DB ? "template1" : options.dbname, + username, password); if (PQstatus(pset.db) == CONNECTION_BAD && strcmp(PQerrorMessage(pset.db), "fe_sendauth: no password supplied\n") == 0) @@ -176,17 +177,18 @@ main(int argc, char *argv[]) if (PQstatus(pset.db) == CONNECTION_BAD) { - fprintf(stderr, "%s: %s", pset.progname, PQerrorMessage(pset.db)); + fprintf(stderr, "%s: %s", pset.progname, PQerrorMessage(pset.db)); PQfinish(pset.db); exit(EXIT_BADCONN); } - PQsetNoticeProcessor(pset.db, NoticeProcessor, NULL); - /* - * We need to save the encoding because we want to have it - * available even if the database connection goes bad. - */ - pset.encoding = PQclientEncoding(pset.db); + PQsetNoticeProcessor(pset.db, NoticeProcessor, NULL); + + /* + * We need to save the encoding because we want to have it available + * even if the database connection goes bad. + */ + pset.encoding = PQclientEncoding(pset.db); if (options.action == ACT_LIST_DB) { @@ -196,79 +198,82 @@ main(int argc, char *argv[]) exit(success ? EXIT_SUCCESS : EXIT_FAILURE); } - SetVariable(pset.vars, "DBNAME", PQdb(pset.db)); - SetVariable(pset.vars, "USER", PQuser(pset.db)); - SetVariable(pset.vars, "HOST", PQhost(pset.db)); - SetVariable(pset.vars, "PORT", PQport(pset.db)); - SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding)); + SetVariable(pset.vars, "DBNAME", PQdb(pset.db)); + SetVariable(pset.vars, "USER", PQuser(pset.db)); + SetVariable(pset.vars, "HOST", PQhost(pset.db)); + SetVariable(pset.vars, "PORT", PQport(pset.db)); + SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding)); #ifndef WIN32 pqsignal(SIGINT, handle_sigint); /* control-C => cancel */ #endif /* - * Now find something to do - */ + * Now find something to do + */ /* - * process file given by -f - */ + * process file given by -f + */ if (options.action == ACT_FILE) - { - if (!options.no_psqlrc) - process_psqlrc(); + { + if (!options.no_psqlrc) + process_psqlrc(); successResult = process_file(options.action_string); - } + } + /* - * process slash command if one was given to -c - */ + * process slash command if one was given to -c + */ else if (options.action == ACT_SINGLE_SLASH) - { - const char * value; + { + const char *value; - if ((value = GetVariable(pset.vars, "ECHO")) && strcmp(value, "all")==0) - puts(options.action_string); + if ((value = GetVariable(pset.vars, "ECHO")) && strcmp(value, "all") == 0) + puts(options.action_string); successResult = HandleSlashCmds(options.action_string, NULL, NULL) != CMD_ERROR - ? EXIT_SUCCESS : EXIT_FAILURE; - } + ? EXIT_SUCCESS : EXIT_FAILURE; + } + /* - * If the query given to -c was a normal one, send it - */ + * If the query given to -c was a normal one, send it + */ else if (options.action == ACT_SINGLE_QUERY) - { - const char * value; + { + const char *value; - if ((value = GetVariable(pset.vars, "ECHO")) && strcmp(value, "all")==0) - puts(options.action_string); + if ((value = GetVariable(pset.vars, "ECHO")) && strcmp(value, "all") == 0) + puts(options.action_string); successResult = SendQuery(options.action_string) - ? EXIT_SUCCESS : EXIT_FAILURE; - } + ? EXIT_SUCCESS : EXIT_FAILURE; + } + /* - * or otherwise enter interactive main loop - */ + * or otherwise enter interactive main loop + */ else - { - pset.issuper = test_superuser(PQuser(pset.db)); - if (!QUIET() && !pset.notty) - { - printf("Welcome to %s, the PostgreSQL interactive terminal.\n\n" - "Type: \\copyright for distribution terms\n" - " \\h for help with SQL commands\n" - " \\? for help on internal slash commands\n" - " \\g or terminate with semicolon to execute query\n" - " \\q to quit\n\n", pset.progname); - } - - SetVariable(pset.vars, "PROMPT1", DEFAULT_PROMPT1); - SetVariable(pset.vars, "PROMPT2", DEFAULT_PROMPT2); - SetVariable(pset.vars, "PROMPT3", DEFAULT_PROMPT3); - if (!options.no_psqlrc) - process_psqlrc(); - if (!pset.notty) - initializeInput(options.no_readline ? 0 : 1); + { + pset.issuper = test_superuser(PQuser(pset.db)); + if (!QUIET() && !pset.notty) + { + printf("Welcome to %s, the PostgreSQL interactive terminal.\n\n" + "Type: \\copyright for distribution terms\n" + " \\h for help with SQL commands\n" + " \\? for help on internal slash commands\n" + " \\g or terminate with semicolon to execute query\n" + " \\q to quit\n\n", pset.progname); + } + + SetVariable(pset.vars, "PROMPT1", DEFAULT_PROMPT1); + SetVariable(pset.vars, "PROMPT2", DEFAULT_PROMPT2); + SetVariable(pset.vars, "PROMPT3", DEFAULT_PROMPT3); + if (!options.no_psqlrc) + process_psqlrc(); + if (!pset.notty) + initializeInput(options.no_readline ? 0 : 1); successResult = MainLoop(stdin); - } + } /* clean up */ PQfinish(pset.db); @@ -286,8 +291,10 @@ main(int argc, char *argv[]) #ifdef WIN32 /* getopt is not in the standard includes on Win32 */ int getopt(int, char *const[], const char *); + /* And it requires progname to be set */ -char *__progname = "psql"; +char *__progname = "psql"; + #endif static void @@ -295,8 +302,8 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options) { #ifdef HAVE_GETOPT_LONG static struct option long_options[] = - { - {"echo-all", no_argument, NULL, 'a'}, + { + {"echo-all", no_argument, NULL, 'a'}, {"no-align", no_argument, NULL, 'A'}, {"command", required_argument, NULL, 'c'}, {"dbname", required_argument, NULL, 'd'}, @@ -311,7 +318,7 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options) {"port", required_argument, NULL, 'p'}, {"pset", required_argument, NULL, 'P'}, {"quiet", no_argument, NULL, 'q'}, - {"record-separator", required_argument, NULL, 'R'}, + {"record-separator", required_argument, NULL, 'R'}, {"single-step", no_argument, NULL, 's'}, {"single-line", no_argument, NULL, 'S'}, {"tuples-only", no_argument, NULL, 't'}, @@ -322,29 +329,31 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options) {"version", no_argument, NULL, 'V'}, {"password", no_argument, NULL, 'W'}, {"expanded", no_argument, NULL, 'x'}, - {"no-psqlrc", no_argument, NULL, 'X'}, + {"no-psqlrc", no_argument, NULL, 'X'}, {"help", no_argument, NULL, '?'}, }; int optindex; -#endif /* HAVE_GETOPT_LONG */ + +#endif /* HAVE_GETOPT_LONG */ extern char *optarg; extern int optind; int c; - bool used_old_u_option = false; + bool used_old_u_option = false; memset(options, 0, sizeof *options); #ifdef HAVE_GETOPT_LONG while ((c = getopt_long(argc, argv, "aAc:d:eEf:F:lh:Hno:p:P:qRsStT:uU:v:VWxX?", long_options, &optindex)) != -1) -#else /* not HAVE_GETOPT_LONG */ +#else /* not HAVE_GETOPT_LONG */ + /* * Be sure to leave the '-' in here, so we can catch accidental long * options. */ while ((c = getopt(argc, argv, "aAc:d:eEf:F:lh:Hno:p:P:qRsStT:uU:v:VWxX?-")) != -1) -#endif /* not HAVE_GETOPT_LONG */ +#endif /* not HAVE_GETOPT_LONG */ { switch (c) { @@ -426,9 +435,9 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options) case 'q': SetVariableBool(pset.vars, "QUIET"); break; - case 'R': - pset.popt.topt.recordSep = xstrdup(optarg); - break; + case 'R': + pset.popt.topt.recordSep = xstrdup(optarg); + break; case 's': SetVariableBool(pset.vars, "SINGLESTEP"); break; @@ -443,9 +452,10 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options) break; case 'u': pset.getPassword = true; - options->username = "\001"; /* hopefully nobody has that username */ - /* this option is out */ - used_old_u_option = true; + options->username = "\001"; /* hopefully nobody has + * that username */ + /* this option is out */ + used_old_u_option = true; break; case 'U': options->username = optarg; @@ -462,7 +472,7 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options) if (!DeleteVariable(pset.vars, value)) { fprintf(stderr, "%s: could not delete variable %s\n", - pset.progname, value); + pset.progname, value); exit(EXIT_FAILURE); } } @@ -472,7 +482,7 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options) if (!SetVariable(pset.vars, value, equal_loc + 1)) { fprintf(stderr, "%s: could not set variable %s\n", - pset.progname, value); + pset.progname, value); exit(EXIT_FAILURE); } } @@ -489,22 +499,22 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options) case 'x': pset.popt.topt.expanded = true; break; - case 'X': - options->no_psqlrc = true; - break; + case 'X': + options->no_psqlrc = true; + break; case '?': - /* Actual help option given */ - if (strcmp(argv[optind-1], "-?")==0 || strcmp(argv[optind-1], "--help")==0) - { - usage(); - exit(EXIT_SUCCESS); - } - /* unknown option reported by getopt */ - else - { - fputs("Try -? for help.\n", stderr); - exit(EXIT_FAILURE); - } + /* Actual help option given */ + if (strcmp(argv[optind - 1], "-?") == 0 || strcmp(argv[optind - 1], "--help") == 0) + { + usage(); + exit(EXIT_SUCCESS); + } + /* unknown option reported by getopt */ + else + { + fputs("Try -? for help.\n", stderr); + exit(EXIT_FAILURE); + } break; #ifndef HAVE_GETOPT_LONG case '-': @@ -532,13 +542,13 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options) options->username = argv[optind]; else if (!QUIET()) fprintf(stderr, "%s: warning: extra option %s ignored\n", - pset.progname, argv[optind]); + pset.progname, argv[optind]); optind++; } - if (used_old_u_option && !QUIET()) - fprintf(stderr, "%s: Warning: The -u option is deprecated. Use -U.\n", pset.progname); + if (used_old_u_option && !QUIET()) + fprintf(stderr, "%s: Warning: The -u option is deprecated. Use -U.\n", pset.progname); } @@ -565,7 +575,7 @@ process_psqlrc(void) psqlrc = malloc(strlen(home) + 20); if (!psqlrc) { - fprintf(stderr, "%s: out of memory\n", pset.progname); + fprintf(stderr, "%s: out of memory\n", pset.progname); exit(EXIT_FAILURE); } @@ -591,41 +601,41 @@ process_psqlrc(void) static void showVersion(void) { - puts("psql (PostgreSQL) " PG_RELEASE "." PG_VERSION "." PG_SUBVERSION); + puts("psql (PostgreSQL) " PG_RELEASE "." PG_VERSION "." PG_SUBVERSION); #if defined(USE_READLINE) || defined (USE_HISTORY) || defined(MULTIBYTE) - fputs("contains ", stdout); + fputs("contains ", stdout); #ifdef USE_READLINE - fputs("readline", stdout); + fputs("readline", stdout); #define _Feature #endif #ifdef USE_HISTORY #ifdef _Feature - fputs(", ", stdout); + fputs(", ", stdout); #else #define _Feature #endif - fputs("history", stdout); + fputs("history", stdout); #endif #ifdef MULTIBYTE #ifdef _Feature - fputs(", ", stdout); + fputs(", ", stdout); #else #define _Feature #endif - fputs("multibyte", stdout); + fputs("multibyte", stdout); #endif - + #undef _Feature - puts(" support"); + puts(" support"); #endif - puts("Portions Copyright (c) 1996-2000, PostgreSQL, Inc"); - puts("Portions Copyright (c) 1996 Regents of the University of California"); - puts("Read the file COPYRIGHT or use the command \\copyright to see the"); - puts("usage and distribution terms."); + puts("Portions Copyright (c) 1996-2000, PostgreSQL, Inc"); + puts("Portions Copyright (c) 1996 Regents of the University of California"); + puts("Read the file COPYRIGHT or use the command \\copyright to see the"); + puts("usage and distribution terms."); } diff --git a/src/bin/psql/stringutils.c b/src/bin/psql/stringutils.c index 95b05010273..215572e5f1f 100644 --- a/src/bin/psql/stringutils.c +++ b/src/bin/psql/stringutils.c @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/stringutils.c,v 1.25 2000/02/16 13:15:26 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/stringutils.c,v 1.26 2000/04/12 17:16:23 momjian Exp $ */ #include "postgres.h" #include "stringutils.h" @@ -52,7 +52,7 @@ strtokx(const char *s, char *cp = NULL; #ifndef MULTIBYTE - (void)encoding; /*not used*/ + (void) encoding; /* not used */ #endif if (s) diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 5aec29dc89c..b7912709e36 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.16 2000/03/17 05:29:06 tgl Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.17 2000/04/12 17:16:23 momjian Exp $ */ /*----------- @@ -24,12 +24,12 @@ BUGS: * If you split your queries across lines, this whole things gets confused. - (To fix this, one would have to read psql's query buffer rather than - readline's line buffer, which would require some major revisions of - things.) + (To fix this, one would have to read psql's query buffer rather than + readline's line buffer, which would require some major revisions of + things.) * Table or attribute names with spaces in it will equally confuse it. * Quotes, parenthesis, and other funny characters are not handled all that - gracefully. + gracefully. -------------*/ #include "postgres.h" @@ -40,7 +40,7 @@ /* If we don't have this, we might as well forget about the whole thing: */ #ifdef USE_READLINE -#include <ctype.h> /* toupper */ +#include <ctype.h> /* toupper */ #ifdef USE_ASSERT_CHECKING #include <assert.h> #endif @@ -51,49 +51,56 @@ #include "settings.h" #if defined(HAVE_FILENAME_COMPLETION_FUNCTION) && !defined(HAVE_FILENAME_COMPLETION_FUNCTION_DECL) -char * filename_completion_function (char *, int); +char *filename_completion_function(char *, int); + #endif #define BUF_SIZE 2048 -#define ERROR_QUERY_TOO_LONG /* empty */ +#define ERROR_QUERY_TOO_LONG /* empty */ /* Forward declaration of functions */ -static char ** psql_completion(char *text, int start, int end); -static char * create_command_generator(char *text, int state); -static char * complete_from_query(char *text, int state); -static char * complete_from_const(char *text, int state); -static char * complete_from_list(char *text, int state); - -static PGresult * exec_query(char * query); -char * quote_file_name(char *text, int match_type, char * quote_pointer); +static char **psql_completion(char *text, int start, int end); +static char *create_command_generator(char *text, int state); +static char *complete_from_query(char *text, int state); +static char *complete_from_const(char *text, int state); +static char *complete_from_list(char *text, int state); + +static PGresult *exec_query(char *query); +char *quote_file_name(char *text, int match_type, char *quote_pointer); + /*static char * dequote_file_name(char *text, char quote_char);*/ -static char * previous_word(int point, int skip); +static char *previous_word(int point, int skip); /* These variables are used to pass information into the completion functions. Realizing that this is the cardinal sin of programming, I don't see a better way. */ -char * completion_charp; /* if you need to pass a string */ -char ** completion_charpp; /* if you need to pass a list of strings */ -char * completion_info_charp; /* if you need to pass another string */ +char *completion_charp; /* if you need to pass a string */ +char **completion_charpp; /* if you need to pass a list of strings */ +char *completion_info_charp; /* if you need to pass another + * string */ /* Store how many records from a database query we want to return at most (implemented via SELECT ... LIMIT xx). */ -static int completion_max_records; +static int completion_max_records; /* Initialize the readline library for our purposes. */ -void initialize_readline(void) +void +initialize_readline(void) { - rl_readline_name = pset.progname; - rl_attempted_completion_function = psql_completion; + rl_readline_name = pset.progname; + rl_attempted_completion_function = psql_completion; + + rl_special_prefixes = "()'"; + rl_basic_word_break_characters = "\t\n\"'`@$><=;|&{ "; - rl_special_prefixes = "()'"; - rl_basic_word_break_characters = "\t\n\"'`@$><=;|&{ "; + completion_max_records = 100; - completion_max_records = 100; - /* There is a variable rl_completion_query_items for this but apparently - it's not defined everywhere. */ + /* + * There is a variable rl_completion_query_items for this but + * apparently it's not defined everywhere. + */ } @@ -103,27 +110,29 @@ void initialize_readline(void) If you change the order here or insert things, make sure to also adjust the referencing macros below. */ -typedef struct { - char * name; - char * query; +typedef struct +{ + char *name; + char *query; } pgsql_thing_t; pgsql_thing_t words_after_create[] = { - { "AGGREGATE", "SELECT distinct aggname FROM pg_aggregate WHERE substr(aggname,1,%d)='%s'" }, - { "DATABASE", "SELECT datname FROM pg_database WHERE substr(datname,1,%d)='%s'" }, - { "FUNCTION", "SELECT distinct proname FROM pg_proc WHERE substr(proname,1,%d)='%s'" }, - { "INDEX", "SELECT relname FROM pg_class WHERE relkind='i' and substr(relname,1,%d)='%s'" }, - { "OPERATOR", NULL }, /* Querying for this is probably not such a good idea. */ - { "RULE", "SELECT rulename FROM pg_rules WHERE substr(rulename,1,%d)='%s'" }, - { "SEQUENCE", "SELECT relname FROM pg_class WHERE relkind='S' and substr(relname,1,%d)='%s'" }, - { "TABLE", "SELECT relname FROM pg_class WHERE relkind='r' and substr(relname,1,%d)='%s'" }, - { "TEMP", NULL }, /* for CREATE TEMP TABLE ... */ - { "TRIGGER", "SELECT tgname FROM pg_trigger WHERE substr(tgname,1,%d)='%s'" }, - { "TYPE", "SELECT typname FROM pg_type WHERE substr(typname,1,%d)='%s'" }, - { "UNIQUE", NULL }, /* for CREATE UNIQUE INDEX ... */ - { "USER", "SELECT usename FROM pg_user WHERE substr(usename,1,%d)='%s'" }, - { "VIEW", "SELECT viewname FROM pg_views WHERE substr(viewname,1,%d)='%s'" }, - { NULL, NULL } /* end of list */ + {"AGGREGATE", "SELECT distinct aggname FROM pg_aggregate WHERE substr(aggname,1,%d)='%s'"}, + {"DATABASE", "SELECT datname FROM pg_database WHERE substr(datname,1,%d)='%s'"}, + {"FUNCTION", "SELECT distinct proname FROM pg_proc WHERE substr(proname,1,%d)='%s'"}, + {"INDEX", "SELECT relname FROM pg_class WHERE relkind='i' and substr(relname,1,%d)='%s'"}, + {"OPERATOR", NULL}, /* Querying for this is probably not such + * a good idea. */ + {"RULE", "SELECT rulename FROM pg_rules WHERE substr(rulename,1,%d)='%s'"}, + {"SEQUENCE", "SELECT relname FROM pg_class WHERE relkind='S' and substr(relname,1,%d)='%s'"}, + {"TABLE", "SELECT relname FROM pg_class WHERE relkind='r' and substr(relname,1,%d)='%s'"}, + {"TEMP", NULL}, /* for CREATE TEMP TABLE ... */ + {"TRIGGER", "SELECT tgname FROM pg_trigger WHERE substr(tgname,1,%d)='%s'"}, + {"TYPE", "SELECT typname FROM pg_type WHERE substr(typname,1,%d)='%s'"}, + {"UNIQUE", NULL}, /* for CREATE UNIQUE INDEX ... */ + {"USER", "SELECT usename FROM pg_user WHERE substr(usename,1,%d)='%s'"}, + {"VIEW", "SELECT viewname FROM pg_views WHERE substr(viewname,1,%d)='%s'"}, + {NULL, NULL} /* end of list */ }; @@ -157,22 +166,27 @@ do {completion_charp = Query_for_list_of_attributes; completion_info_charp = tab is some partially obscure list format that can be generated by the readline libraries completion_matches() function, so we don't have to worry about it. */ -char ** psql_completion(char *text, int start, int end) +char ** +psql_completion(char *text, int start, int end) { - /* This is the variable we'll return. */ - char **matches = NULL; - /* These are going to contain some scannage of the input line. */ - char *prev_wd, *prev2_wd, *prev3_wd, *prev4_wd; - - static char * sql_commands[] = { - "ABORT", "ALTER", "BEGIN", "CLOSE", "CLUSTER", "COMMIT", "COPY", - "CREATE", "DECLARE", "DELETE", "DROP", "EXPLAIN", "FETCH", "GRANT", - "INSERT", "LISTEN", "LOAD", "LOCK", "MOVE", "NOTIFY", "RESET", - "REVOKE", "ROLLBACK", "SELECT", "SET", "SHOW", "UNLISTEN", "UPDATE", - "VACUUM", NULL - }; - - static char * pgsql_variables[] = { + /* This is the variable we'll return. */ + char **matches = NULL; + + /* These are going to contain some scannage of the input line. */ + char *prev_wd, + *prev2_wd, + *prev3_wd, + *prev4_wd; + + static char *sql_commands[] = { + "ABORT", "ALTER", "BEGIN", "CLOSE", "CLUSTER", "COMMIT", "COPY", + "CREATE", "DECLARE", "DELETE", "DROP", "EXPLAIN", "FETCH", "GRANT", + "INSERT", "LISTEN", "LOAD", "LOCK", "MOVE", "NOTIFY", "RESET", + "REVOKE", "ROLLBACK", "SELECT", "SET", "SHOW", "UNLISTEN", "UPDATE", + "VACUUM", NULL + }; + + static char *pgsql_variables[] = { /* these SET arguments are known in gram.y */ "TRANSACTION ISOLATION LEVEL", "NAMES", @@ -198,390 +212,468 @@ char ** psql_completion(char *text, int start, int end) "max_expr_depth", "XactIsoLevel", "PG_Options", - NULL - }; + NULL + }; - static char * backslash_commands[] = { - "\\connect", "\\copy", "\\d", "\\di", "\\di", "\\ds", "\\dS", "\\dv", - "\\da", "\\df", "\\do", "\\dt", "\\e", "\\echo", "\\encoding", - "\\g", "\\h", "\\i", "\\l", - "\\lo_import", "\\lo_export", "\\lo_list", "\\lo_unlink", - "\\o", "\\p", "\\pset", "\\q", "\\qecho", "\\r", "\\set", "\\t", "\\unset", - "\\x", "\\w", "\\z", "\\!", NULL - }; + static char *backslash_commands[] = { + "\\connect", "\\copy", "\\d", "\\di", "\\di", "\\ds", "\\dS", "\\dv", + "\\da", "\\df", "\\do", "\\dt", "\\e", "\\echo", "\\encoding", + "\\g", "\\h", "\\i", "\\l", + "\\lo_import", "\\lo_export", "\\lo_list", "\\lo_unlink", + "\\o", "\\p", "\\pset", "\\q", "\\qecho", "\\r", "\\set", "\\t", "\\unset", + "\\x", "\\w", "\\z", "\\!", NULL + }; - (void)end; /* not used */ + (void) end; /* not used */ #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER - rl_completion_append_character = ' '; + rl_completion_append_character = ' '; #endif - /* Clear a few things. */ - completion_charp = NULL; - completion_charpp = NULL; - completion_info_charp = NULL; - - /* Scan the input line before our current position for the last four words. - According to those we'll make some smart decisions on what the user is - probably intending to type. - TODO: Use strtokx() to do this. - */ - prev_wd = previous_word(start,0); - prev2_wd = previous_word(start,1); - prev3_wd = previous_word(start,2); - prev4_wd = previous_word(start,3); - - /* If a backslash command was started, continue */ - if (text[0]=='\\') - COMPLETE_WITH_LIST(backslash_commands); - - /* If no previous word, suggest one of the basic sql commands */ - else if (!prev_wd) - COMPLETE_WITH_LIST(sql_commands); + /* Clear a few things. */ + completion_charp = NULL; + completion_charpp = NULL; + completion_info_charp = NULL; + + /* + * Scan the input line before our current position for the last four + * words. According to those we'll make some smart decisions on what + * the user is probably intending to type. TODO: Use strtokx() to do + * this. + */ + prev_wd = previous_word(start, 0); + prev2_wd = previous_word(start, 1); + prev3_wd = previous_word(start, 2); + prev4_wd = previous_word(start, 3); + + /* If a backslash command was started, continue */ + if (text[0] == '\\') + COMPLETE_WITH_LIST(backslash_commands); + + /* If no previous word, suggest one of the basic sql commands */ + else if (!prev_wd) + COMPLETE_WITH_LIST(sql_commands); /* CREATE or DROP */ - /* complete with something you can create or drop */ - else if( strcasecmp(prev_wd, "CREATE") == 0 || strcasecmp(prev_wd, "DROP") == 0 ) - matches = completion_matches(text, create_command_generator); + /* complete with something you can create or drop */ + else if (strcasecmp(prev_wd, "CREATE") == 0 || strcasecmp(prev_wd, "DROP") == 0) + matches = completion_matches(text, create_command_generator); /* ALTER */ - /* complete with what you can alter (TABLE or USER) */ - else if( strcasecmp(prev_wd, "ALTER") == 0 ) { - char * list_ALTER[] = { "TABLE", "USER", NULL }; - COMPLETE_WITH_LIST(list_ALTER); - } - /* If we detect ALTER TABLE <name>, suggest either "ADD" or "RENAME" */ - else if( strcasecmp(prev3_wd, "ALTER")==0 && strcasecmp(prev2_wd, "TABLE")==0 ) { - char * list_ALTER2[] = { "ADD", "RENAME", NULL }; - COMPLETE_WITH_LIST(list_ALTER2); - } - /* If we have TABLE <sth> ADD|RENAME, provide list of columns */ - else if( strcasecmp(prev3_wd, "TABLE")==0 && - (strcasecmp(prev_wd,"ADD")==0 || strcasecmp(prev_wd,"RENAME")==0) ) - COMPLETE_WITH_ATTR(prev2_wd); + /* complete with what you can alter (TABLE or USER) */ + else if (strcasecmp(prev_wd, "ALTER") == 0) + { + char *list_ALTER[] = {"TABLE", "USER", NULL}; + + COMPLETE_WITH_LIST(list_ALTER); + } + /* If we detect ALTER TABLE <name>, suggest either "ADD" or "RENAME" */ + else if (strcasecmp(prev3_wd, "ALTER") == 0 && strcasecmp(prev2_wd, "TABLE") == 0) + { + char *list_ALTER2[] = {"ADD", "RENAME", NULL}; + + COMPLETE_WITH_LIST(list_ALTER2); + } + /* If we have TABLE <sth> ADD|RENAME, provide list of columns */ + else if (strcasecmp(prev3_wd, "TABLE") == 0 && + (strcasecmp(prev_wd, "ADD") == 0 || strcasecmp(prev_wd, "RENAME") == 0)) + COMPLETE_WITH_ATTR(prev2_wd); /* CLUSTER */ - /* If the previous word is CLUSTER, produce list of indexes. */ - else if( strcasecmp(prev_wd, "CLUSTER") == 0 ) - COMPLETE_WITH_QUERY(Query_for_list_of_indexes); - /* If we have CLUSTER <sth>, then add "ON" */ - else if( strcasecmp(prev2_wd, "CLUSTER") == 0 ) - COMPLETE_WITH_CONST("ON"); - /* If we have CLUSTER <sth> ON, then add the correct tablename as well. */ - else if ( strcasecmp(prev3_wd, "CLUSTER")==0 && strcasecmp(prev_wd, "ON")==0 ) { - char query_buffer[BUF_SIZE]; /* Some room to build queries. */ - if(snprintf(query_buffer, BUF_SIZE, - "SELECT c1.relname FROM pg_class c1, pg_class c2, pg_index i WHERE c1.oid=i.indrelid and i.indexrelid=c2.oid and c2.relname='%s'", - prev2_wd) == -1) - ERROR_QUERY_TOO_LONG; - else - COMPLETE_WITH_QUERY(query_buffer); - } + /* If the previous word is CLUSTER, produce list of indexes. */ + else if (strcasecmp(prev_wd, "CLUSTER") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_indexes); + /* If we have CLUSTER <sth>, then add "ON" */ + else if (strcasecmp(prev2_wd, "CLUSTER") == 0) + COMPLETE_WITH_CONST("ON"); + + /* + * If we have CLUSTER <sth> ON, then add the correct tablename as + * well. + */ + else if (strcasecmp(prev3_wd, "CLUSTER") == 0 && strcasecmp(prev_wd, "ON") == 0) + { + char query_buffer[BUF_SIZE]; /* Some room to build + * queries. */ + + if (snprintf(query_buffer, BUF_SIZE, + "SELECT c1.relname FROM pg_class c1, pg_class c2, pg_index i WHERE c1.oid=i.indrelid and i.indexrelid=c2.oid and c2.relname='%s'", + prev2_wd) == -1) + ERROR_QUERY_TOO_LONG; + else + COMPLETE_WITH_QUERY(query_buffer); + } /* COPY */ - /* If we have COPY [BINARY] (which you'd have to type yourself), offer list of tables - (Also cover the analogous backslash command) */ - else if( strcasecmp(prev_wd, "COPY")==0 || - strcasecmp(prev_wd, "\\copy")==0 || - (strcasecmp(prev2_wd,"COPY")==0 && strcasecmp(prev_wd,"BINARY")==0) ) - COMPLETE_WITH_QUERY(Query_for_list_of_tables); - /* If we have COPY|BINARY <sth>, complete it with "TO" or "FROM" */ - else if( strcasecmp(prev2_wd, "COPY")==0 || - strcasecmp(prev2_wd, "\\copy")==0 || - strcasecmp(prev2_wd, "BINARY")==0 ) { - char * list_FROMTO[] = { "FROM", "TO", NULL }; - COMPLETE_WITH_LIST(list_FROMTO); - } + + /* + * If we have COPY [BINARY] (which you'd have to type yourself), offer + * list of tables (Also cover the analogous backslash command) + */ + else if (strcasecmp(prev_wd, "COPY") == 0 || + strcasecmp(prev_wd, "\\copy") == 0 || + (strcasecmp(prev2_wd, "COPY") == 0 && strcasecmp(prev_wd, "BINARY") == 0)) + COMPLETE_WITH_QUERY(Query_for_list_of_tables); + /* If we have COPY|BINARY <sth>, complete it with "TO" or "FROM" */ + else if (strcasecmp(prev2_wd, "COPY") == 0 || + strcasecmp(prev2_wd, "\\copy") == 0 || + strcasecmp(prev2_wd, "BINARY") == 0) + { + char *list_FROMTO[] = {"FROM", "TO", NULL}; + + COMPLETE_WITH_LIST(list_FROMTO); + } /* CREATE INDEX */ - /* First off we complete CREATE UNIQUE with "INDEX" */ - else if( strcasecmp(prev2_wd, "CREATE")==0 && strcasecmp(prev_wd, "UNIQUE")==0 ) - COMPLETE_WITH_CONST("INDEX"); - /* If we have CREATE|UNIQUE INDEX <sth>, then add "ON" */ - else if( strcasecmp(prev2_wd, "INDEX") == 0 && - (strcasecmp(prev3_wd,"CREATE")==0 || strcasecmp(prev3_wd,"UNIQUE")==0) ) - COMPLETE_WITH_CONST("ON"); - /* Complete ... INDEX <name> ON with a list of tables */ - else if( (strcasecmp(prev3_wd, "INDEX")==0 && strcasecmp(prev_wd, "ON")==0) || (0) ) - COMPLETE_WITH_QUERY(Query_for_list_of_tables); - /* Complete INDEX <name> ON <table> with a list of table columns (which should really be in parens) */ - else if( (strcasecmp(prev4_wd, "INDEX")==0 && strcasecmp(prev2_wd, "ON")==0) ) - COMPLETE_WITH_ATTR(prev_wd); - /* same if you put in USING */ - else if ((strcasecmp(prev4_wd,"ON")==0 && strcasecmp(prev2_wd,"USING")==0) ) - COMPLETE_WITH_ATTR(prev3_wd); - /* Complete USING with an index method */ - else if( strcasecmp(prev_wd, "USING")==0 ) { - char * index_mth[] = { "BTREE", "RTREE", "HASH", NULL }; - COMPLETE_WITH_LIST(index_mth); - } - + /* First off we complete CREATE UNIQUE with "INDEX" */ + else if (strcasecmp(prev2_wd, "CREATE") == 0 && strcasecmp(prev_wd, "UNIQUE") == 0) + COMPLETE_WITH_CONST("INDEX"); + /* If we have CREATE|UNIQUE INDEX <sth>, then add "ON" */ + else if (strcasecmp(prev2_wd, "INDEX") == 0 && + (strcasecmp(prev3_wd, "CREATE") == 0 || strcasecmp(prev3_wd, "UNIQUE") == 0)) + COMPLETE_WITH_CONST("ON"); + /* Complete ... INDEX <name> ON with a list of tables */ + else if ((strcasecmp(prev3_wd, "INDEX") == 0 && strcasecmp(prev_wd, "ON") == 0) || (0)) + COMPLETE_WITH_QUERY(Query_for_list_of_tables); + + /* + * Complete INDEX <name> ON <table> with a list of table columns + * (which should really be in parens) + */ + else if ((strcasecmp(prev4_wd, "INDEX") == 0 && strcasecmp(prev2_wd, "ON") == 0)) + COMPLETE_WITH_ATTR(prev_wd); + /* same if you put in USING */ + else if ((strcasecmp(prev4_wd, "ON") == 0 && strcasecmp(prev2_wd, "USING") == 0)) + COMPLETE_WITH_ATTR(prev3_wd); + /* Complete USING with an index method */ + else if (strcasecmp(prev_wd, "USING") == 0) + { + char *index_mth[] = {"BTREE", "RTREE", "HASH", NULL}; + + COMPLETE_WITH_LIST(index_mth); + } + /* CREATE RULE */ - /* Complete "CREATE RULE <sth>" with "AS" */ - else if( strcasecmp(prev3_wd,"CREATE")==0 && strcasecmp(prev2_wd,"RULE")==0 ) - COMPLETE_WITH_CONST("AS"); - /* Complete "CREATE RULE <sth> AS with "ON" */ - else if( strcasecmp(prev4_wd,"CREATE")==0 && - strcasecmp(prev3_wd,"RULE")==0 && - strcasecmp(prev_wd,"AS")==0 ) - COMPLETE_WITH_CONST("ON"); - /* Complete "RULE * AS ON" with SELECT|UPDATE|DELETE|INSERT */ - else if( strcasecmp(prev4_wd,"RULE")==0 && - strcasecmp(prev2_wd,"AS")==0 && - strcasecmp(prev_wd,"ON")==0 ) { - char * rule_events[] = { "SELECT", "UPDATE", "INSERT", "DELETE", NULL }; - COMPLETE_WITH_LIST(rule_events); - } - /* Complete "AS ON <sth with a 'T' :)>" with a "TO" */ - else if( strcasecmp(prev3_wd,"AS")==0 && - strcasecmp(prev2_wd,"ON")==0 && - (toupper(prev_wd[4])=='T' || toupper(prev_wd[5])=='T') ) - COMPLETE_WITH_CONST("TO"); - /* Complete "AS ON <sth> TO" with a table name */ - else if( strcasecmp(prev4_wd,"AS")==0 && - strcasecmp(prev3_wd,"ON")==0 && - strcasecmp(prev_wd,"TO")==0 ) - COMPLETE_WITH_QUERY(Query_for_list_of_tables); + /* Complete "CREATE RULE <sth>" with "AS" */ + else if (strcasecmp(prev3_wd, "CREATE") == 0 && strcasecmp(prev2_wd, "RULE") == 0) + COMPLETE_WITH_CONST("AS"); + /* Complete "CREATE RULE <sth> AS with "ON" */ + else if (strcasecmp(prev4_wd, "CREATE") == 0 && + strcasecmp(prev3_wd, "RULE") == 0 && + strcasecmp(prev_wd, "AS") == 0) + COMPLETE_WITH_CONST("ON"); + /* Complete "RULE * AS ON" with SELECT|UPDATE|DELETE|INSERT */ + else if (strcasecmp(prev4_wd, "RULE") == 0 && + strcasecmp(prev2_wd, "AS") == 0 && + strcasecmp(prev_wd, "ON") == 0) + { + char *rule_events[] = {"SELECT", "UPDATE", "INSERT", "DELETE", NULL}; + + COMPLETE_WITH_LIST(rule_events); + } + /* Complete "AS ON <sth with a 'T' :)>" with a "TO" */ + else if (strcasecmp(prev3_wd, "AS") == 0 && + strcasecmp(prev2_wd, "ON") == 0 && + (toupper(prev_wd[4]) == 'T' || toupper(prev_wd[5]) == 'T')) + COMPLETE_WITH_CONST("TO"); + /* Complete "AS ON <sth> TO" with a table name */ + else if (strcasecmp(prev4_wd, "AS") == 0 && + strcasecmp(prev3_wd, "ON") == 0 && + strcasecmp(prev_wd, "TO") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_tables); /* CREATE TABLE */ - /* Complete CREATE TEMP with "TABLE" */ - else if( strcasecmp(prev2_wd, "CREATE")==0 && strcasecmp(prev_wd, "TEMP")==0 ) - COMPLETE_WITH_CONST("TABLE"); + /* Complete CREATE TEMP with "TABLE" */ + else if (strcasecmp(prev2_wd, "CREATE") == 0 && strcasecmp(prev_wd, "TEMP") == 0) + COMPLETE_WITH_CONST("TABLE"); /* CREATE TRIGGER */ - /* is on the agenda . . . */ + /* is on the agenda . . . */ /* CREATE VIEW */ - /* Complete "CREATE VIEW <name>" with "AS" */ - else if( strcasecmp(prev3_wd,"CREATE")==0 && strcasecmp(prev2_wd,"VIEW")==0 ) - COMPLETE_WITH_CONST("AS"); - /* Complete "CREATE VIEW <sth> AS with "SELECT" */ - else if( strcasecmp(prev4_wd,"CREATE")==0 && - strcasecmp(prev3_wd,"VIEW")==0 && - strcasecmp(prev_wd,"AS")==0 ) - COMPLETE_WITH_CONST("SELECT"); + /* Complete "CREATE VIEW <name>" with "AS" */ + else if (strcasecmp(prev3_wd, "CREATE") == 0 && strcasecmp(prev2_wd, "VIEW") == 0) + COMPLETE_WITH_CONST("AS"); + /* Complete "CREATE VIEW <sth> AS with "SELECT" */ + else if (strcasecmp(prev4_wd, "CREATE") == 0 && + strcasecmp(prev3_wd, "VIEW") == 0 && + strcasecmp(prev_wd, "AS") == 0) + COMPLETE_WITH_CONST("SELECT"); /* DELETE */ - /* Complete DELETE with FROM (only if the word before that is not "ON" (cf. - rules) or "BEFORE" or "AFTER" (cf. triggers) ) */ - else if( strcasecmp(prev_wd,"DELETE")==0 && - !(strcasecmp(prev2_wd,"ON")==0 || - strcasecmp(prev2_wd,"BEFORE")==0 || - strcasecmp(prev2_wd,"AFTER")==0) ) - COMPLETE_WITH_CONST("FROM"); - /* Complete DELETE FROM with a list of tables */ - else if( strcasecmp(prev2_wd,"DELETE")==0 && strcasecmp(prev_wd,"FROM")==0 ) - COMPLETE_WITH_QUERY(Query_for_list_of_tables); - /* Complete DELETE FROM <table> with "WHERE" (perhaps a safe idea?) */ - else if( strcasecmp(prev3_wd,"DELETE")==0 && strcasecmp(prev2_wd,"FROM")==0 ) - COMPLETE_WITH_CONST("WHERE"); + + /* + * Complete DELETE with FROM (only if the word before that is not "ON" + * (cf. rules) or "BEFORE" or "AFTER" (cf. triggers) ) + */ + else if (strcasecmp(prev_wd, "DELETE") == 0 && + !(strcasecmp(prev2_wd, "ON") == 0 || + strcasecmp(prev2_wd, "BEFORE") == 0 || + strcasecmp(prev2_wd, "AFTER") == 0)) + COMPLETE_WITH_CONST("FROM"); + /* Complete DELETE FROM with a list of tables */ + else if (strcasecmp(prev2_wd, "DELETE") == 0 && strcasecmp(prev_wd, "FROM") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_tables); + /* Complete DELETE FROM <table> with "WHERE" (perhaps a safe idea?) */ + else if (strcasecmp(prev3_wd, "DELETE") == 0 && strcasecmp(prev2_wd, "FROM") == 0) + COMPLETE_WITH_CONST("WHERE"); /* EXPLAIN */ - /* Complete EXPLAIN [VERBOSE] (which you'd have to type yourself) with the list of SQL commands */ - else if( strcasecmp(prev_wd,"EXPLAIN")==0 || - (strcasecmp(prev2_wd,"EXPLAIN")==0 && strcasecmp(prev_wd,"VERBOSE")==0) ) - COMPLETE_WITH_LIST(sql_commands); + + /* + * Complete EXPLAIN [VERBOSE] (which you'd have to type yourself) with + * the list of SQL commands + */ + else if (strcasecmp(prev_wd, "EXPLAIN") == 0 || + (strcasecmp(prev2_wd, "EXPLAIN") == 0 && strcasecmp(prev_wd, "VERBOSE") == 0)) + COMPLETE_WITH_LIST(sql_commands); /* FETCH && MOVE */ - /* Complete FETCH with one of FORWARD, BACKWARD, RELATIVE */ - else if( strcasecmp(prev_wd,"FETCH")==0 || strcasecmp(prev_wd,"MOVE")==0 ) { - char * list_FETCH1[] = { "FORWARD", "BACKWARD", "RELATIVE", NULL }; - COMPLETE_WITH_LIST(list_FETCH1); - } - /* Complete FETCH <sth> with one of ALL, NEXT, PRIOR */ - else if( strcasecmp(prev2_wd,"FETCH")==0 || strcasecmp(prev2_wd,"MOVE")==0 ) { - char * list_FETCH2[] = { "ALL", "NEXT", "PRIOR", NULL }; - COMPLETE_WITH_LIST(list_FETCH2); - } - /* Complete FETCH <sth1> <sth2> with "FROM" or "TO". - (Is there a difference? If not, remove one.) */ - else if( strcasecmp(prev3_wd,"FETCH")==0 || strcasecmp(prev3_wd,"MOVE")==0 ) { - char * list_FROMTO[] = { "FROM", "TO", NULL }; - COMPLETE_WITH_LIST(list_FROMTO); - } + /* Complete FETCH with one of FORWARD, BACKWARD, RELATIVE */ + else if (strcasecmp(prev_wd, "FETCH") == 0 || strcasecmp(prev_wd, "MOVE") == 0) + { + char *list_FETCH1[] = {"FORWARD", "BACKWARD", "RELATIVE", NULL}; + + COMPLETE_WITH_LIST(list_FETCH1); + } + /* Complete FETCH <sth> with one of ALL, NEXT, PRIOR */ + else if (strcasecmp(prev2_wd, "FETCH") == 0 || strcasecmp(prev2_wd, "MOVE") == 0) + { + char *list_FETCH2[] = {"ALL", "NEXT", "PRIOR", NULL}; + + COMPLETE_WITH_LIST(list_FETCH2); + } + + /* + * Complete FETCH <sth1> <sth2> with "FROM" or "TO". (Is there a + * difference? If not, remove one.) + */ + else if (strcasecmp(prev3_wd, "FETCH") == 0 || strcasecmp(prev3_wd, "MOVE") == 0) + { + char *list_FROMTO[] = {"FROM", "TO", NULL}; + + COMPLETE_WITH_LIST(list_FROMTO); + } /* GRANT && REVOKE*/ - /* Complete GRANT/REVOKE with a list of privileges */ - else if( strcasecmp(prev_wd,"GRANT")==0 || strcasecmp(prev_wd,"REVOKE")==0 ) { - char * list_privileg[] = { "SELECT", "INSERT", "UPDATE", "DELETE", "RULE", "ALL", NULL }; - COMPLETE_WITH_LIST(list_privileg); - } - /* Complete GRANT/REVOKE <sth> with "ON" */ - else if( strcasecmp(prev2_wd,"GRANT")==0 || strcasecmp(prev2_wd,"REVOKE")==0 ) - COMPLETE_WITH_CONST("ON"); - /* Complete GRANT/REVOKE <sth> ON with a list of tables, views, sequences, and indexes */ - else if( (strcasecmp(prev3_wd,"GRANT")==0 || strcasecmp(prev3_wd,"REVOKE")==0) && - strcasecmp(prev_wd,"ON")==0 ) - COMPLETE_WITH_QUERY("SELECT relname FROM pg_class WHERE relkind in ('r','i','s') and substr(relname,1,%d)='%s'"); - /* Complete "GRANT * ON * " with "TO" */ - else if( strcasecmp(prev4_wd,"GRANT")==0 && strcasecmp(prev2_wd,"ON")==0 ) - COMPLETE_WITH_CONST("TO"); - /* Complete "REVOKE * ON * " with "FROM" */ - else if( strcasecmp(prev4_wd,"REVOKE")==0 && strcasecmp(prev2_wd,"ON")==0 ) - COMPLETE_WITH_CONST("FROM"); - /* TODO: to complete with user name we need prev5_wd -- wait for a more general solution there */ + /* Complete GRANT/REVOKE with a list of privileges */ + else if (strcasecmp(prev_wd, "GRANT") == 0 || strcasecmp(prev_wd, "REVOKE") == 0) + { + char *list_privileg[] = {"SELECT", "INSERT", "UPDATE", "DELETE", "RULE", "ALL", NULL}; + + COMPLETE_WITH_LIST(list_privileg); + } + /* Complete GRANT/REVOKE <sth> with "ON" */ + else if (strcasecmp(prev2_wd, "GRANT") == 0 || strcasecmp(prev2_wd, "REVOKE") == 0) + COMPLETE_WITH_CONST("ON"); + + /* + * Complete GRANT/REVOKE <sth> ON with a list of tables, views, + * sequences, and indexes + */ + else if ((strcasecmp(prev3_wd, "GRANT") == 0 || strcasecmp(prev3_wd, "REVOKE") == 0) && + strcasecmp(prev_wd, "ON") == 0) + COMPLETE_WITH_QUERY("SELECT relname FROM pg_class WHERE relkind in ('r','i','s') and substr(relname,1,%d)='%s'"); + /* Complete "GRANT * ON * " with "TO" */ + else if (strcasecmp(prev4_wd, "GRANT") == 0 && strcasecmp(prev2_wd, "ON") == 0) + COMPLETE_WITH_CONST("TO"); + /* Complete "REVOKE * ON * " with "FROM" */ + else if (strcasecmp(prev4_wd, "REVOKE") == 0 && strcasecmp(prev2_wd, "ON") == 0) + COMPLETE_WITH_CONST("FROM"); + + /* + * TODO: to complete with user name we need prev5_wd -- wait for a + * more general solution there + */ /* INSERT */ - /* Complete INSERT with "INTO" */ - else if( strcasecmp(prev_wd,"INSERT")==0 ) - COMPLETE_WITH_CONST("INTO"); - /* Complete INSERT INTO with table names */ - else if( strcasecmp(prev2_wd, "INSERT")==0 && strcasecmp(prev_wd,"INTO")==0 ) - COMPLETE_WITH_QUERY(Query_for_list_of_tables); - /* Complete INSERT INTO <table> with "VALUES" or "SELECT" */ - else if( strcasecmp(prev3_wd, "INSERT")==0 && strcasecmp(prev2_wd,"INTO")==0 ) { - char * list_INSERT[] = { "SELECT", "VALUES", NULL }; - COMPLETE_WITH_LIST(list_INSERT); - } - /* Insert an open parenthesis after "VALUES" */ - else if( strcasecmp(prev_wd,"VALUES")==0 ) - COMPLETE_WITH_CONST("("); + /* Complete INSERT with "INTO" */ + else if (strcasecmp(prev_wd, "INSERT") == 0) + COMPLETE_WITH_CONST("INTO"); + /* Complete INSERT INTO with table names */ + else if (strcasecmp(prev2_wd, "INSERT") == 0 && strcasecmp(prev_wd, "INTO") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_tables); + /* Complete INSERT INTO <table> with "VALUES" or "SELECT" */ + else if (strcasecmp(prev3_wd, "INSERT") == 0 && strcasecmp(prev2_wd, "INTO") == 0) + { + char *list_INSERT[] = {"SELECT", "VALUES", NULL}; + + COMPLETE_WITH_LIST(list_INSERT); + } + /* Insert an open parenthesis after "VALUES" */ + else if (strcasecmp(prev_wd, "VALUES") == 0) + COMPLETE_WITH_CONST("("); /* LOCK */ - /* Complete with list of tables */ - else if( strcasecmp(prev_wd, "LOCK") == 0 ) - COMPLETE_WITH_QUERY(Query_for_list_of_tables); - /* (If you want more with LOCK, you better think about it yourself.) */ + /* Complete with list of tables */ + else if (strcasecmp(prev_wd, "LOCK") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_tables); + /* (If you want more with LOCK, you better think about it yourself.) */ /* SELECT */ - /* naah . . . */ + /* naah . . . */ /* SET, RESET, SHOW */ - /* Complete with a variable name */ - else if( (strcasecmp(prev_wd,"SET")==0 && strcasecmp(prev3_wd,"UPDATE")!=0) || - strcasecmp(prev_wd,"RESET")==0 || - strcasecmp(prev_wd,"SHOW")==0 ) - COMPLETE_WITH_LIST(pgsql_variables); - /* Complete "SET TRANSACTION ISOLOLATION LEVEL" */ - else if( strcasecmp(prev2_wd,"SET")==0 && strcasecmp(prev_wd,"TRANSACTION")==0 ) - COMPLETE_WITH_CONST("ISOLATION"); - else if( strcasecmp(prev3_wd,"SET")==0 && - strcasecmp(prev2_wd,"TRANSACTION")==0 && - strcasecmp(prev_wd,"ISOLATION")==0 ) - COMPLETE_WITH_CONST("LEVEL"); - else if( strcasecmp(prev4_wd,"SET")==0 && - strcasecmp(prev3_wd,"TRANSACTION")==0 && - strcasecmp(prev2_wd,"ISOLATION")==0 && - strcasecmp(prev_wd,"LEVEL")==0 ) { - char * my_list[] = {"READ","SERIALIZED",NULL}; - COMPLETE_WITH_LIST(my_list); - } - else if( strcasecmp(prev4_wd,"TRANSACTION")==0 && - strcasecmp(prev3_wd,"ISOLATION")==0 && - strcasecmp(prev2_wd,"LEVEL")==0 && - strcasecmp(prev_wd,"READ")==0 ) - COMPLETE_WITH_CONST("COMMITTED"); - /* Complete SET <var> with "TO" */ - else if( strcasecmp(prev2_wd,"SET")==0 && - strcasecmp(prev4_wd,"UPDATE")!=0 ) - COMPLETE_WITH_CONST("TO"); - /* Suggest possible variable values */ - else if( strcasecmp(prev3_wd,"SET")==0 && - (strcasecmp(prev_wd,"TO")==0 || strcmp(prev_wd,"=")==0) ) { - if ( strcasecmp(prev2_wd,"DateStyle")==0 ) { - char * my_list[] = {"'ISO'", "'SQL'", "'Postgres'", "'European'", "'NonEuropean'", "'German'", "DEFAULT", NULL}; - COMPLETE_WITH_LIST(my_list); - } - else if( strcasecmp(prev2_wd,"GEQO")==0 || strcasecmp(prev2_wd,"KSQO")==0 ) { - char * my_list[] = {"ON", "OFF", "DEFAULT", NULL}; - COMPLETE_WITH_LIST(my_list); - } - else { - char * my_list[] = {"DEFAULT", NULL}; - COMPLETE_WITH_LIST(my_list); - } - } + /* Complete with a variable name */ + else if ((strcasecmp(prev_wd, "SET") == 0 && strcasecmp(prev3_wd, "UPDATE") != 0) || + strcasecmp(prev_wd, "RESET") == 0 || + strcasecmp(prev_wd, "SHOW") == 0) + COMPLETE_WITH_LIST(pgsql_variables); + /* Complete "SET TRANSACTION ISOLOLATION LEVEL" */ + else if (strcasecmp(prev2_wd, "SET") == 0 && strcasecmp(prev_wd, "TRANSACTION") == 0) + COMPLETE_WITH_CONST("ISOLATION"); + else if (strcasecmp(prev3_wd, "SET") == 0 && + strcasecmp(prev2_wd, "TRANSACTION") == 0 && + strcasecmp(prev_wd, "ISOLATION") == 0) + COMPLETE_WITH_CONST("LEVEL"); + else if (strcasecmp(prev4_wd, "SET") == 0 && + strcasecmp(prev3_wd, "TRANSACTION") == 0 && + strcasecmp(prev2_wd, "ISOLATION") == 0 && + strcasecmp(prev_wd, "LEVEL") == 0) + { + char *my_list[] = {"READ", "SERIALIZED", NULL}; + + COMPLETE_WITH_LIST(my_list); + } + else if (strcasecmp(prev4_wd, "TRANSACTION") == 0 && + strcasecmp(prev3_wd, "ISOLATION") == 0 && + strcasecmp(prev2_wd, "LEVEL") == 0 && + strcasecmp(prev_wd, "READ") == 0) + COMPLETE_WITH_CONST("COMMITTED"); + /* Complete SET <var> with "TO" */ + else if (strcasecmp(prev2_wd, "SET") == 0 && + strcasecmp(prev4_wd, "UPDATE") != 0) + COMPLETE_WITH_CONST("TO"); + /* Suggest possible variable values */ + else if (strcasecmp(prev3_wd, "SET") == 0 && + (strcasecmp(prev_wd, "TO") == 0 || strcmp(prev_wd, "=") == 0)) + { + if (strcasecmp(prev2_wd, "DateStyle") == 0) + { + char *my_list[] = {"'ISO'", "'SQL'", "'Postgres'", "'European'", "'NonEuropean'", "'German'", "DEFAULT", NULL}; + + COMPLETE_WITH_LIST(my_list); + } + else if (strcasecmp(prev2_wd, "GEQO") == 0 || strcasecmp(prev2_wd, "KSQO") == 0) + { + char *my_list[] = {"ON", "OFF", "DEFAULT", NULL}; + + COMPLETE_WITH_LIST(my_list); + } + else + { + char *my_list[] = {"DEFAULT", NULL}; + + COMPLETE_WITH_LIST(my_list); + } + } /* UPDATE */ - /* If prev. word is UPDATE suggest a list of tables */ - else if( strcasecmp(prev_wd, "UPDATE") == 0 ) - COMPLETE_WITH_QUERY(Query_for_list_of_tables); - /* Complete UPDATE <table> with "SET" */ - else if( strcasecmp(prev2_wd, "UPDATE") == 0 ) - COMPLETE_WITH_CONST("SET"); - /* If the previous word is SET (and it wasn't caught above as the _first_ - word) the word before it was (hopefully) a table name and we'll now make - a list of attributes. */ - else if( strcasecmp(prev_wd, "SET") == 0 ) - COMPLETE_WITH_ATTR(prev2_wd); + /* If prev. word is UPDATE suggest a list of tables */ + else if (strcasecmp(prev_wd, "UPDATE") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_tables); + /* Complete UPDATE <table> with "SET" */ + else if (strcasecmp(prev2_wd, "UPDATE") == 0) + COMPLETE_WITH_CONST("SET"); + + /* + * If the previous word is SET (and it wasn't caught above as the + * _first_ word) the word before it was (hopefully) a table name and + * we'll now make a list of attributes. + */ + else if (strcasecmp(prev_wd, "SET") == 0) + COMPLETE_WITH_ATTR(prev2_wd); /* VACUUM */ - else if( strcasecmp(prev_wd, "VACUUM") == 0 ) - COMPLETE_WITH_QUERY("SELECT relname FROM pg_class WHERE relkind='r' and substr(relname,1,%d)='%s' UNION SELECT 'ANALYZE'::text"); - else if( strcasecmp(prev2_wd, "VACUUM")==0 && strcasecmp(prev_wd, "ANALYZE")==0 ) - COMPLETE_WITH_QUERY(Query_for_list_of_tables); + else if (strcasecmp(prev_wd, "VACUUM") == 0) + COMPLETE_WITH_QUERY("SELECT relname FROM pg_class WHERE relkind='r' and substr(relname,1,%d)='%s' UNION SELECT 'ANALYZE'::text"); + else if (strcasecmp(prev2_wd, "VACUUM") == 0 && strcasecmp(prev_wd, "ANALYZE") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_tables); /* ... FROM ... */ - else if (strcasecmp(prev_wd, "FROM") == 0 ) - COMPLETE_WITH_QUERY(Query_for_list_of_tables); + else if (strcasecmp(prev_wd, "FROM") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_tables); /* Backslash commands */ - else if (strcmp(prev_wd, "\\connect")==0 || strcmp(prev_wd, "\\c")==0) - COMPLETE_WITH_QUERY(Query_for_list_of_databases); - else if (strcmp(prev_wd, "\\d")==0) - COMPLETE_WITH_QUERY(Query_for_list_of_tables); - else if (strcmp(prev_wd, "\\h")==0 || strcmp(prev_wd, "\\help")==0) - COMPLETE_WITH_LIST(sql_commands); - else if (strcmp(prev_wd, "\\pset")==0) { - char * my_list[] = { "format", "border", "expanded", "null", "fieldsep", - "tuples_only", "title", "tableattr", "pager", - "recordsep", NULL }; - COMPLETE_WITH_LIST(my_list); - } - else if( strcmp(prev_wd, "\\e")==0 || strcmp(prev_wd, "\\edit")==0 || - strcmp(prev_wd, "\\g")==0 || - strcmp(prev_wd, "\\i")==0 || strcmp(prev_wd, "\\include")==0 || - strcmp(prev_wd, "\\o")==0 || strcmp(prev_wd, "\\out")==0 || - strcmp(prev_wd, "\\s")==0 || - strcmp(prev_wd, "\\w")==0 || strcmp(prev_wd, "\\write")==0 - ) { + else if (strcmp(prev_wd, "\\connect") == 0 || strcmp(prev_wd, "\\c") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_databases); + else if (strcmp(prev_wd, "\\d") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_tables); + else if (strcmp(prev_wd, "\\h") == 0 || strcmp(prev_wd, "\\help") == 0) + COMPLETE_WITH_LIST(sql_commands); + else if (strcmp(prev_wd, "\\pset") == 0) + { + char *my_list[] = {"format", "border", "expanded", "null", "fieldsep", + "tuples_only", "title", "tableattr", "pager", + "recordsep", NULL}; + + COMPLETE_WITH_LIST(my_list); + } + else if (strcmp(prev_wd, "\\e") == 0 || strcmp(prev_wd, "\\edit") == 0 || + strcmp(prev_wd, "\\g") == 0 || + strcmp(prev_wd, "\\i") == 0 || strcmp(prev_wd, "\\include") == 0 || + strcmp(prev_wd, "\\o") == 0 || strcmp(prev_wd, "\\out") == 0 || + strcmp(prev_wd, "\\s") == 0 || + strcmp(prev_wd, "\\w") == 0 || strcmp(prev_wd, "\\write") == 0 + ) + { #ifdef HAVE_FILENAME_COMPLETION_FUNCTION - matches = completion_matches(text, filename_completion_function); + matches = completion_matches(text, filename_completion_function); #else - /* - * This will probably have the same effect, but you never know what - * the heck some readline incarnation out there is going to do. - */ - matches = NULL; + + /* + * This will probably have the same effect, but you never know + * what the heck some readline incarnation out there is going to + * do. + */ + matches = NULL; #endif - } - - - /* Finally, we look through the list of "things", such as TABLE, INDEX and - check if that was the previous word. If so, execute the query to get a - list of them. */ - else { - int i; - for(i=0; words_after_create[i].name; i++) - if ( strcasecmp(prev_wd, words_after_create[i].name) == 0 ) { - COMPLETE_WITH_QUERY(words_after_create[i].query); - break; - } - } - - - /* If we still don't have anything to match we have to fabricate some sort - of default list. If we were to just return NULL, readline automatically - attempts filename completion, and that's usually no good. */ - if (matches == NULL) - { - COMPLETE_WITH_CONST(""); + } + + + /* + * Finally, we look through the list of "things", such as TABLE, INDEX + * and check if that was the previous word. If so, execute the query + * to get a list of them. + */ + else + { + int i; + + for (i = 0; words_after_create[i].name; i++) + if (strcasecmp(prev_wd, words_after_create[i].name) == 0) + { + COMPLETE_WITH_QUERY(words_after_create[i].query); + break; + } + } + + + /* + * If we still don't have anything to match we have to fabricate some + * sort of default list. If we were to just return NULL, readline + * automatically attempts filename completion, and that's usually no + * good. + */ + if (matches == NULL) + { + COMPLETE_WITH_CONST(""); #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER - rl_completion_append_character = '\0'; + rl_completion_append_character = '\0'; #endif - } - + } - /* free storage */ - free(prev_wd); - free(prev2_wd); - free(prev3_wd); - free(prev4_wd); - /* Return our Grand List O' Matches */ - return matches; + /* free storage */ + free(prev_wd); + free(prev2_wd); + free(prev3_wd); + free(prev4_wd); + + /* Return our Grand List O' Matches */ + return matches; } @@ -602,24 +694,27 @@ char ** psql_completion(char *text, int start, int end) /* This one gives you one from a list of things you can put after CREATE or DROP as defined above. */ -char * create_command_generator(char *text, int state) +char * +create_command_generator(char *text, int state) { - static int list_index, string_length; - char *name; - - /* If this is the first time for this completion, init some values */ - if (state == 0) { - list_index = 0; - string_length = strlen(text); - } - - /* find something that matches */ - while ( (name = words_after_create[list_index++].name) ) - if ( strncasecmp(name, text, string_length) == 0 ) - return xstrdup(name); - - /* if nothing matches, return NULL */ - return NULL; + static int list_index, + string_length; + char *name; + + /* If this is the first time for this completion, init some values */ + if (state == 0) + { + list_index = 0; + string_length = strlen(text); + } + + /* find something that matches */ + while ((name = words_after_create[list_index++].name)) + if (strncasecmp(name, text, string_length) == 0) + return xstrdup(name); + + /* if nothing matches, return NULL */ + return NULL; } @@ -632,40 +727,47 @@ char * create_command_generator(char *text, int state) Ordinarily this would be used to get a list of matching tables or functions, etc. */ -char * complete_from_query(char *text, int state) +char * +complete_from_query(char *text, int state) { - static int list_index, string_length; - static PGresult *result = NULL; - char query_buffer[BUF_SIZE]; - const char * item; - - /* If this ist the first time for this completion, we fetch a list of our - "things" from the backend. */ - if (state == 0) { - list_index = 0; - string_length = strlen(text); - - /* Need to have a query */ - if (completion_charp == NULL) return NULL; - - if (snprintf(query_buffer, BUF_SIZE, completion_charp, string_length, text, completion_info_charp) == -1) { - ERROR_QUERY_TOO_LONG; - return NULL; - } - - result = exec_query(query_buffer); - } - - /* Find something that matches */ - if( result && PQresultStatus(result) == PGRES_TUPLES_OK ) - while( list_index < PQntuples(result) && (item = PQgetvalue(result, list_index++, 0)) ) - if ( strncasecmp(text, item, string_length) == 0) - return xstrdup(item); - - /* If nothing matches, free the db structure and return null */ - PQclear(result); - result = NULL; - return NULL; + static int list_index, + string_length; + static PGresult *result = NULL; + char query_buffer[BUF_SIZE]; + const char *item; + + /* + * If this ist the first time for this completion, we fetch a list of + * our "things" from the backend. + */ + if (state == 0) + { + list_index = 0; + string_length = strlen(text); + + /* Need to have a query */ + if (completion_charp == NULL) + return NULL; + + if (snprintf(query_buffer, BUF_SIZE, completion_charp, string_length, text, completion_info_charp) == -1) + { + ERROR_QUERY_TOO_LONG; + return NULL; + } + + result = exec_query(query_buffer); + } + + /* Find something that matches */ + if (result && PQresultStatus(result) == PGRES_TUPLES_OK) + while (list_index < PQntuples(result) && (item = PQgetvalue(result, list_index++, 0))) + if (strncasecmp(text, item, string_length) == 0) + return xstrdup(item); + + /* If nothing matches, free the db structure and return null */ + PQclear(result); + result = NULL; + return NULL; } @@ -673,27 +775,31 @@ char * complete_from_query(char *text, int state) of strings (if matching). This can be used if there are only a fixed number SQL words that can appear at certain spot. */ -char * complete_from_list(char *text, int state) { - static int string_length, list_index; - char * item; +char * +complete_from_list(char *text, int state) +{ + static int string_length, + list_index; + char *item; - /* need to have a list */ + /* need to have a list */ #ifdef USE_ASSERT_CHECKING - assert(completion_charpp); + assert(completion_charpp); #endif - /* Initialization */ - if (state == 0) { - list_index = 0; - string_length = strlen(text); - } + /* Initialization */ + if (state == 0) + { + list_index = 0; + string_length = strlen(text); + } - while( (item = completion_charpp[list_index++]) ) - if ( strncasecmp(text,item,string_length) == 0 ) - return xstrdup(item); + while ((item = completion_charpp[list_index++])) + if (strncasecmp(text, item, string_length) == 0) + return xstrdup(item); - /* If no more matches, return null. */ - return NULL; + /* If no more matches, return null. */ + return NULL; } @@ -703,16 +809,19 @@ char * complete_from_list(char *text, int state) { will be overwritten. The string to be passed must be in completion_charp. */ -char * complete_from_const(char *text, int state) +char * +complete_from_const(char *text, int state) { - (void)text; /* We don't care about what was entered already. */ + (void) text; /* We don't care about what was entered + * already. */ + #ifdef USE_ASSERT_CHECKING - assert(completion_charp); + assert(completion_charp); #endif - if (state==0) - return xstrdup(completion_charp); - else - return NULL; + if (state == 0) + return xstrdup(completion_charp); + else + return NULL; } @@ -725,34 +834,37 @@ char * complete_from_const(char *text, int state) Note that the query passed in here must not have a semicolon at the end because we need to append LIMIT xxx. */ -PGresult * exec_query(char * query) +PGresult * +exec_query(char *query) { - PGresult * result; - char query_buffer[BUF_SIZE]; + PGresult *result; + char query_buffer[BUF_SIZE]; - if (query == NULL || !pset.db || PQstatus(pset.db) != CONNECTION_OK) - return NULL; + if (query == NULL || !pset.db || PQstatus(pset.db) != CONNECTION_OK) + return NULL; #ifdef USE_ASSERT_CHECKING - assert( query[strlen(query)-1] != ';' ); + assert(query[strlen(query) - 1] != ';'); #endif - if( snprintf(query_buffer, BUF_SIZE, "%s LIMIT %d;", query, completion_max_records) == -1 ) { - ERROR_QUERY_TOO_LONG; - return NULL; - } + if (snprintf(query_buffer, BUF_SIZE, "%s LIMIT %d;", query, completion_max_records) == -1) + { + ERROR_QUERY_TOO_LONG; + return NULL; + } - result = PQexec(pset.db, query); + result = PQexec(pset.db, query); - if (result != NULL && PQresultStatus(result) != PGRES_TUPLES_OK) { + if (result != NULL && PQresultStatus(result) != PGRES_TUPLES_OK) + { #if 0 - psql_error("tab completion: %s failed - %s\n", - query, PQresStatus(PQresultStatus(result))); + psql_error("tab completion: %s failed - %s\n", + query, PQresStatus(PQresultStatus(result))); #endif - PQclear(result); - result = NULL; - } - - return result; + PQclear(result); + result = NULL; + } + + return result; } @@ -762,52 +874,63 @@ PGresult * exec_query(char * query) TODO: Take account of quotes. (Right now, if you table names contain spaces you're screwed.) */ -char * previous_word(int point, int skip) { - int i, start=0, end=-1; - char * s; - - while (skip-- >=0) { - /* first we look for a space before the current word */ - for(i=point; i>=0; i--) - if (rl_line_buffer[i] == ' ') - break; - - /* now find the first non-space which then constitutes the end */ - for(; i>=0; i--) - if (rl_line_buffer[i] != ' ') { - end = i; - break; - } - - /* If no end found we return null, because there is no word before the point */ - if (end == -1) - return NULL; - - /* Otherwise we now look for the start. The start is either the last - character before any space going backwards from the end, or it's - simply character 0 */ - for (start=end; start>0; start--) - if (rl_line_buffer[start-1] == ' ') - break; - - point=start; - } - - /* make a copy */ - s = (char *)malloc(end-start+2); - if (!s) - { - psql_error("out of memory\n"); - if (!pset.cur_cmd_interactive) - exit(EXIT_FAILURE); - else - return NULL; - } - - strncpy(s, &rl_line_buffer[start], end-start+1); - s[end-start+1] = '\0'; - - return s; +char * +previous_word(int point, int skip) +{ + int i, + start = 0, + end = -1; + char *s; + + while (skip-- >= 0) + { + /* first we look for a space before the current word */ + for (i = point; i >= 0; i--) + if (rl_line_buffer[i] == ' ') + break; + + /* now find the first non-space which then constitutes the end */ + for (; i >= 0; i--) + if (rl_line_buffer[i] != ' ') + { + end = i; + break; + } + + /* + * If no end found we return null, because there is no word before + * the point + */ + if (end == -1) + return NULL; + + /* + * Otherwise we now look for the start. The start is either the + * last character before any space going backwards from the end, + * or it's simply character 0 + */ + for (start = end; start > 0; start--) + if (rl_line_buffer[start - 1] == ' ') + break; + + point = start; + } + + /* make a copy */ + s = (char *) malloc(end - start + 2); + if (!s) + { + psql_error("out of memory\n"); + if (!pset.cur_cmd_interactive) + exit(EXIT_FAILURE); + else + return NULL; + } + + strncpy(s, &rl_line_buffer[start], end - start + 1); + s[end - start + 1] = '\0'; + + return s; } @@ -819,41 +942,43 @@ char * previous_word(int point, int skip) { * psql internal. Currently disable because it is reported not to * cooperate with certain versions of readline. */ -char * quote_file_name(char *text, int match_type, char * quote_pointer) +char * +quote_file_name(char *text, int match_type, char *quote_pointer) { - char *s; - size_t length; - - (void)quote_pointer; /* not used */ - - length = strlen(text) + ( match_type==SINGLE_MATCH ? 3 : 2 ); - s = malloc(length); - s[0] = '\''; - strcpy(s+1, text); - if (match_type==SINGLE_MATCH) - s[length-2] = '\''; - s[length-1] = '\0'; - return s; + char *s; + size_t length; + + (void) quote_pointer; /* not used */ + + length = strlen(text) +(match_type == SINGLE_MATCH ? 3 : 2); + s = malloc(length); + s[0] = '\''; + strcpy(s + 1, text); + if (match_type == SINGLE_MATCH) + s[length - 2] = '\''; + s[length - 1] = '\0'; + return s; } -static char * dequote_file_name(char *text, char quote_char) +static char * +dequote_file_name(char *text, char quote_char) { - char *s; - size_t length; + char *s; + size_t length; - if (!quote_char) - return xstrdup(text); + if (!quote_char) + return xstrdup(text); - length = strlen(text); - s = malloc(length-2+1); - strncpy(s, text+1, length-2); - s[length] = '\0'; + length = strlen(text); + s = malloc(length - 2 + 1); + strncpy(s, text +1, length - 2); + s[length] = '\0'; - return s; + return s; } -#endif /* 0 */ +#endif /* 0 */ -#endif /* USE_READLINE */ +#endif /* USE_READLINE */ diff --git a/src/bin/psql/tab-complete.h b/src/bin/psql/tab-complete.h index c7d44bd2f07..98f3e9546f1 100644 --- a/src/bin/psql/tab-complete.h +++ b/src/bin/psql/tab-complete.h @@ -3,13 +3,13 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.h,v 1.4 2000/03/05 13:30:19 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.h,v 1.5 2000/04/12 17:16:23 momjian Exp $ */ #ifndef TAB_COMPLETE_H #define TAB_COMPLETE_H #include "postgres.h" -void initialize_readline(void); +void initialize_readline(void); #endif diff --git a/src/bin/psql/variables.c b/src/bin/psql/variables.c index 667066cbfd8..c8d8760b785 100644 --- a/src/bin/psql/variables.c +++ b/src/bin/psql/variables.c @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/variables.c,v 1.7 2000/02/16 13:15:26 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/variables.c,v 1.8 2000/04/12 17:16:23 momjian Exp $ */ #include "postgres.h" #include "variables.h" @@ -113,7 +113,7 @@ SetVariable(VariableSpace space, const char *name, const char *value) bool SetVariableBool(VariableSpace space, const char *name) { - return SetVariable(space, name, ""); + return SetVariable(space, name, ""); } diff --git a/src/bin/psql/variables.h b/src/bin/psql/variables.h index d0f01a7d791..0814d71a9a4 100644 --- a/src/bin/psql/variables.h +++ b/src/bin/psql/variables.h @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/variables.h,v 1.7 2000/02/16 13:15:26 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/variables.h,v 1.8 2000/04/12 17:16:23 momjian Exp $ */ /* @@ -16,7 +16,7 @@ #define VARIABLES_H #define VALID_VARIABLE_CHARS "abcdefghijklmnopqrstuvwxyz"\ - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789_" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789_" struct _variable { @@ -32,7 +32,7 @@ VariableSpace CreateVariableSpace(void); const char *GetVariable(VariableSpace space, const char *name); bool GetVariableBool(VariableSpace space, const char *name); bool SetVariable(VariableSpace space, const char *name, const char *value); -bool SetVariableBool(VariableSpace space, const char *name); +bool SetVariableBool(VariableSpace space, const char *name); bool DeleteVariable(VariableSpace space, const char *name); void DestroyVariableSpace(VariableSpace space); |