Clint Byrum wrote:

On Oct 13, 2009, at 6:56 AM, Jay Pipes wrote:


For #1 in 14 years of programming, I've never worked on any application where I have had the need to "prepare" a SELECT statement that would be executed more than once in a single connection. Never. If I were to do so, I would ask myself why I wasn't doing a single SELECT statement to begin with....


The "Nibble" algorithm used in Maatkit (mk-archiver and I think mk-checksum-table as well) has a nice example of a good usage of running the same select many, many times. In short, the algorithm has you finding the row with PKcolumn = min(PKcolumn), then selecting like this:

select PKcolumn,x,y,z from table where PKcolumn > :lastpk order by PKcolumn limit 10

This allows you to traverse an entire table 10 rows at a time, avoiding locks, and providing the ability to sleep between them to ease the burden on the database and prevent your query from taking the entire buffer pool. This is essentially a bulk "get data out of the database" operation.

Also there are plenty of applications, like asynchronous backend process subscribers, that will run in an infinite loop and be fed arguments and return data on the same connection over and over. The less repetitive work these have to do, the better.

I agree that uint8_t * is the way to go for the args. Essentially what the prepared statement API is doing is building a parsed sql tree with the data nodes empty... so the actual query execution method would just fill in those nodes then feed the query to the next step in the execution chain. For most language bindings, its going to be pretty natural to provide a uint8_t * and length. Doing it w/ multiple types would just make the code more complex for a very small client side win of not having to convert your ints.

The above does indeed make sense to me. Thank you for your clear explanation and thorough response, Clint.

FWIW, in my email response I wasn't necessarily arguing that preparing a SELECT statement should not be *allowed*, but that the API should make it clear and easy to do a simple SELECT (and even lots of modifications) without having to bumble through an awkward bind and prepare API.

This is why my proposed API was this:

drizzle_statement_st *drizzle_create_statement
(
  drizzle_con_st *connection,
  drizzle_statement_st *statement,
  const char *query,
  drizzle_ret_t *return_code,
  uint8_t** records
);

#define drizzle_select(A,B,C,D) drizzle_create_statement( \
  (A), \
  (B), \
  (C), \
  (D), \
  NULL)

If you look at my original response, the point was to make things simple, and have a simpler API that hid the binding and preparation in a cleaner, easier API.

Cheers,

Jay

_______________________________________________
Mailing list: https://launchpad.net/~drizzle-discuss
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~drizzle-discuss
More help   : https://help.launchpad.net/ListHelp

Reply via email to