Skip to content

Commit 969b6f1

Browse files
committed
named_params: Ignore numeric params
numeric unused params are undistinguishable from numeric bindable parameters. So a simple loop from 1-bind_parameter_count is the best you can do. This means .named_params can be focused on the truly named parameters only, which is what This commit does by dropping numeric parameters
1 parent c73faa9 commit 969b6f1

3 files changed

Lines changed: 22 additions & 11 deletions

File tree

FAQ.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,11 @@ Placeholders in an SQL statement take any of the following formats:
122122
* `?`
123123
* `?_nnn_`
124124
* `:_word_`
125+
* `:_nnn_`
126+
* `$_word_`
127+
* `$_nnn_`
128+
* `@_word_`
129+
* `@_nnn_`
125130

126131

127132
Where _n_ is an integer, and _word_ is an alpha-numeric identifier (or

ext/sqlite3/statement.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -460,9 +460,14 @@ bind_parameter_count(VALUE self)
460460
return INT2NUM(sqlite3_bind_parameter_count(ctx->st));
461461
}
462462

463-
/** call-seq: stmt.named_params
463+
/** call-seq: stmt.params
464+
*
465+
* Return the list of named alphanumeric parameters in the statement.
466+
* This returns a list of strings.
467+
* The values of this list can be used to bind parameters
468+
* to the statement using bind_param. Numeric and anonymous parameters
469+
* are ignored.
464470
*
465-
* Return the list of named parameters in the statement.
466471
*/
467472
static VALUE
468473
named_params(VALUE self)
@@ -479,12 +484,15 @@ named_params(VALUE self)
479484
// The first host parameter has an index of 1, not 0.
480485
for (int i = 1; i <= param_count; i++) {
481486
const char *name = sqlite3_bind_parameter_name(ctx->st, i);
482-
// If parameters of the ?NNN form are used, there may be gaps in the list.
487+
// If parameters of the ?NNN/$NNN/@NNN/:NNN form are used
488+
// there may be gaps in the list.
483489
if (name) {
484-
VALUE rb_name = interned_utf8_cstr(name);
485-
// The initial ":" or "$" or "@" or "?" is included as part of the name.
486-
rb_name = rb_str_substr(rb_name, 1, RSTRING_LEN(rb_name) - 1);
487-
rb_ary_push(params, rb_name);
490+
// We ignore numeric parameters
491+
int n = atoi(name + 1);
492+
if (n == 0) {
493+
VALUE param = interned_utf8_cstr(name + 1);
494+
rb_ary_push(params, param);
495+
}
488496
}
489497
}
490498
return rb_obj_freeze(params);

test/test_statement.rb

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -256,10 +256,8 @@ def test_named_bind_not_found
256256
stmt.close
257257
end
258258

259-
def test_named_params
260-
assert_empty @stmt.named_params
261-
262-
stmt = SQLite3::Statement.new(@db, "select :foo, $bar, @zed")
259+
def test_params
260+
stmt = SQLite3::Statement.new(@db, "select ?1, :foo, ?, $bar, @zed, ?250, @999")
263261
assert_equal ["foo", "bar", "zed"], stmt.named_params
264262
stmt.close
265263
end

0 commit comments

Comments
 (0)