SQLite

Check-in [ff1f4e7447]
Login

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

Overview
Comment:Internationalize the TRIM functions. Ticket #2323. (CVS 3883)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ff1f4e744728c8f55afae265246797b30fe98fb0
User & Date: drh 2007-04-27 21:59:53.000
Context
2007-04-27
22:02
Break interior-node and leaf-node readers apart in loadSegment(). Previously, the code looped until the block was a leaf node as indicated by a leading NUL. Now the code loops until it finds a block in the range of leaf nodes for this segment, then reads it using LeavesReader. This will make it easier to traverse a range of leaves when doing a prefix search. (CVS 3884) (check-in: 9466367d65 user: shess tags: trunk)
21:59
Internationalize the TRIM functions. Ticket #2323. (CVS 3883) (check-in: ff1f4e7447 user: drh tags: trunk)
21:24
Lift code to traverse interior nodes out of loadSegment(). Refactoring towards prefix searching. (CVS 3882) (check-in: 25935db738 user: shess tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/func.c.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.142 2007/04/27 17:16:20 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
/* #include <math.h> */
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.143 2007/04/27 21:59:53 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
/* #include <math.h> */
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"
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
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const unsigned char *zIn;         /* Input string */
  const unsigned char *zCharSet;    /* Set of characters to trim */
  int nIn;                          /* Number of bytes in input */
  int flags;
  int i;



  unsigned char cFirst, cNext;
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
    return;
  }
  nIn = sqlite3_value_bytes(argv[0]);
  zIn = sqlite3_value_text(argv[0]);
  if( zIn==0 ) return;
  if( argc==1 ){
    static const unsigned char zSpace[] = " ";




    zCharSet = zSpace;
  }else if( (zCharSet = sqlite3_value_text(argv[1]))==0 ){
    return;




  }


  cFirst = zCharSet[0];










  if( cFirst ){
    flags = (int)sqlite3_user_data(context);
    if( flags & 1 ){
      for(; nIn>0; nIn--, zIn++){
        if( cFirst==zIn[0] ) continue;
        for(i=1; zCharSet[i] && zCharSet[i]!=zIn[0]; i++){}

        if( zCharSet[i]==0 ) break;
      }



    }

    if( flags & 2 ){
      for(; nIn>0; nIn--){
        cNext = zIn[nIn-1];
        if( cFirst==cNext ) continue;
        for(i=1; zCharSet[i] && zCharSet[i]!=cNext; i++){}



        if( zCharSet[i]==0 ) break;

      }
    }



  }
  sqlite3_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT);
}

#ifdef SQLITE_SOUNDEX
/*
** Compute the soundex encoding of a word.







|
|
>
>
>
|







|
>
>
>
>
|


>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
|


|
|
|
>
|
|
>
>
>
|
>

|
|
<
|
>
>
>
|
>


>
>
>







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
814
815
816
817
818
819
820
821
822
823
824
825
826
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const unsigned char *zIn;         /* Input string */
  const unsigned char *zCharSet;    /* Set of characters to trim */
  int nIn;                          /* Number of bytes in input */
  int flags;                        /* 1: trimleft  2: trimright  3: trim */
  int i;                            /* Loop counter */
  unsigned char *aLen;              /* Length of each character in zCharSet */
  const unsigned char **azChar;     /* Individual characters in zCharSet */
  int nChar;                        /* Number of characters in zCharSet */

  if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
    return;
  }
  nIn = sqlite3_value_bytes(argv[0]);
  zIn = sqlite3_value_text(argv[0]);
  if( zIn==0 ) return;
  if( argc==1 ){
    static const unsigned char lenOne[] = { 1 };
    static const char *azOne[] = { " " };
    nChar = 1;
    aLen = (unsigned char*)lenOne;
    azChar = (const unsigned char**)azOne;
    zCharSet = 0;
  }else if( (zCharSet = sqlite3_value_text(argv[1]))==0 ){
    return;
  }else{
    const unsigned char *z;
    for(z=zCharSet, nChar=0; *z; nChar++){
      sqliteNextChar(z);
    }
    if( nChar>0 ){
      azChar = sqlite3_malloc( nChar*(sizeof(char*)+1) );
      if( azChar==0 ){
        return;
      }
      aLen = (unsigned char*)&azChar[nChar];
      for(z=zCharSet, nChar=0; *z; nChar++){
        azChar[nChar] = z;
        sqliteNextChar(z);
        aLen[nChar] = z - azChar[nChar];
      }
    }
  }
  if( nChar>0 ){
    flags = (int)sqlite3_user_data(context);
    if( flags & 1 ){
      while( nIn>0 ){
        int len;
        for(i=0; i<nChar; i++){
          len = aLen[i];
          if( memcmp(zIn, azChar[i], len)==0 ) break;
        }
        if( i>=nChar ) break;
        zIn += len;
        nIn -= len;
      }
    }
    if( flags & 2 ){
      while( nIn>0 ){
        int len;

        for(i=0; i<nChar; i++){
          len = aLen[i];
          if( len<=nIn && memcmp(&zIn[nIn-len],azChar[i],len)==0 ) break;
        }
        if( i>=nChar ) break;
        nIn -= len;
      }
    }
    if( zCharSet ){
      sqlite3_free(azChar);
    }
  }
  sqlite3_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT);
}

#ifdef SQLITE_SOUNDEX
/*
** Compute the soundex encoding of a word.
Changes to test/func.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2001 September 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing built-in functions.
#
# $Id: func.test,v 1.61 2007/04/27 01:18:03 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Create a table to work with.
#
do_test func-0.0 {













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2001 September 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing built-in functions.
#
# $Id: func.test,v 1.62 2007/04/27 21:59:53 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Create a table to work with.
#
do_test func-0.0 {
817
818
819
820
821
822
823










824
825
826
827
828
829
830
831
832
833
834
} {{  hi  zzzy}}
do_test func-22.12 {
  execsql {SELECT rtrim('xyxzy  hi  zzzy','xyz');}
} {{xyxzy  hi  }}
do_test func-22.13 {
  execsql {SELECT trim('  hi  ','');}
} {{  hi  }}










do_test func-22.20 {
  execsql {SELECT typeof(trim(NULL));}
} {null}
do_test func-22.21 {
  execsql {SELECT typeof(trim(NULL,'xyz'));}
} {null}
do_test func-22.22 {
  execsql {SELECT typeof(trim('hello',NULL));}
} {null}

finish_test







>
>
>
>
>
>
>
>
>
>











817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
} {{  hi  zzzy}}
do_test func-22.12 {
  execsql {SELECT rtrim('xyxzy  hi  zzzy','xyz');}
} {{xyxzy  hi  }}
do_test func-22.13 {
  execsql {SELECT trim('  hi  ','');}
} {{  hi  }}
do_test func-22.14 {
  execsql {SELECT hex(trim(x'c280e1bfbff7bfbfbf6869',x'6162e1bfbfc280'))}
} {F7BFBFBF6869}
do_test func-22.15 {
  execsql {SELECT hex(trim(x'6869c280e1bfbff7bfbfbf61',
                           x'6162e1bfbfc280f7bfbfbf'))}
} {6869}
do_test func-22.16 {
  execsql {SELECT hex(trim(x'ceb1ceb2ceb3',x'ceb1'));}
} {CEB2CEB3}
do_test func-22.20 {
  execsql {SELECT typeof(trim(NULL));}
} {null}
do_test func-22.21 {
  execsql {SELECT typeof(trim(NULL,'xyz'));}
} {null}
do_test func-22.22 {
  execsql {SELECT typeof(trim('hello',NULL));}
} {null}

finish_test