Dnia 2013-11-13, śro o godzinie 10:26 -0500, Bruce Momjian pisze: > On Wed, Nov 13, 2013 at 08:58:07AM +0530, Amit Kapila wrote: > > On Tue, Nov 12, 2013 at 9:37 PM, Bruce Momjian <br...@momjian.us> wrote: > > > On Wed, Oct 23, 2013 at 10:31:39AM +0530, Amit Kapila wrote: > > >> On Tue, Oct 22, 2013 at 3:04 AM, Piotr Marcinczyk <pmarc...@gmail.com> > > >> wrote: > > >> > Hi, > > >> > > > >> > I would like to implement item from TODO marked as easy: "Add \i option > > >> > to bring in the specified file as a quoted literal". I understand > > >> > intent > > >> > of this item, to be able to have parts of query written in separate > > >> > files (now it is impossible, because \i tries to execute content of > > >> > file > > >> > as a separate command by function process_file). > > >> > > >> For the usecase discussed in the mail chain of that TODO item, Robert > > >> Haas has provided an alternative to achieve it, please check below > > >> link: > > >> http://www.postgresql.org/message-id/AANLkTi=7c8xfyf7uqw0y+si8ondkoy2nx8jc4bu0g...@mail.gmail.com > > >> > > >> If you think that alternative is not sufficient for the use case, then > > >> adding new option/syntax is worth, otherwise it might be a shortcut or > > >> other form of some existing way which can be useful depending on how > > >> frequently users use this syntax. > > > > > > So, can we remove this TODO item? > > TODO item is created before Robert Haas has provided an alternative > > way to achieve the same thing. In some cases there are multiple ways > > to > > achieve the same thing (example: shortcut options in psql) if it is > > used quite frequently and people want some easy way of doing it. In > > this case I > > don't think this is used frequently, so I don't see the need of > > doing it. We should remove this TODO item. > > OK, removed. > Well, I wrote it few days ago. I'm sure it is not critical, but I suppose it may be useful. This is my first patch, so I think that it is good idea to sent it and have it reviewed anyway. First argument to send it, is to see what kind of errors I made, to not do them in the next patches. Second, if it (flexible appending file to buffer) appears interesting for reviewer, it may be committed.
*** a/doc/src/sgml/ref/psql-ref.sgml --- b/doc/src/sgml/ref/psql-ref.sgml *************** *** 1731,1736 **** hello 10 --- 1731,1749 ---- <varlistentry> + <term><literal>\ib <replaceable class="parameter">filename</replaceable> [ <replaceable class="parameter">quote_string</replaceable> ] </literal></term> + <listitem> + <para> + The <literal>\ib</> command appends content of file <literal>filename</literal> + to current query buffer. If parameter <literal>quote_string</literal> + is not set, no quotation is used. If it is set, content of file will be + quoted by <literal>quote_string</literal> enclosed in <literal>$</literal>. + </para> + </listitem> + </varlistentry> + + + <varlistentry> <term><literal>\ir <replaceable class="parameter">filename</replaceable></literal></term> <listitem> <para> *** a/src/bin/psql/command.c --- b/src/bin/psql/command.c *************** *** 59,64 **** static backslashResult exec_command(const char *cmd, --- 59,65 ---- PQExpBuffer query_buf); static bool do_edit(const char *filename_arg, PQExpBuffer query_buf, int lineno, bool *edited); + static bool do_append(const char *filename_arg, const char *quote_string, PQExpBuffer query_buf); static bool do_connect(char *dbname, char *user, char *host, char *port); static bool do_shell(const char *command); static bool do_watch(PQExpBuffer query_buf, long sleep); *************** *** 798,806 **** exec_command(const char *cmd, } ! /* \i and \ir include files */ else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0 ! || strcmp(cmd, "ir") == 0 || strcmp(cmd, "include_relative") == 0) { char *fname = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, true); --- 799,808 ---- } ! /* \i, \ib and \ir include files */ else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0 ! || strcmp(cmd, "ir") == 0 || strcmp(cmd, "include_relative") == 0 ! || strcmp(cmd, "ib") == 0 || strcmp(cmd, "include_buffer") == 0) { char *fname = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, true); *************** *** 812,823 **** exec_command(const char *cmd, } else { ! bool include_relative; - include_relative = (strcmp(cmd, "ir") == 0 - || strcmp(cmd, "include_relative") == 0); - expand_tilde(&fname); - success = (process_file(fname, false, include_relative) == EXIT_SUCCESS); free(fname); } } --- 814,845 ---- } else { ! bool include_buffer; ! ! include_buffer = (strcmp(cmd, "ib") == 0 ! || strcmp(cmd, "include_buffer") == 0); ! ! ! if (include_buffer) ! { ! char *quote_string = psql_scan_slash_option(scan_state, ! OT_NORMAL, NULL, true); ! expand_tilde(&fname); ! success = !do_append(fname, quote_string, query_buf); ! if (success) { ! status = PSQL_CMD_NEWEDIT; ! } else { ! status = PSQL_CMD_ERROR; ! } ! } else { ! bool include_relative; ! ! include_relative = (strcmp(cmd, "ir") == 0 ! || strcmp(cmd, "include_relative") == 0); ! expand_tilde(&fname); ! success = (process_file(fname, false, include_relative) == EXIT_SUCCESS); ! } free(fname); } } *************** *** 2099,2104 **** do_edit(const char *filename_arg, PQExpBuffer query_buf, --- 2121,2175 ---- } + /* + * do_append + * + * Read content from file and append it to query_buffer. + */ + static bool + do_append(const char *fname, const char *quote_string, PQExpBuffer query_buf) + { + FILE *stream = NULL; + bool error = false; + stream = fopen(fname, PG_BINARY_R); + if (!stream) + { + psql_error("%s: %s\n", fname, strerror(errno)); + error = true; + } + else + { + /* read file back into query_buf */ + char line[1024]; + + /* insert newline to separate buffer from file input */ + appendPQExpBufferStr(query_buf, "\n"); + /* if quote_string exists add it before file content */ + if (quote_string != NULL) { + appendPQExpBufferStr(query_buf, "$"); + appendPQExpBufferStr(query_buf, quote_string); + appendPQExpBufferStr(query_buf, "$\n"); + } + while (fgets(line, sizeof(line), stream) != NULL) + appendPQExpBufferStr(query_buf, line); + + if (ferror(stream)) + { + psql_error("%s: %s\n", fname, strerror(errno)); + error = true; + } + + fclose(stream); + /* if quote_string exists add it after file content */ + if (quote_string != NULL) { + appendPQExpBufferStr(query_buf, "$"); + appendPQExpBufferStr(query_buf, quote_string); + appendPQExpBufferStr(query_buf, "$"); + } + } + return error; + } + /* * process_file *** a/src/bin/psql/help.c --- b/src/bin/psql/help.c *************** *** 187,192 **** slashUsage(unsigned short int pager) --- 187,193 ---- fprintf(output, _(" \\s [FILE] display history or save it to file\n")); #endif fprintf(output, _(" \\w FILE write query buffer to file\n")); + fprintf(output, _(" \\ib FILE [QUOTE_STR] append file to query buffer\n")); fprintf(output, "\n"); fprintf(output, _("Input/Output\n"));
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers