SQLite

Check-in [396f720f36]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add fts5 auxiliary function fts5_get_locale(). For querying the locale of a stored value.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 396f720f36a937145ac727c2750acfd26e4eda350b46d648d82a7e9985545a9f
User & Date: dan 2024-08-23 15:18:02.618
Context
2024-08-23
17:40
Fix a problem in the ext/fts5/extract_api_docs.tcl script. (check-in: 9a9d0f6301 user: dan tags: trunk)
15:18
Add fts5 auxiliary function fts5_get_locale(). For querying the locale of a stored value. (check-in: 396f720f36 user: dan tags: trunk)
2024-08-22
18:12
Enhance the generate_series() table-valued function such that it is able to recognize equality and inequality constraints on the "value" column and optimize its operating accordingly. (check-in: d50b784807 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to ext/fts5/fts5_aux.c.
741
742
743
744
745
746
747















































748
749
750
751
752
753
754
755
756
757
758

759
760
761
762
763
764
765
      );
    }
    sqlite3_result_double(pCtx, -1.0 * score);
  }else{
    sqlite3_result_error_code(pCtx, rc);
  }
}
















































int sqlite3Fts5AuxInit(fts5_api *pApi){
  struct Builtin {
    const char *zFunc;            /* Function name (nul-terminated) */
    void *pUserData;              /* User-data pointer */
    fts5_extension_function xFunc;/* Callback function */
    void (*xDestroy)(void*);      /* Destructor function */
  } aBuiltin [] = {
    { "snippet",   0, fts5SnippetFunction, 0 },
    { "highlight", 0, fts5HighlightFunction, 0 },
    { "bm25",      0, fts5Bm25Function,    0 },

  };
  int rc = SQLITE_OK;             /* Return code */
  int i;                          /* To iterate through builtin functions */

  for(i=0; rc==SQLITE_OK && i<ArraySize(aBuiltin); i++){
    rc = pApi->xCreateFunction(pApi,
        aBuiltin[i].zFunc,







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








|
|
|
>







741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
      );
    }
    sqlite3_result_double(pCtx, -1.0 * score);
  }else{
    sqlite3_result_error_code(pCtx, rc);
  }
}

/*
** Implementation of fts5_get_locale() function.
*/
static void fts5GetLocaleFunction(
  const Fts5ExtensionApi *pApi,   /* API offered by current FTS version */
  Fts5Context *pFts,              /* First arg to pass to pApi functions */
  sqlite3_context *pCtx,          /* Context for returning result/error */
  int nVal,                       /* Number of values in apVal[] array */
  sqlite3_value **apVal           /* Array of trailing arguments */
){
  int iCol = 0;
  int eType = 0;
  int rc = SQLITE_OK;
  const char *zLocale = 0;
  int nLocale = 0;

  /* xColumnLocale() must be available */
  assert( pApi->iVersion>=4 );

  if( nVal!=1 ){
    const char *z = "wrong number of arguments to function fts5_get_locale()";
    sqlite3_result_error(pCtx, z, -1);
    return;
  }

  eType = sqlite3_value_numeric_type(apVal[0]);
  if( eType!=SQLITE_INTEGER ){
    const char *z = "non-integer argument passed to function fts5_get_locale()";
    sqlite3_result_error(pCtx, z, -1);
    return;
  }

  iCol = sqlite3_value_int(apVal[0]);
  if( iCol<0 || iCol>=pApi->xColumnCount(pFts) ){
    sqlite3_result_error_code(pCtx, SQLITE_RANGE);
    return;
  }

  rc = pApi->xColumnLocale(pFts, iCol, &zLocale, &nLocale);
  if( rc!=SQLITE_OK ){
    sqlite3_result_error_code(pCtx, rc);
    return;
  }

  sqlite3_result_text(pCtx, zLocale, nLocale, SQLITE_TRANSIENT);
}

