Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible to make SQLite3::Statement#to_s more useful? #293

Closed
sixtyfive opened this issue Oct 25, 2020 · 3 comments · Fixed by #498
Closed

Possible to make SQLite3::Statement#to_s more useful? #293

sixtyfive opened this issue Oct 25, 2020 · 3 comments · Fixed by #498
Labels
Milestone

Comments

@sixtyfive
Copy link

sixtyfive commented Oct 25, 2020

Hi, after trying to debug something for a while and not being able to figure out how to see the SQL produced by sqlite3-ruby I'm now wondering why the following is the way it is:

qry = db.prepare("SELECT * FROM table WHERE a = ?")
qry.bind_params(123)
p qry.to_s # #<SQLite3::Statement:0x000055ed3b1d1f68>

An output like

SELECT * FROM table WHERE a = 123:

would be more helpful and expected.

@tenderlove
Copy link
Member

On main, the output is like this:

irb(main):001> require "sqlite3"
=> true
irb(main):002> db = SQLite3::Database.new(":memory:")
=> 
#<SQLite3::Database:0x000000011dd805e0
...
irb(main):003> db.prepare "SELECT 1"
=> 
#<SQLite3::Statement:0x000000011dd603f8
 @columns=nil,
 @connection=
  #<SQLite3::Database:0x000000011dd805e0
   @authorizer=nil,
   @busy_handler=nil,
   @collations={},
   @default_transaction_mode=:deferred,
   @encoding=nil,
   @functions={},
   @readonly=false,
   @results_as_hash=nil,
   @tracefunc=nil,
   @type_translation=nil,
   @type_translator=#<Proc:0x000000011d8a84c8 /Users/aaron/git/sqlite3-ruby/lib/sqlite3/database.rb:747 (lambda)>>,
 @remainder="",
 @types=nil>
irb(main):004>

The gem throws away the SQL and bind params (after they're cast) because the statement doesn't need them anymore. We could modify the statement object to hold a reference, but that means the strings would live longer (IOW not get GC'd as quickly).

Is improving inspect output worth the cost of keeping (usually) unnecessary data around?

@sixtyfive
Copy link
Author

When I wrote the issue, I was in the middle of a debugging session and really having difficulty figuring things out because the mental load was already high and working memory (my brain's, not the computer's) constantly at its limit. Reading your post, then mine again, I really do see your point. In production, SQLite is all about speed and efficiency. Perhaps this would need to be implemented as some sort of debugging flag. An environment variable switch, perhaps?

@tenderlove
Copy link
Member

Perhaps this would need to be implemented as some sort of debugging flag. An environment variable switch, perhaps?

I think that's a good idea. We could do something like:

if $DEBUG
  @query = the_string
end

You can enable $DEBUG with a command line flag to Ruby (ruby -d script.rb).

@tenderlove tenderlove added this to the 2.0.0 milestone Jan 24, 2024
tenderlove added a commit that referenced this issue Feb 1, 2024
These methods allow you to retrieve the SQL statement that was used to
create the statement object.  The `sql` method just returns the sql
statement, where the `expanded_sql` method returns the statement but
with bind parameters substituted.

This should aid with debugging and other tasks.

Fixes #293
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants