Thread: I want to send comments to the backend!
Why can't I send comments like -- a comment to the backend using libpq? Are these only handled in psql? Please allow to send comments to the backend, as I really need them. -- Gerhard
On Thursday 20 March 2003 09:05, Gerhard Häring wrote: > Why can't I send comments like > > -- a comment > > to the backend using libpq? Are these only handled in psql? Please allow to > send comments to the backend, as I really need them. Just curious, why? It's easy enough to strip them out from an input stream. -- D'Arcy J.M. Cain <darcy@{druid|vex}.net> | Democracy is three wolves http://www.druid.net/darcy/ | and a sheep voting on +1 416 425 1212 (DoD#0082) (eNTP) | what's for dinner.
Gerhard H�ring wrote: > Why can't I send comments like > > -- a comment > > to the backend using libpq? Are these only handled in psql? Please allow to > send comments to the backend, as I really need them. The backend should handle them fine. Can you give us pgsql version and an example. -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001+ If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania19073
Bruce Momjian <pgman@candle.pha.pa.us> writes: > Gerhard H�ring wrote: >> Why can't I send comments like >> -- a comment >> to the backend using libpq? Are these only handled in psql? Please allow to >> send comments to the backend, as I really need them. > The backend should handle them fine. Can you give us pgsql version and > an example. I think he's complaining that psql strips out the comments before sending stuff to the backend. Unfortunately, most of the world probably considers that a feature, not a bug. I'm quite certain that libpq does not strip comments, so the complaint isn't strictly accurate... regards, tom lane
D'Arcy J.M. Cain wrote: > On Thursday 20 March 2003 09:05, Gerhard Häring wrote: > >>Why can't I send comments like >> >> -- a comment >> >>to the backend using libpq? Are these only handled in psql? Please allow to >>send comments to the backend, as I really need them. > > Just curious, why? I want to write code that works with both the pyPgSQL and PySQLite Python DB-API modules. I've developed PySQLite such that: cursor.execute("-- types int, str, binary") cursor.execute("select a, b, c from sometable") tell PySQLite the "expected" types, so it can convert them from the typeless SQLite engine, which always just returns strings. My hope was that pyPgSQL would just ignore the ANSI SQL comments, but it doesn't, even if I use libpq directly. > It's easy enough to strip them out from an input stream. Sure, I could just hack that into pyPgSQL. -- Gerhard
Tom Lane wrote: > Bruce Momjian <pgman@candle.pha.pa.us> writes: > >>Gerhard Häring wrote: >> >>>Why can't I send comments like >>>-- a comment >>>to the backend using libpq? Are these only handled in psql? Please allow to >>>send comments to the backend, as I really need them. > > >>The backend should handle them fine. Can you give us pgsql version and >>an example. > > I think he's complaining that psql strips out the comments before > sending stuff to the backend. Unfortunately, most of the world probably > considers that a feature, not a bug. Me too. The problem is I use *libpq*. My question was badly asked. I don't care wether the comments end up on the backend, but I want to be able to send comments to libpq. I'd still expect the backend would handle comments, though, should I chose to implement the network protocol myself, without using libpq. > I'm quite certain that libpq does not strip comments, so the complaint > isn't strictly accurate... Then why does the attached program not work? Sorry for sending it twice, my first post is stalled because of an overzealeous TMDA proxy on my side. -- Gerhard /* * testlibpq.c * * Test the C version of libpq, the PostgreSQL frontend * library. */ #include <stdio.h> #include <libpq-fe.h> void exit_nicely(PGconn *conn) { PQfinish(conn); exit(1); } main() { char *pghost, *pgport, *pgoptions, *pgtty; char *dbName; int nFields; int i, j; /* FILE *debug; */ PGconn *conn; PGresult *res; /* * begin, by setting the parameters for a backend connection if the * parameters are null, then the system will try to use reasonable * defaults by looking up environment variables or, failing that, * using hardwired constants */ pghost = NULL; /* host name of the backend server */ pgport = NULL; /* port of the backend server */ pgoptions = NULL; /* special options to start up the backend * server */ pgtty = NULL; /* debugging tty for the backend server */ dbName = "template1"; /* make a connection to the database */ conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName); /* * check to see that the backend connection was successfully made */ if (PQstatus(conn) == CONNECTION_BAD) { fprintf(stderr, "Connection to database '%s' failed.\n", dbName); fprintf(stderr, "%s", PQerrorMessage(conn)); exit_nicely(conn); } /* debug = fopen("/tmp/trace.out","w"); */ /* PQtrace(conn, debug); */ /* start a transaction block */ res = PQexec(conn, "-- foobar"); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "couldn't process comment\n"); PQclear(res); exit_nicely(conn); } /* * should PQclear PGresult whenever it is no longer needed to avoid * memory leaks */ PQclear(res); /* close the connection to the database and cleanup */ PQfinish(conn); /* fclose(debug); */ return 0; }
Gerhard Häring <lists@ghaering.de> writes: >> I'm quite certain that libpq does not strip comments, so the complaint >> isn't strictly accurate... > Then why does the attached program not work? > res = PQexec(conn, "-- foobar"); > if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) Because a comment isn't an SQL command. I forget what the result status is in this case, but COMMAND_OK ain't it. regards, tom lane
Tom Lane wrote: > Gerhard Häring <lists@ghaering.de> writes: > >> I'm quite certain that libpq does not strip comments, so the complaint > >> isn't strictly accurate... > > > Then why does the attached program not work? > > > res = PQexec(conn, "-- foobar"); > > if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) > > Because a comment isn't an SQL command. I forget what the result status > is in this case, but COMMAND_OK ain't it. It returns PGRES_NONFATAL_ERROR. Why should this be an error? -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001+ If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania19073
Bruce Momjian <pgman@candle.pha.pa.us> writes: > It returns PGRES_NONFATAL_ERROR. Why should this be an error? Actually, you don't get a "res" object at all, because nothing happened. The only place in libpq that returns that code is PQresultStatus itself. Perhaps PGRES_EMPTY_QUERY would be more appropriate? Not sure where in the chain would be best to change the behavior, though. regards, tom lane
Hello Tom, Thursday, March 20, 2003, 1:10:36 PM, you wrote: TL> Gerhard Häring <lists@ghaering.de> writes: >>> I'm quite certain that libpq does not strip comments, so the complaint >>> isn't strictly accurate... >> Then why does the attached program not work? >> res = PQexec(conn, "-- foobar"); >> if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) TL> Because a comment isn't an SQL command. I forget what the result status TL> is in this case, but COMMAND_OK ain't it. Probably PGRES_EMPTY_QUERY I think... ------------- Best regards,Steve Howe mailto:howe@carcass.dhs.org
Tom Lane wrote: > Bruce Momjian <pgman@candle.pha.pa.us> writes: > > It returns PGRES_NONFATAL_ERROR. Why should this be an error? > > Actually, you don't get a "res" object at all, because nothing happened. > The only place in libpq that returns that code is PQresultStatus itself. Yes, I see that now. res is NULL and PQresultStatus() is returning PGRES_NONFATAL_ERROR. What is strange is that "" and "\n" both return an OK result, so I am trying to figure out why comments are different. > Perhaps PGRES_EMPTY_QUERY would be more appropriate? Not sure where in > the chain would be best to change the behavior, though. Yes. -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001+ If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania19073
Bruce Momjian <pgman@candle.pha.pa.us> writes: > Yes, I see that now. res is NULL and PQresultStatus() is returning > PGRES_NONFATAL_ERROR. What is strange is that "" and "\n" both return > an OK result, so I am trying to figure out why comments are different. The backend special-cases an input string that contains only whitespace (look in postgres.c). The special case doesn't apply here, though. >> Perhaps PGRES_EMPTY_QUERY would be more appropriate? Not sure where in >> the chain would be best to change the behavior, though. > Yes. Well, we could change the backend --- but that would be a nontrivial change, and to tell you the truth I think the special response for empty query is a wart on the protocol anyhow. In the long run I'd rather get rid of it. Or we could change PQexec to return a PGRES_EMPTY_QUERY result if it gets nothing back from the backend except ReadyForQuery. Question is, does that create the possibility of masking error conditions? Or we could just change PQresultStatus to return PGRES_EMPTY_QUERY for a null input. Attractive 'cause it's a one-line change, but I think it really does create the possibility of masking errors --- application programmer errors, mostly. regards, tom lane
Tom Lane wrote: > Bruce Momjian <pgman@candle.pha.pa.us> writes: > > Yes, I see that now. res is NULL and PQresultStatus() is returning > > PGRES_NONFATAL_ERROR. What is strange is that "" and "\n" both return > > an OK result, so I am trying to figure out why comments are different. > > The backend special-cases an input string that contains only whitespace > (look in postgres.c). The special case doesn't apply here, though. > > >> Perhaps PGRES_EMPTY_QUERY would be more appropriate? Not sure where in > >> the chain would be best to change the behavior, though. > > > Yes. > > Well, we could change the backend --- but that would be a nontrivial > change, and to tell you the truth I think the special response for empty > query is a wart on the protocol anyhow. In the long run I'd rather get > rid of it. Yes, I see that now: if (strspn(parser_input->data, " \t\r\n") == parser_input->len) > Or we could change PQexec to return a PGRES_EMPTY_QUERY result if it > gets nothing back from the backend except ReadyForQuery. Question is, > does that create the possibility of masking error conditions? > > Or we could just change PQresultStatus to return PGRES_EMPTY_QUERY for > a null input. Attractive 'cause it's a one-line change, but I think it > really does create the possibility of masking errors --- application > programmer errors, mostly. Could we change the backend to return NullCommand() if the query string was empty, rather than checking for whitespace directly? I thought the whitespace test was there only as a performance hack. In fact, the comment in postgres.c says that: * if there is nothing in the input buffer, don't *bother trying to parse and execute anything; just * send back a quick NullCommand response. In pg_exec_query_string(), if nothing is processed, we can do the call there. or course assuming destination is correct? -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001+ If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania19073
Bruce Momjian <pgman@candle.pha.pa.us> writes: > Could we change the backend to return NullCommand() if the query string > was empty, rather than checking for whitespace directly? I thought the > whitespace test was there only as a performance hack. It's not a performance hack; it's a performance loss, because 99.99999% of the time the strspn test is wasted. Don't tell me that empty queries are an important case to optimize ;-). The only reason that code is still there is that old versions of libpq used to need to see a special NullCommand response when they deliberately sent empty queries (which IIRC they used to do for NOTIFY checks, many years ago before the backend would send NOTIFYs unprompted). I'd prefer to take NullCommand out of the protocol, not generalize it to understand about comments. Right now seems to be a fine time to think about this, in fact, given that we're hacking the protocol anyway. If we were only dealing with libpq, I think I'd take that code out of the backend and modify PQexec to produce a PGRES_EMPTY_QUERY on getting only ReadyForQuery from the backend. I'm not sure whether JDBC or ODBC might care about NullCommand responses, though --- anyone know? regards, tom lane
Tom Lane wrote: > Bruce Momjian <pgman@candle.pha.pa.us> writes: > > Could we change the backend to return NullCommand() if the query string > > was empty, rather than checking for whitespace directly? I thought the > > whitespace test was there only as a performance hack. > > It's not a performance hack; it's a performance loss, because 99.99999% > of the time the strspn test is wasted. Don't tell me that empty queries > are an important case to optimize ;-). > > The only reason that code is still there is that old versions of libpq > used to need to see a special NullCommand response when they > deliberately sent empty queries (which IIRC they used to do for NOTIFY > checks, many years ago before the backend would send NOTIFYs > unprompted). I'd prefer to take NullCommand out of the protocol, not Right. I am sure it was for that. > generalize it to understand about comments. Right now seems to be a > fine time to think about this, in fact, given that we're hacking the > protocol anyway. Yes. > If we were only dealing with libpq, I think I'd take that code out of > the backend and modify PQexec to produce a PGRES_EMPTY_QUERY on getting > only ReadyForQuery from the backend. I'm not sure whether JDBC or ODBC > might care about NullCommand responses, though --- anyone know? -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001+ If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania19073
Bruce Momjian <pgman@candle.pha.pa.us> writes: > Tom Lane wrote: >> generalize it to understand about comments. Right now seems to be a >> fine time to think about this, in fact, given that we're hacking the >> protocol anyway. > Yes. On third thought, though, it would be really trivial for pg_exec_query_string to call NullCommand and fall out early if pg_parse_query returns an empty list; it'd take one extra test for NIL, which would be more than compensated for if we got rid of the strspn test. So maybe changing the backend is the best answer after all. regards, tom lane
Tom Lane wrote: > Bruce Momjian <pgman@candle.pha.pa.us> writes: > > Tom Lane wrote: > >> generalize it to understand about comments. Right now seems to be a > >> fine time to think about this, in fact, given that we're hacking the > >> protocol anyway. > > > Yes. > > On third thought, though, it would be really trivial for > pg_exec_query_string to call NullCommand and fall out early if > pg_parse_query returns an empty list; it'd take one extra test for NIL, > which would be more than compensated for if we got rid of the strspn > test. So maybe changing the backend is the best answer after all. Yes, that was my original thought. -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001+ If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania19073
OK, this patch fixes the comment passing bug. I remove the strspn() and added a boolean to test if any parsetree had been generated --- if not, I call NullCommand(). I also changed the call to use 'dest' rather than a hardwired "Remote". --------------------------------------------------------------------------- Tom Lane wrote: > Bruce Momjian <pgman@candle.pha.pa.us> writes: > > Tom Lane wrote: > >> generalize it to understand about comments. Right now seems to be a > >> fine time to think about this, in fact, given that we're hacking the > >> protocol anyway. > > > Yes. > > On third thought, though, it would be really trivial for > pg_exec_query_string to call NullCommand and fall out early if > pg_parse_query returns an empty list; it'd take one extra test for NIL, > which would be more than compensated for if we got rid of the strspn > test. So maybe changing the backend is the best answer after all. > > regards, tom lane > > ---------------------------(end of broadcast)--------------------------- > TIP 3: if posting/reading through Usenet, please send an appropriate > subscribe-nomail command to majordomo@postgresql.org so that your > message can get through to the mailing list cleanly > -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073 Index: src/backend/tcop/postgres.c =================================================================== RCS file: /cvsroot/pgsql-server/src/backend/tcop/postgres.c,v retrieving revision 1.318 diff -c -c -r1.318 postgres.c *** src/backend/tcop/postgres.c 20 Mar 2003 07:02:10 -0000 1.318 --- src/backend/tcop/postgres.c 21 Mar 2003 05:14:15 -0000 *************** *** 553,559 **** MemoryContext parse_context) /* context for * parsetrees */ { ! bool xact_started; MemoryContext oldcontext; List *parsetree_list, *parsetree_item; --- 553,559 ---- MemoryContext parse_context) /* context for * parsetrees */ { ! bool xact_started, was_parsetree = false; MemoryContext oldcontext; List *parsetree_list, *parsetree_item; *************** *** 618,623 **** --- 618,624 ---- List *querytree_list, *querytree_item; + was_parsetree = true; /* * First we set the command-completion tag to the main query (as * opposed to each of the others that may be generated by analyze *************** *** 927,932 **** --- 928,936 ---- EndCommand(commandTag, dest); } /* end loop over parsetrees */ + if (!was_parsetree && IsUnderPostmaster) + NullCommand(dest); + /* * Close down transaction statement, if one is open. (Note that this * will only happen if the querystring was empty.) *************** *** 1995,2030 **** * 'Q' indicates a user query */ case 'Q': ! if (strspn(parser_input->data, " \t\r\n") == parser_input->len) ! { ! /* ! * if there is nothing in the input buffer, don't ! * bother trying to parse and execute anything; just ! * send back a quick NullCommand response. ! */ ! if (IsUnderPostmaster) ! NullCommand(Remote); ! } ! else ! { ! /* ! * otherwise, process the input string. ! * ! * Note: transaction command start/end is now done within ! * pg_exec_query_string(), not here. ! */ ! if (log_statement_stats) ! ResetUsage(); ! pgstat_report_activity(parser_input->data); ! pg_exec_query_string(parser_input, ! whereToSendOutput, ! QueryContext); ! if (log_statement_stats) ! ShowUsage("QUERY STATISTICS"); ! } break; /* --- 1999,2021 ---- * 'Q' indicates a user query */ case 'Q': ! /* ! * otherwise, process the input string. ! * ! * Note: transaction command start/end is now done within ! * pg_exec_query_string(), not here. ! */ ! if (log_statement_stats) ! ResetUsage(); ! pgstat_report_activity(parser_input->data); ! pg_exec_query_string(parser_input, ! whereToSendOutput, ! QueryContext); ! if (log_statement_stats) ! ShowUsage("QUERY STATISTICS"); break; /*
Bruce Momjian <pgman@candle.pha.pa.us> writes: > OK, this patch fixes the comment passing bug. I remove the strspn() and > added a boolean to test if any parsetree had been generated --- if not, > I call NullCommand(). Seems like the hard way. I had in mind a quick if (parsetree_list == NIL){ NullCommand(dest); return;} before entering the main loop. It'd take a small amount of reordering of the existing code to make this happen without adding any more code than that, but it looked doable. regards, tom lane
Tom Lane wrote: > Bruce Momjian <pgman@candle.pha.pa.us> writes: > > OK, this patch fixes the comment passing bug. I remove the strspn() and > > added a boolean to test if any parsetree had been generated --- if not, > > I call NullCommand(). > > Seems like the hard way. I had in mind a quick > > if (parsetree_list == NIL) > { > NullCommand(dest); > return; > } > > before entering the main loop. It'd take a small amount of reordering > of the existing code to make this happen without adding any more code > than that, but it looked doable. The problem is that there is so much startup/shutdown in that function that adding a quick exit point seems too error-prone for maintenance, rather than keeping the existing structure. I used your idea of testing just 'parsetree_list' and the patch is now smaller. -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073 Index: src/backend/tcop/postgres.c =================================================================== RCS file: /cvsroot/pgsql-server/src/backend/tcop/postgres.c,v retrieving revision 1.318 diff -c -c -r1.318 postgres.c *** src/backend/tcop/postgres.c 20 Mar 2003 07:02:10 -0000 1.318 --- src/backend/tcop/postgres.c 21 Mar 2003 05:52:56 -0000 *************** *** 927,932 **** --- 927,936 ---- EndCommand(commandTag, dest); } /* end loop over parsetrees */ + /* No parsetree - return empty result */ + if (!parsetree_list && IsUnderPostmaster) + NullCommand(dest); + /* * Close down transaction statement, if one is open. (Note that this * will only happen if the querystring was empty.) *************** *** 1995,2030 **** * 'Q' indicates a user query */ case 'Q': ! if (strspn(parser_input->data, " \t\r\n") == parser_input->len) ! { ! /* ! * if there is nothing in the input buffer, don't ! * bother trying to parse and execute anything; just ! * send back a quick NullCommand response. ! */ ! if (IsUnderPostmaster) ! NullCommand(Remote); ! } ! else ! { ! /* ! * otherwise, process the input string. ! * ! * Note: transaction command start/end is now done within ! * pg_exec_query_string(), not here. ! */ ! if (log_statement_stats) ! ResetUsage(); ! pgstat_report_activity(parser_input->data); ! pg_exec_query_string(parser_input, ! whereToSendOutput, ! QueryContext); ! if (log_statement_stats) ! ShowUsage("QUERY STATISTICS"); ! } break; /* --- 1999,2021 ---- * 'Q' indicates a user query */ case 'Q': ! /* ! * otherwise, process the input string. ! * ! * Note: transaction command start/end is now done within ! * pg_exec_query_string(), not here. ! */ ! if (log_statement_stats) ! ResetUsage(); ! pgstat_report_activity(parser_input->data); ! pg_exec_query_string(parser_input, ! whereToSendOutput, ! QueryContext); ! if (log_statement_stats) ! ShowUsage("QUERY STATISTICS"); break; /*
I now understand that IsUnderPostmaster isn't needed, as you suggested below. --------------------------------------------------------------------------- Tom Lane wrote: > Bruce Momjian <pgman@candle.pha.pa.us> writes: > > OK, this patch fixes the comment passing bug. I remove the strspn() and > > added a boolean to test if any parsetree had been generated --- if not, > > I call NullCommand(). > > Seems like the hard way. I had in mind a quick > > if (parsetree_list == NIL) > { > NullCommand(dest); > return; > } > > before entering the main loop. It'd take a small amount of reordering > of the existing code to make this happen without adding any more code > than that, but it looked doable. > > regards, tom lane > > ---------------------------(end of broadcast)--------------------------- > TIP 2: you can get off all lists at once with the unregister command > (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) > -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001+ If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania19073
Bruce Momjian <pgman@candle.pha.pa.us> writes: > I used your idea of testing just 'parsetree_list' and the patch is now > smaller. You cannot drop out there -- the xact is still open. regards, tom lane
Tom Lane wrote: > Bruce Momjian <pgman@candle.pha.pa.us> writes: > > I used your idea of testing just 'parsetree_list' and the patch is now > > smaller. > > You cannot drop out there -- the xact is still open. I didn't drop out. I just called NullCommand(). There is no 'return' there. -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001+ If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania19073
Tom Lane <tgl@sss.pgh.pa.us> writes: > I think he's complaining that psql strips out the comments before > sending stuff to the backend. Unfortunately, most of the world probably > considers that a feature, not a bug. I don't know why this user wants them but I can give one example of why one might want to have comments get processed by the backend: In my previous project we had the database wrapper functions insert the file and line number where the call to the wrapper functions were made in sql comments in the query. This was **invaluable** for tracking down problems when the only evidence was information in the logs or query cache. It was so valuable and so easy that I definitely intend to reimplement it on my current project and on any future projects. > I'm quite certain that libpq does not strip comments, so the complaint > isn't strictly accurate... Happy news. But a plea to any interface implementors: *Please* don't even consider stripping comments from queries, It would be most annoying for at least this user. -- greg
Bruce Momjian wrote: > Gerhard Häring wrote: > >>Why can't I send comments like >> >> -- a comment >> >>to the backend using libpq? Are these only handled in psql? Please allow to >>send comments to the backend, as I really need them. > > The backend should handle them fine. Can you give us pgsql version and > an example. I experience it on 7.2.1 on Debian Woody here. Same on 7.3.1 AFAIK. I attached a minimal libpq example in C (to rule out any interference from my Python modules) that shows the problem. -- Gerhard /* * testlibpq.c * * Test the C version of libpq, the PostgreSQL frontend * library. */ #include <stdio.h> #include <libpq-fe.h> void exit_nicely(PGconn *conn) { PQfinish(conn); exit(1); } main() { char *pghost, *pgport, *pgoptions, *pgtty; char *dbName; int nFields; int i, j; /* FILE *debug; */ PGconn *conn; PGresult *res; /* * begin, by setting the parameters for a backend connection if the * parameters are null, then the system will try to use reasonable * defaults by looking up environment variables or, failing that, * using hardwired constants */ pghost = NULL; /* host name of the backend server */ pgport = NULL; /* port of the backend server */ pgoptions = NULL; /* special options to start up the backend * server */ pgtty = NULL; /* debugging tty for the backend server */ dbName = "template1"; /* make a connection to the database */ conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName); /* * check to see that the backend connection was successfully made */ if (PQstatus(conn) == CONNECTION_BAD) { fprintf(stderr, "Connection to database '%s' failed.\n", dbName); fprintf(stderr, "%s", PQerrorMessage(conn)); exit_nicely(conn); } /* debug = fopen("/tmp/trace.out","w"); */ /* PQtrace(conn, debug); */ /* start a transaction block */ res = PQexec(conn, "-- foobar"); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "couldn't process comment\n"); PQclear(res); exit_nicely(conn); } /* * should PQclear PGresult whenever it is no longer needed to avoid * memory leaks */ PQclear(res); /* close the connection to the database and cleanup */ PQfinish(conn); /* fclose(debug); */ return 0; }