int sqlite3Fts5AuxInit(fts5_api *pApi){
  struct Builtin {
    const char *zFunc;            /* Function name (nul-terminated) */
    void *pUserData;              /* User-data pointer */
    fts5_extension_function xFunc;/* Callback function */
    void (*xDestroy)(void*);      /* Destructor function */
  } aBuiltin [] = {
    { "snippet",         0, fts5SnippetFunction,   0 },
    { "highlight",       0, fts5HighlightFunction, 0 },
    { "bm25",            0, fts5Bm25Function,      0 },
    { "fts5_get_locale", 0, fts5GetLocaleFunction, 0 },
  };
  int rc = SQLITE_OK;             /* Return code */
  int i;                          /* To iterate through builtin functions */

  for(i=0; rc==SQLITE_OK && i<ArraySize(aBuiltin); i++){
    rc = pApi->xCreateFunction(pApi,
        aBuiltin[i].zFunc,
Changes to ext/fts5/test/fts5faultI.test.
227
228
229
230
231
232
233
























234
235
236
237
  execsql {
    SELECT rowid FROM ft WHERE x MATCH 'one AND two AND three'
  }
} -test {
  faultsim_test_result {0 1}
}



























finish_test








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
  execsql {
    SELECT rowid FROM ft WHERE x MATCH 'one AND two AND three'
  }
} -test {
  faultsim_test_result {0 1}
}

#-------------------------------------------------------------------------
reset_db

do_execsql_test 10.0 {
  CREATE VIRTUAL TABLE ft USING fts5(x, locale=1);
  INSERT INTO ft VALUES(fts5_locale('hello', 'one two three i ii iii'));
  INSERT INTO ft VALUES('four five six iv v vi');
  INSERT INTO ft VALUES('eight nine ten viii ix x');
} {}

do_execsql_test 10.1 {
  SELECT fts5_get_locale(ft, 0) FROM ft WHERE x MATCH 'one AND two AND three'
} {hello}

faultsim_save_and_close
do_faultsim_test 10 -faults oom* -prep {
  faultsim_restore_and_reopen
} -body {
  execsql {
    SELECT fts5_get_locale(ft, 0) FROM ft WHERE x MATCH 'one AND two AND three'
  }
} -test {
  faultsim_test_result {0 hello}
}


finish_test

Changes to ext/fts5/test/fts5locale.test.
567
568
569
570
571
572
573



























































































574
575
576
#
reset_db
do_test 12.0 {
  list [catch {
    sqlite3_fts5_create_tokenizer -v2 -version 3 db tcl tcl_create
  } msg] $msg
} {1 {error in fts5_api.xCreateTokenizer_v2()}}




























































































finish_test








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
#
reset_db
do_test 12.0 {
  list [catch {
    sqlite3_fts5_create_tokenizer -v2 -version 3 db tcl tcl_create
  } msg] $msg
} {1 {error in fts5_api.xCreateTokenizer_v2()}}

#-------------------------------------------------------------------------
# Tests for auxiliary function fts5_get_locale().
#
reset_db

# Check that if the table does not support locale=1, fts5_get_locale()
# always returns NULL.
do_execsql_test 13.1.0 {
  CREATE VIRTUAL TABLE nolocale USING fts5(a, b);
  INSERT INTO nolocale VALUES('one two three', 'four five six');
  INSERT INTO nolocale VALUES('three two one', 'seven eight nine');
}
do_execsql_test 13.1.1 {
  SELECT fts5_get_locale(nolocale, 0) IS NULL FROM nolocale;
} {1 1}
do_execsql_test 13.1.2 {
  SELECT fts5_get_locale(nolocale, 1) IS NULL FROM nolocale('one + two');
} {1}
do_execsql_test 13.1.3 {
  SELECT fts5_get_locale(nolocale, 0) IS NULL FROM nolocale('one AND two');
} {1 1}
do_execsql_test 13.1.4 {
  SELECT 
      fts5_get_locale(nolocale, 1) IS NULL 
  FROM nolocale('three AND two') ORDER BY rank
} {1 1}
do_catchsql_test 13.1.5 {
  SELECT fts5_get_locale(nolocale, 2) IS NULL FROM nolocale('three AND two');
} {1 {column index out of range}}
do_catchsql_test 13.1.6 {
  SELECT fts5_get_locale(nolocale, -1) IS NULL FROM nolocale('three AND two');
} {1 {column index out of range}}
do_catchsql_test 13.1.7 {
  SELECT fts5_get_locale(nolocale) IS NULL FROM nolocale('three AND two');
} {1 {wrong number of arguments to function fts5_get_locale()}}
do_catchsql_test 13.1.8 {
  SELECT fts5_get_locale(nolocale, 0, 0) IS NULL FROM nolocale('three AND two');
} {1 {wrong number of arguments to function fts5_get_locale()}}
do_catchsql_test 13.1.9 {
  SELECT fts5_get_locale(nolocale, 'text') FROM nolocale('three AND two');
} {1 {non-integer argument passed to function fts5_get_locale()}}


# Check that if the table does support locale=1, fts5_get_locale()
# returns the locale of the identified row/column.
do_execsql_test 13.2.0 {
  CREATE VIRTUAL TABLE ft USING fts5(a, b, locale=1);
  INSERT INTO ft VALUES(
      fts5_locale('th_TH', 'one two three'), 'four five six seven'
  );
  INSERT INTO ft VALUES(
      'three two one', fts5_locale('en_AU', 'seven eight nine')
  );
}

do_execsql_test 13.2.1 {
  SELECT quote(fts5_get_locale(ft, 0)), quote(fts5_get_locale(ft, 1)) FROM ft
} { 'th_TH' NULL NULL 'en_AU' }
do_execsql_test 13.2.2 {
  SELECT 
    quote(fts5_get_locale(ft, 0)), quote(fts5_get_locale(ft, 1)) 
  FROM ft('one AND three')
} { 'th_TH' NULL NULL 'en_AU' }
do_execsql_test 13.2.3 {
  SELECT 
    quote(fts5_get_locale(ft, 0)), quote(fts5_get_locale(ft, 1)) 
  FROM ft('one AND three') ORDER BY rank
} { NULL 'en_AU' 'th_TH' NULL }
do_execsql_test 13.2.4 {
  SELECT 
    quote(fts5_get_locale(ft, 0)), quote(fts5_get_locale(ft, 1)) 
  FROM ft('one AND three') ORDER BY rowid
} { 'th_TH' NULL NULL 'en_AU' }

do_execsql_test 13.2.5 {
  SELECT 
    quote(fts5_get_locale(ft, '0')), quote(fts5_get_locale(ft, 1)) 
  FROM ft('one AND three') ORDER BY rowid
} { 'th_TH' NULL NULL 'en_AU' }

do_catchsql_test 13.2.6 {
  SELECT 
    quote(fts5_get_locale(ft, '0.0')), quote(fts5_get_locale(ft, 1)) 
  FROM ft('one AND three') ORDER BY rowid
} {1 {non-integer argument passed to function fts5_get_locale()}}
do_catchsql_test 13.2.7 {
  SELECT 
    quote(fts5_get_locale(ft, 0.0)), quote(fts5_get_locale(ft, 1)) 
  FROM ft('one AND three') ORDER BY rowid
} {1 {non-integer argument passed to function fts5_get_locale()}}

finish_test