extralite 2.6 → 2.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -162,6 +162,12 @@ static inline VALUE row_to_ary(sqlite3_stmt *stmt, int column_count) {
162
162
  return row;
163
163
  }
164
164
 
165
+ static inline void row_to_argv_values(sqlite3_stmt *stmt, int column_count, VALUE *values) {
166
+ for (int i = 0; i < column_count; i++) {
167
+ values[i] = get_column_value(stmt, i, sqlite3_column_type(stmt, i));
168
+ }
169
+ }
170
+
165
171
  typedef struct {
166
172
  sqlite3 *db;
167
173
  sqlite3_stmt **stmt;
@@ -315,65 +321,130 @@ VALUE cleanup_stmt(query_ctx *ctx) {
315
321
  return Qnil;
316
322
  }
317
323
 
324
+ VALUE safe_query_argv(query_ctx *ctx);
325
+
318
326
  VALUE safe_query_hash(query_ctx *ctx) {
319
- VALUE array = MULTI_ROW_P(ctx->mode) ? rb_ary_new() : Qnil;
327
+ VALUE array = ROW_MULTI_P(ctx->row_mode) ? rb_ary_new() : Qnil;
320
328
  VALUE row = Qnil;
321
329
  int column_count = sqlite3_column_count(ctx->stmt);
322
330
  VALUE column_names = get_column_names(ctx->stmt, column_count);
323
331
  int row_count = 0;
332
+ int do_transform = !NIL_P(ctx->transform_proc);
324
333
 
325
334
  while (stmt_iterate(ctx)) {
326
335
  row = row_to_hash(ctx->stmt, column_count, column_names);
336
+ if (do_transform)
337
+ row = rb_funcall(ctx->transform_proc, ID_call, 1, row);
327
338
  row_count++;
328
- switch (ctx->mode) {
329
- case QUERY_YIELD:
339
+ switch (ctx->row_mode) {
340
+ case ROW_YIELD:
330
341
  rb_yield(row);
331
342
  break;
332
- case QUERY_MULTI_ROW:
343
+ case ROW_MULTI:
333
344
  rb_ary_push(array, row);
334
345
  break;
335
- case QUERY_SINGLE_ROW:
346
+ case ROW_SINGLE:
336
347
  return row;
337
348
  }
338
349
  if (ctx->max_rows != ALL_ROWS && row_count >= ctx->max_rows)
339
- return MULTI_ROW_P(ctx->mode) ? array : ctx->self;
350
+ return ROW_MULTI_P(ctx->row_mode) ? array : ctx->self;
340
351
  }
341
352
 
342
353
  RB_GC_GUARD(column_names);
343
354
  RB_GC_GUARD(row);
344
355
  RB_GC_GUARD(array);
345
- return MULTI_ROW_P(ctx->mode) ? array : Qnil;
356
+ return ROW_MULTI_P(ctx->row_mode) ? array : Qnil;
357
+ }
358
+
359
+ #define MAX_ARGV_COLUMNS 8
360
+ #define NIL_ARGV_VALUES {Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil}
361
+ #define ARGV_GC_GUARD(values) \
362
+ RB_GC_GUARD(values[0]); \
363
+ RB_GC_GUARD(values[1]); \
364
+ RB_GC_GUARD(values[2]); \
365
+ RB_GC_GUARD(values[3]); \
366
+ RB_GC_GUARD(values[4]); \
367
+ RB_GC_GUARD(values[5]); \
368
+ RB_GC_GUARD(values[6]); \
369
+ RB_GC_GUARD(values[7])
370
+
371
+ #define ARGV_GET_ROW(ctx, column_count, argv_values, row, do_transform, return_rows) \
372
+ row_to_argv_values(ctx->stmt, column_count, argv_values); \
373
+ if (do_transform) \
374
+ row = rb_funcall2(ctx->transform_proc, ID_call, column_count, argv_values); \
375
+ else if (return_rows) \
376
+ row = column_count == 1 ? argv_values[0] : rb_ary_new_from_values(column_count, argv_values);
377
+
378
+ VALUE safe_query_argv(query_ctx *ctx) {
379
+ VALUE array = ROW_MULTI_P(ctx->row_mode) ? rb_ary_new() : Qnil;
380
+ VALUE argv_values[MAX_ARGV_COLUMNS] = NIL_ARGV_VALUES;
381
+ VALUE row = Qnil;
382
+ int column_count = sqlite3_column_count(ctx->stmt);
383
+ if (column_count > MAX_ARGV_COLUMNS)
384
+ rb_raise(cError, "Conversion is supported only up to %d columns", MAX_ARGV_COLUMNS);
385
+
386
+ int do_transform = !NIL_P(ctx->transform_proc);
387
+ int return_rows = (ctx->row_mode != ROW_YIELD);
388
+
389
+ int row_count = 0;
390
+ while (stmt_iterate(ctx)) {
391
+ row_count++;
392
+ ARGV_GET_ROW(ctx, column_count, argv_values, row, do_transform, return_rows);
393
+ switch (ctx->row_mode) {
394
+ case ROW_YIELD:
395
+ if (do_transform)
396
+ rb_yield(row);
397
+ else
398
+ rb_yield_values2(column_count, argv_values);
399
+ break;
400
+ case ROW_MULTI:
401
+ rb_ary_push(array, row);
402
+ break;
403
+ case ROW_SINGLE:
404
+ return row;
405
+ }
406
+ if (ctx->max_rows != ALL_ROWS && row_count >= ctx->max_rows)
407
+ return ROW_MULTI_P(ctx->row_mode) ? array : ctx->self;
408
+ }
409
+
410
+ ARGV_GC_GUARD(argv_values);
411
+ RB_GC_GUARD(row);
412
+ RB_GC_GUARD(array);
413
+ return ROW_MULTI_P(ctx->row_mode) ? array : Qnil;
346
414
  }
347
415
 
348
416
  VALUE safe_query_ary(query_ctx *ctx) {
349
- VALUE array = MULTI_ROW_P(ctx->mode) ? rb_ary_new() : Qnil;
417
+ VALUE array = ROW_MULTI_P(ctx->row_mode) ? rb_ary_new() : Qnil;
350
418
  VALUE row = Qnil;
351
419
  int column_count = sqlite3_column_count(ctx->stmt);
352
420
  int row_count = 0;
421
+ int do_transform = !NIL_P(ctx->transform_proc);
353
422
 
354
423
  while (stmt_iterate(ctx)) {
355
424
  row = row_to_ary(ctx->stmt, column_count);
425
+ if (do_transform)
426
+ row = rb_funcall(ctx->transform_proc, ID_call, 1, row);
356
427
  row_count++;
357
- switch (ctx->mode) {
358
- case QUERY_YIELD:
428
+ switch (ctx->row_mode) {
429
+ case ROW_YIELD:
359
430
  rb_yield(row);
360
431
  break;
361
- case QUERY_MULTI_ROW:
432
+ case ROW_MULTI:
362
433
  rb_ary_push(array, row);
363
434
  break;
364
- case QUERY_SINGLE_ROW:
435
+ case ROW_SINGLE:
365
436
  return row;
366
437
  }
367
438
  if (ctx->max_rows != ALL_ROWS && row_count >= ctx->max_rows)
368
- return MULTI_ROW_P(ctx->mode) ? array : ctx->self;
439
+ return ROW_MULTI_P(ctx->row_mode) ? array : ctx->self;
369
440
  }
370
441
 
371
442
  RB_GC_GUARD(row);
372
443
  RB_GC_GUARD(array);
373
- return MULTI_ROW_P(ctx->mode) ? array : Qnil;
444
+ return ROW_MULTI_P(ctx->row_mode) ? array : Qnil;
374
445
  }
375
446
 
376
- VALUE safe_query_single_row(query_ctx *ctx) {
447
+ VALUE safe_query_single_row_hash(query_ctx *ctx) {
377
448
  int column_count;
378
449
  VALUE row = Qnil;
379
450
  VALUE column_names;
@@ -381,64 +452,54 @@ VALUE safe_query_single_row(query_ctx *ctx) {
381
452
  column_count = sqlite3_column_count(ctx->stmt);
382
453
  column_names = get_column_names(ctx->stmt, column_count);
383
454
 
384
- if (stmt_iterate(ctx))
455
+ if (stmt_iterate(ctx)) {
385
456
  row = row_to_hash(ctx->stmt, column_count, column_names);
457
+ if (!NIL_P(ctx->transform_proc))
458
+ row = rb_funcall(ctx->transform_proc, ID_call, 1, row);
459
+ }
386
460
 
387
461
  RB_GC_GUARD(row);
388
462
  RB_GC_GUARD(column_names);
389
463
  return row;
390
464
  }
391
465
 
392
- VALUE safe_query_single_column(query_ctx *ctx) {
393
- VALUE array = MULTI_ROW_P(ctx->mode) ? rb_ary_new() : Qnil;
394
- VALUE value = Qnil;
466
+ VALUE safe_query_single_row_argv(query_ctx *ctx) {
467
+ VALUE argv_values[MAX_ARGV_COLUMNS] = NIL_ARGV_VALUES;
468
+ VALUE row = Qnil;
395
469
  int column_count = sqlite3_column_count(ctx->stmt);
396
- int row_count = 0;
397
-
398
- if (column_count != 1) rb_raise(cError, "Expected query result to have 1 column");
470
+ if (column_count > MAX_ARGV_COLUMNS)
471
+ rb_raise(cError, "Conversion is supported only up to %d columns", MAX_ARGV_COLUMNS);
472
+ int do_transform = !NIL_P(ctx->transform_proc);
399
473
 
400
- while (stmt_iterate(ctx)) {
401
- value = get_column_value(ctx->stmt, 0, sqlite3_column_type(ctx->stmt, 0));
402
- row_count++;
403
- switch (ctx->mode) {
404
- case QUERY_YIELD:
405
- rb_yield(value);
406
- break;
407
- case QUERY_MULTI_ROW:
408
- rb_ary_push(array, value);
409
- break;
410
- case QUERY_SINGLE_ROW:
411
- return value;
412
- }
413
- if (ctx->max_rows != ALL_ROWS && row_count >= ctx->max_rows)
414
- return MULTI_ROW_P(ctx->mode) ? array : ctx->self;
474
+ if (stmt_iterate(ctx)) {
475
+ ARGV_GET_ROW(ctx, column_count, argv_values, row, do_transform, 1);
415
476
  }
416
477
 
417
- RB_GC_GUARD(value);
418
- RB_GC_GUARD(array);
419
- return MULTI_ROW_P(ctx->mode) ? array : Qnil;
478
+ ARGV_GC_GUARD(argv_values);
479
+ RB_GC_GUARD(row);
480
+ return row;
420
481
  }
421
482
 
422
- VALUE safe_query_single_value(query_ctx *ctx) {
423
- int column_count;
424
- VALUE value = Qnil;
425
-
426
- column_count = sqlite3_column_count(ctx->stmt);
427
- if (column_count != 1)
428
- rb_raise(cError, "Expected query result to have 1 column");
483
+ VALUE safe_query_single_row_ary(query_ctx *ctx) {
484
+ int column_count = sqlite3_column_count(ctx->stmt);
485
+ VALUE row = Qnil;
486
+ int do_transform = !NIL_P(ctx->transform_proc);
429
487
 
430
- if (stmt_iterate(ctx))
431
- value = get_column_value(ctx->stmt, 0, sqlite3_column_type(ctx->stmt, 0));
488
+ if (stmt_iterate(ctx)) {
489
+ row = row_to_ary(ctx->stmt, column_count);
490
+ if (do_transform)
491
+ row = rb_funcall(ctx->transform_proc, ID_call, 1, row);
492
+ }
432
493
 
433
- RB_GC_GUARD(value);
434
- return value;
494
+ RB_GC_GUARD(row);
495
+ return row;
435
496
  }
436
497
 
437
498
  enum batch_mode {
438
499
  BATCH_EXECUTE,
439
- BATCH_QUERY_ARY,
440
500
  BATCH_QUERY_HASH,
441
- BATCH_QUERY_SINGLE_COLUMN
501
+ BATCH_QUERY_ARGV,
502
+ BATCH_QUERY_ARY,
442
503
  };
443
504
 
444
505
  static inline VALUE batch_iterate_hash(query_ctx *ctx) {
@@ -446,13 +507,17 @@ static inline VALUE batch_iterate_hash(query_ctx *ctx) {
446
507
  VALUE row = Qnil;
447
508
  int column_count = sqlite3_column_count(ctx->stmt);
448
509
  VALUE column_names = get_column_names(ctx->stmt, column_count);
510
+ const int do_transform = !NIL_P(ctx->transform_proc);
449
511
 
450
512
  while (stmt_iterate(ctx)) {
451
513
  row = row_to_hash(ctx->stmt, column_count, column_names);
514
+ if (do_transform)
515
+ row = rb_funcall(ctx->transform_proc, ID_call, 1, row);
452
516
  rb_ary_push(rows, row);
453
517
  }
454
518
 
455
519
  RB_GC_GUARD(column_names);
520
+ RB_GC_GUARD(row);
456
521
  RB_GC_GUARD(rows);
457
522
  return rows;
458
523
  }
@@ -461,27 +526,36 @@ static inline VALUE batch_iterate_ary(query_ctx *ctx) {
461
526
  VALUE rows = rb_ary_new();
462
527
  VALUE row = Qnil;
463
528
  int column_count = sqlite3_column_count(ctx->stmt);
529
+ int do_transform = !NIL_P(ctx->transform_proc);
464
530
 
465
531
  while (stmt_iterate(ctx)) {
466
532
  row = row_to_ary(ctx->stmt, column_count);
533
+ if (do_transform)
534
+ row = rb_funcall(ctx->transform_proc, ID_call, 1, row);
467
535
  rb_ary_push(rows, row);
468
536
  }
469
537
 
538
+ RB_GC_GUARD(row);
470
539
  RB_GC_GUARD(rows);
471
540
  return rows;
472
541
  }
473
542
 
474
- static inline VALUE batch_iterate_single_column(query_ctx *ctx) {
543
+ static inline VALUE batch_iterate_argv(query_ctx *ctx) {
475
544
  VALUE rows = rb_ary_new();
476
- VALUE value = Qnil;
545
+ VALUE argv_values[MAX_ARGV_COLUMNS] = NIL_ARGV_VALUES;
546
+ VALUE row = Qnil;
477
547
  int column_count = sqlite3_column_count(ctx->stmt);
478
- if (column_count != 1) rb_raise(cError, "Expected query result to have 1 column");
548
+ if (column_count > MAX_ARGV_COLUMNS)
549
+ rb_raise(cError, "Conversion is supported only up to %d columns", MAX_ARGV_COLUMNS);
550
+ int do_transform = !NIL_P(ctx->transform_proc);
479
551
 
480
552
  while (stmt_iterate(ctx)) {
481
- value = get_column_value(ctx->stmt, 0, sqlite3_column_type(ctx->stmt, 0));
482
- rb_ary_push(rows, value);
553
+ ARGV_GET_ROW(ctx, column_count, argv_values, row, do_transform, 1);
554
+ rb_ary_push(rows, row);
483
555
  }
484
556
 
557
+ ARGV_GC_GUARD(argv_values);
558
+ RB_GC_GUARD(row);
485
559
  RB_GC_GUARD(rows);
486
560
  return rows;
487
561
  }
@@ -491,34 +565,35 @@ static inline void batch_iterate(query_ctx *ctx, enum batch_mode mode, VALUE *ro
491
565
  case BATCH_EXECUTE:
492
566
  while (stmt_iterate(ctx));
493
567
  break;
494
- case BATCH_QUERY_ARY:
495
- *rows = batch_iterate_ary(ctx);
496
- break;
497
568
  case BATCH_QUERY_HASH:
498
569
  *rows = batch_iterate_hash(ctx);
499
570
  break;
500
- case BATCH_QUERY_SINGLE_COLUMN:
501
- *rows = batch_iterate_single_column(ctx);
571
+ case BATCH_QUERY_ARGV:
572
+ *rows = batch_iterate_argv(ctx);
573
+ break;
574
+ case BATCH_QUERY_ARY:
575
+ *rows = batch_iterate_ary(ctx);
502
576
  break;
503
577
  }
504
578
  }
505
579
 
506
- static inline VALUE batch_run_array(query_ctx *ctx, enum batch_mode mode) {
580
+ static inline VALUE batch_run_array(query_ctx *ctx, enum batch_mode batch_mode) {
507
581
  int count = RARRAY_LEN(ctx->params);
508
582
  int block_given = rb_block_given_p();
509
- VALUE results = (mode != BATCH_EXECUTE) && !block_given ? rb_ary_new() : Qnil;
583
+ VALUE results = (batch_mode != BATCH_EXECUTE) && !block_given ? rb_ary_new() : Qnil;
510
584
  VALUE rows = Qnil;
511
585
  int changes = 0;
512
586
 
513
587
  for (int i = 0; i < count; i++) {
514
588
  sqlite3_reset(ctx->stmt);
515
589
  sqlite3_clear_bindings(ctx->stmt);
590
+ Database_issue_query(ctx->db, ctx->sql);
516
591
  bind_all_parameters_from_object(ctx->stmt, RARRAY_AREF(ctx->params, i));
517
592
 
518
- batch_iterate(ctx, mode, &rows);
593
+ batch_iterate(ctx, batch_mode, &rows);
519
594
  changes += sqlite3_changes(ctx->sqlite3_db);
520
595
 
521
- if (mode != BATCH_EXECUTE) {
596
+ if (batch_mode != BATCH_EXECUTE) {
522
597
  if (block_given)
523
598
  rb_yield(rows);
524
599
  else
@@ -529,7 +604,7 @@ static inline VALUE batch_run_array(query_ctx *ctx, enum batch_mode mode) {
529
604
  RB_GC_GUARD(rows);
530
605
  RB_GC_GUARD(results);
531
606
 
532
- if (mode == BATCH_EXECUTE || block_given)
607
+ if (batch_mode == BATCH_EXECUTE || block_given)
533
608
  return INT2FIX(changes);
534
609
  else
535
610
  return results;
@@ -537,7 +612,7 @@ static inline VALUE batch_run_array(query_ctx *ctx, enum batch_mode mode) {
537
612
 
538
613
  struct batch_execute_each_ctx {
539
614
  query_ctx *ctx;
540
- enum batch_mode mode;
615
+ enum batch_mode batch_mode;
541
616
  int block_given;
542
617
  VALUE results;
543
618
  int changes;
@@ -549,12 +624,13 @@ static VALUE batch_run_each_iter(RB_BLOCK_CALL_FUNC_ARGLIST(yield_value, vctx))
549
624
 
550
625
  sqlite3_reset(each_ctx->ctx->stmt);
551
626
  sqlite3_clear_bindings(each_ctx->ctx->stmt);
627
+ Database_issue_query(each_ctx->ctx->db, each_ctx->ctx->sql);
552
628
  bind_all_parameters_from_object(each_ctx->ctx->stmt, yield_value);
553
629
 
554
- batch_iterate(each_ctx->ctx, each_ctx->mode, &rows);
630
+ batch_iterate(each_ctx->ctx, each_ctx->batch_mode, &rows);
555
631
  each_ctx->changes += sqlite3_changes(each_ctx->ctx->sqlite3_db);
556
632
 
557
- if (each_ctx->mode != BATCH_EXECUTE) {
633
+ if (each_ctx->batch_mode != BATCH_EXECUTE) {
558
634
  if (each_ctx->block_given)
559
635
  rb_yield(rows);
560
636
  else
@@ -565,26 +641,26 @@ static VALUE batch_run_each_iter(RB_BLOCK_CALL_FUNC_ARGLIST(yield_value, vctx))
565
641
  return Qnil;
566
642
  }
567
643
 
568
- static inline VALUE batch_run_each(query_ctx *ctx, enum batch_mode mode) {
644
+ static inline VALUE batch_run_each(query_ctx *ctx, enum batch_mode batch_mode) {
569
645
  struct batch_execute_each_ctx each_ctx = {
570
646
  .ctx = ctx,
571
- .mode = mode,
647
+ .batch_mode = batch_mode,
572
648
  .block_given = rb_block_given_p(),
573
- .results = ((mode != BATCH_EXECUTE) && !rb_block_given_p() ? rb_ary_new() : Qnil),
649
+ .results = ((batch_mode != BATCH_EXECUTE) && !rb_block_given_p() ? rb_ary_new() : Qnil),
574
650
  .changes = 0
575
651
  };
576
652
  rb_block_call(ctx->params, ID_each, 0, 0, batch_run_each_iter, (VALUE)&each_ctx);
577
653
 
578
- if (mode == BATCH_EXECUTE || each_ctx.block_given)
654
+ if (batch_mode == BATCH_EXECUTE || each_ctx.block_given)
579
655
  return INT2FIX(each_ctx.changes);
580
656
  else
581
657
  return each_ctx.results;
582
658
  }
583
659
 
584
- static inline VALUE batch_run_proc(query_ctx *ctx, enum batch_mode mode) {
660
+ static inline VALUE batch_run_proc(query_ctx *ctx, enum batch_mode batch_mode) {
585
661
  VALUE params = Qnil;
586
662
  int block_given = rb_block_given_p();
587
- VALUE results = (mode != BATCH_EXECUTE) && !block_given ? rb_ary_new() : Qnil;
663
+ VALUE results = (batch_mode != BATCH_EXECUTE) && !block_given ? rb_ary_new() : Qnil;
588
664
  VALUE rows = Qnil;
589
665
  int changes = 0;
590
666
 
@@ -594,12 +670,13 @@ static inline VALUE batch_run_proc(query_ctx *ctx, enum batch_mode mode) {
594
670
 
595
671
  sqlite3_reset(ctx->stmt);
596
672
  sqlite3_clear_bindings(ctx->stmt);
673
+ Database_issue_query(ctx->db, ctx->sql);
597
674
  bind_all_parameters_from_object(ctx->stmt, params);
598
675
 
599
- batch_iterate(ctx, mode, &rows);
676
+ batch_iterate(ctx, batch_mode, &rows);
600
677
  changes += sqlite3_changes(ctx->sqlite3_db);
601
678
 
602
- if (mode != BATCH_EXECUTE) {
679
+ if (batch_mode != BATCH_EXECUTE) {
603
680
  if (block_given)
604
681
  rb_yield(rows);
605
682
  else
@@ -611,21 +688,21 @@ static inline VALUE batch_run_proc(query_ctx *ctx, enum batch_mode mode) {
611
688
  RB_GC_GUARD(results);
612
689
  RB_GC_GUARD(params);
613
690
 
614
- if (mode == BATCH_EXECUTE || block_given)
691
+ if (batch_mode == BATCH_EXECUTE || block_given)
615
692
  return INT2FIX(changes);
616
693
  else
617
694
  return results;
618
695
  }
619
696
 
620
- static inline VALUE batch_run(query_ctx *ctx, enum batch_mode mode) {
697
+ static inline VALUE batch_run(query_ctx *ctx, enum batch_mode batch_mode) {
621
698
  if (TYPE(ctx->params) == T_ARRAY)
622
- return batch_run_array(ctx, mode);
699
+ return batch_run_array(ctx, batch_mode);
623
700
 
624
701
  if (rb_respond_to(ctx->params, ID_each))
625
- return batch_run_each(ctx, mode);
702
+ return batch_run_each(ctx, batch_mode);
626
703
 
627
704
  if (rb_respond_to(ctx->params, ID_call))
628
- return batch_run_proc(ctx, mode);
705
+ return batch_run_proc(ctx, batch_mode);
629
706
 
630
707
  rb_raise(cParameterError, "Invalid parameter source supplied to #batch_execute");
631
708
  }
@@ -635,15 +712,24 @@ VALUE safe_batch_execute(query_ctx *ctx) {
635
712
  }
636
713
 
637
714
  VALUE safe_batch_query(query_ctx *ctx) {
638
- return batch_run(ctx, BATCH_QUERY_HASH);
715
+ switch (ctx->query_mode) {
716
+ case QUERY_HASH:
717
+ return batch_run(ctx, BATCH_QUERY_HASH);
718
+ case QUERY_ARGV:
719
+ return batch_run(ctx, BATCH_QUERY_ARGV);
720
+ case QUERY_ARY:
721
+ return batch_run(ctx, BATCH_QUERY_ARY);
722
+ default:
723
+ rb_raise(cError, "Invalid query mode (safe_batch_query)");
724
+ }
639
725
  }
640
726
 
641
727
  VALUE safe_batch_query_ary(query_ctx *ctx) {
642
728
  return batch_run(ctx, BATCH_QUERY_ARY);
643
729
  }
644
730
 
645
- VALUE safe_batch_query_single_column(query_ctx *ctx) {
646
- return batch_run(ctx, BATCH_QUERY_SINGLE_COLUMN);
731
+ VALUE safe_batch_query_argv(query_ctx *ctx) {
732
+ return batch_run(ctx, BATCH_QUERY_ARGV);
647
733
  }
648
734
 
649
735
  VALUE safe_query_columns(query_ctx *ctx) {