/ Check-in [ff1f4e74]
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 | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ff1f4e744728c8f55afae265246797b30fe98fb0
User & Date: drh 2007-04-27 21:59:53
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: 9466367d user: shess tags: trunk
21:59
Internationalize the TRIM functions. Ticket #2323. (CVS 3883) check-in: ff1f4e74 user: drh tags: trunk
21:24
Lift code to traverse interior nodes out of loadSegment(). Refactoring towards prefix searching. (CVS 3882) check-in: 25935db7 user: shess tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/func.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
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
** 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"
................................................................................
  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.







|







 







|
|
|
>
>
>







|
>
>
>
>
|


>
>
>
>
|
<
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>


<
<
<
<
>
>
>
>
>
|
>
>
>
|
>

<
<
<
<
<
>
>
>
>
>
|
>
>
|
>
>
>
>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
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
** 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"
................................................................................
  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.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
817
818
819
820
821
822
823










824
825
826
827
828
829
830
831
832
833
834
#    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 {
................................................................................
} {{  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







|







 







>
>
>
>
>
>
>
>
>
>











7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
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
#    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 {
................................................................................
} {{  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