@@ -213,8 +213,9 @@ fn parameters() {
213
213
} ) ;
214
214
}
215
215
216
+ // Use case 1: ARRAY_CONTAINS => bad index (because of partial match)
216
217
#[ test]
217
- fn guillaume ( ) {
218
+ fn use_case_1 ( ) {
218
219
utils:: with_db ( |db| {
219
220
assert ! ( db
220
221
. create_index(
@@ -270,3 +271,228 @@ fn guillaume() {
270
271
assert_eq ! ( query. execute( ) . unwrap( ) . count( ) , 1 ) ;
271
272
} ) ;
272
273
}
274
+
275
+ // Use case 2: IN ($truc) + set_parameters => no result
276
+ #[ test]
277
+ fn use_case_2 ( ) {
278
+ utils:: with_db ( |db| {
279
+ assert ! ( db
280
+ . create_index(
281
+ "good_index" ,
282
+ & ValueIndexConfiguration :: new(
283
+ QueryLanguage :: JSON ,
284
+ r#"[[".type"],[".session_id"]]"#
285
+ ) ,
286
+ )
287
+ . unwrap( ) ) ;
288
+
289
+ assert ! ( db
290
+ . create_index(
291
+ "bad_index" ,
292
+ & ValueIndexConfiguration :: new( QueryLanguage :: JSON , r#"[[".type"]]"# ) ,
293
+ )
294
+ . unwrap( ) ) ;
295
+
296
+ let mut doc = Document :: new_with_id ( "id1" ) ;
297
+ let mut props = doc. mutable_properties ( ) ;
298
+ props. at ( "type" ) . put_string ( "HardcodedType" ) ;
299
+ props. at ( "session_id" ) . put_string ( "session1" ) ;
300
+ db. save_document_with_concurency_control ( & mut doc, ConcurrencyControl :: FailOnConflict )
301
+ . expect ( "save" ) ;
302
+
303
+ let query = Query :: new (
304
+ db,
305
+ QueryLanguage :: N1QL ,
306
+ "SELECT _.* FROM _ \
307
+ WHERE _.type = 'HardcodedType' \
308
+ AND _.session_id IN ($sessionIds)",
309
+ )
310
+ . expect ( "create query" ) ;
311
+
312
+ let mut params = MutableDict :: new ( ) ;
313
+ let mut session_ids = MutableArray :: new ( ) ;
314
+ session_ids. append ( ) . put_string ( "session1" ) ;
315
+ session_ids. append ( ) . put_string ( "session2" ) ;
316
+ params. at ( "sessionIds" ) . put_value ( & session_ids) ;
317
+ query. set_parameters ( & params) ;
318
+
319
+ let params = query. parameters ( ) ;
320
+ assert_eq ! (
321
+ params. get( "sessionIds" ) . as_array( ) . get( 0 ) . as_string( ) ,
322
+ Some ( "session1" )
323
+ ) ;
324
+ assert_eq ! (
325
+ params. get( "sessionIds" ) . as_array( ) . get( 1 ) . as_string( ) ,
326
+ Some ( "session2" )
327
+ ) ;
328
+
329
+ println ! ( "Explain: {:?}" , query. explain( ) ) ;
330
+ assert_eq ! ( query. execute( ) . unwrap( ) . count( ) , 1 ) ;
331
+ } ) ;
332
+ }
333
+
334
+ // Use case 3: IN + hardcoded values => result + good index, but sql injection
335
+ #[ test]
336
+ fn use_case_3 ( ) {
337
+ utils:: with_db ( |db| {
338
+ assert ! ( db
339
+ . create_index(
340
+ "good_index" ,
341
+ & ValueIndexConfiguration :: new(
342
+ QueryLanguage :: JSON ,
343
+ r#"[[".type"],[".session_id"]]"#
344
+ ) ,
345
+ )
346
+ . unwrap( ) ) ;
347
+
348
+ assert ! ( db
349
+ . create_index(
350
+ "bad_index" ,
351
+ & ValueIndexConfiguration :: new( QueryLanguage :: JSON , r#"[[".type"]]"# ) ,
352
+ )
353
+ . unwrap( ) ) ;
354
+
355
+ let mut doc = Document :: new_with_id ( "id1" ) ;
356
+ let mut props = doc. mutable_properties ( ) ;
357
+ props. at ( "type" ) . put_string ( "HardcodedType" ) ;
358
+ props. at ( "session_id" ) . put_string ( "session1" ) ;
359
+ db. save_document_with_concurency_control ( & mut doc, ConcurrencyControl :: FailOnConflict )
360
+ . expect ( "save" ) ;
361
+
362
+ let query = Query :: new (
363
+ db,
364
+ QueryLanguage :: N1QL ,
365
+ "SELECT _.* FROM _ \
366
+ WHERE _.type = 'HardcodedType' \
367
+ AND _.session_id in ('session1', 'session2')",
368
+ )
369
+ . expect ( "create query" ) ;
370
+
371
+ println ! ( "Explain: {:?}" , query. explain( ) ) ;
372
+ assert_eq ! ( query. execute( ) . unwrap( ) . count( ) , 1 ) ;
373
+ } ) ;
374
+ }
375
+
376
+ // Use case 4: IN [$truc] + set_parameters => n1ql error
377
+ #[ test]
378
+ fn use_case_4 ( ) {
379
+ utils:: with_db ( |db| {
380
+ assert ! ( db
381
+ . create_index(
382
+ "good_index" ,
383
+ & ValueIndexConfiguration :: new(
384
+ QueryLanguage :: JSON ,
385
+ r#"[[".type"],[".session_id"]]"#
386
+ ) ,
387
+ )
388
+ . unwrap( ) ) ;
389
+
390
+ assert ! ( db
391
+ . create_index(
392
+ "bad_index" ,
393
+ & ValueIndexConfiguration :: new( QueryLanguage :: JSON , r#"[[".type"]]"# ) ,
394
+ )
395
+ . unwrap( ) ) ;
396
+
397
+ let mut doc = Document :: new_with_id ( "id1" ) ;
398
+ let mut props = doc. mutable_properties ( ) ;
399
+ props. at ( "type" ) . put_string ( "HardcodedType" ) ;
400
+ props. at ( "session_id" ) . put_string ( "session1" ) ;
401
+ db. save_document_with_concurency_control ( & mut doc, ConcurrencyControl :: FailOnConflict )
402
+ . expect ( "save" ) ;
403
+
404
+ let query = Query :: new (
405
+ db,
406
+ QueryLanguage :: N1QL ,
407
+ "SELECT _.* FROM _ \
408
+ WHERE _.type = 'HardcodedType' \
409
+ AND _.session_id IN [$sessionIds]",
410
+ )
411
+ . expect ( "create query" ) ;
412
+
413
+ let mut params = MutableDict :: new ( ) ;
414
+ let mut session_ids = MutableArray :: new ( ) ;
415
+ session_ids. append ( ) . put_string ( "session1" ) ;
416
+ session_ids. append ( ) . put_string ( "session2" ) ;
417
+ params. at ( "sessionIds" ) . put_value ( & session_ids) ;
418
+ query. set_parameters ( & params) ;
419
+
420
+ let params = query. parameters ( ) ;
421
+ assert_eq ! (
422
+ params. get( "sessionIds" ) . as_array( ) . get( 0 ) . as_string( ) ,
423
+ Some ( "session1" )
424
+ ) ;
425
+ assert_eq ! (
426
+ params. get( "sessionIds" ) . as_array( ) . get( 1 ) . as_string( ) ,
427
+ Some ( "session2" )
428
+ ) ;
429
+
430
+ println ! ( "Explain: {:?}" , query. explain( ) ) ;
431
+ assert_eq ! ( query. execute( ) . unwrap( ) . count( ) , 1 ) ;
432
+ } ) ;
433
+ }
434
+
435
+ // Use case 5: IN [$truc] + set_parameters => n1ql error
436
+ #[ test]
437
+ fn use_case_5 ( ) {
438
+ utils:: with_db ( |db| {
439
+ assert ! ( db
440
+ . create_index(
441
+ "good_index" ,
442
+ & ValueIndexConfiguration :: new(
443
+ QueryLanguage :: JSON ,
444
+ r#"[[".type"],[".session_id"]]"#
445
+ ) ,
446
+ )
447
+ . unwrap( ) ) ;
448
+
449
+ assert ! ( db
450
+ . create_index(
451
+ "bad_index" ,
452
+ & ValueIndexConfiguration :: new( QueryLanguage :: JSON , r#"[[".type"]]"# ) ,
453
+ )
454
+ . unwrap( ) ) ;
455
+
456
+ let mut doc = Document :: new_with_id ( "id1" ) ;
457
+ let mut props = doc. mutable_properties ( ) ;
458
+ props. at ( "type" ) . put_string ( "HardcodedType" ) ;
459
+ props. at ( "session_id" ) . put_string ( "session1" ) ;
460
+ db. save_document_with_concurency_control ( & mut doc, ConcurrencyControl :: FailOnConflict )
461
+ . expect ( "save" ) ;
462
+
463
+ let query = Query :: new (
464
+ db,
465
+ QueryLanguage :: N1QL ,
466
+ "SELECT _.* FROM _ \
467
+ WHERE _.type = 'HardcodedType' \
468
+ AND _.session_id IN $sessionIds",
469
+ )
470
+ . expect ( "create query" ) ;
471
+
472
+ let mut params = MutableDict :: new ( ) ;
473
+ let mut session_ids = MutableArray :: new ( ) ;
474
+ session_ids. append ( ) . put_string ( "session1" ) ;
475
+ session_ids. append ( ) . put_string ( "session2" ) ;
476
+ params. at ( "sessionIds" ) . put_value ( & session_ids) ;
477
+ query. set_parameters ( & params) ;
478
+
479
+ let params = query. parameters ( ) ;
480
+ assert_eq ! (
481
+ params. get( "sessionIds" ) . as_array( ) . get( 0 ) . as_string( ) ,
482
+ Some ( "session1" )
483
+ ) ;
484
+ assert_eq ! (
485
+ params. get( "sessionIds" ) . as_array( ) . get( 1 ) . as_string( ) ,
486
+ Some ( "session2" )
487
+ ) ;
488
+
489
+ println ! ( "Explain: {:?}" , query. explain( ) ) ;
490
+ assert_eq ! ( query. execute( ) . unwrap( ) . count( ) , 1 ) ;
491
+ } ) ;
492
+ }
493
+
494
+ // Use case 1: ARRAY_CONTAINS => bad index (because of partial match)
495
+ // Use case 2: IN ($truc) + set_parameters => no result
496
+ // Use case 3: IN + hardcoded values => result + good index, but sql injection
497
+ // Use case 4: IN [$truc] + set_parameters => n1ql error
498
+ // Use case 5: IN $truc + set_parameters => n1ql error
0 commit comments