SQLite

Check-in [4a807d48ea]
Login

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

Overview
Comment:Make the 3rd parameter of the SUBSTR() function optional. Ticket #2579. (CVS 4486)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 4a807d48ea9923c1e3df4a5ad503710e62ae29f8
User & Date: drh 2007-10-12 19:11:55.000
Context
2007-10-12
19:35
Convert a K&R style function to ANSI style. Ticket #2548. (CVS 4487) (check-in: e1b2e7c24c user: drh tags: trunk)
19:11
Make the 3rd parameter of the SUBSTR() function optional. Ticket #2579. (CVS 4486) (check-in: 4a807d48ea user: drh tags: trunk)
18:36
Add an explicit type conversion in an AWK script to work around bugs in cygwin. Ticket #2713. (CVS 4485) (check-in: 043cee2fd9 user: drh 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.174 2007/09/03 11:04:22 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.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.175 2007/10/12 19:11:55 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"

165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187

188



189
190
191
192
193
194
195
){
  const unsigned char *z;
  const unsigned char *z2;
  int len;
  int p0type;
  i64 p1, p2;

  assert( argc==3 );
  p0type = sqlite3_value_type(argv[0]);
  if( p0type==SQLITE_BLOB ){
    len = sqlite3_value_bytes(argv[0]);
    z = sqlite3_value_blob(argv[0]);
    if( z==0 ) return;
    assert( len==sqlite3_value_bytes(argv[0]) );
  }else{
    z = sqlite3_value_text(argv[0]);
    if( z==0 ) return;
    len = 0;
    for(z2=z; *z2; len++){
      SQLITE_SKIP_UTF8(z2);
    }
  }
  p1 = sqlite3_value_int(argv[1]);

  p2 = sqlite3_value_int(argv[2]);



  if( p1<0 ){
    p1 += len;
    if( p1<0 ){
      p2 += p1;
      p1 = 0;
    }
  }else if( p1>0 ){







|















>
|
>
>
>







165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
){
  const unsigned char *z;
  const unsigned char *z2;
  int len;
  int p0type;
  i64 p1, p2;

  assert( argc==3 || argc==2 );
  p0type = sqlite3_value_type(argv[0]);
  if( p0type==SQLITE_BLOB ){
    len = sqlite3_value_bytes(argv[0]);
    z = sqlite3_value_blob(argv[0]);
    if( z==0 ) return;
    assert( len==sqlite3_value_bytes(argv[0]) );
  }else{
    z = sqlite3_value_text(argv[0]);
    if( z==0 ) return;
    len = 0;
    for(z2=z; *z2; len++){
      SQLITE_SKIP_UTF8(z2);
    }
  }
  p1 = sqlite3_value_int(argv[1]);
  if( argc==3 ){
    p2 = sqlite3_value_int(argv[2]);
  }else{
    p2 = SQLITE_MAX_LENGTH;
  }
  if( p1<0 ){
    p1 += len;
    if( p1<0 ){
      p2 += p1;
      p1 = 0;
    }
  }else if( p1>0 ){
1325
1326
1327
1328
1329
1330
1331

1332
1333
1334
1335
1336
1337
1338
  } aFuncs[] = {
    { "min",               -1, 0, SQLITE_UTF8,    1, minmaxFunc },
    { "min",                0, 0, SQLITE_UTF8,    1, 0          },
    { "max",               -1, 1, SQLITE_UTF8,    1, minmaxFunc },
    { "max",                0, 1, SQLITE_UTF8,    1, 0          },
    { "typeof",             1, 0, SQLITE_UTF8,    0, typeofFunc },
    { "length",             1, 0, SQLITE_UTF8,    0, lengthFunc },

    { "substr",             3, 0, SQLITE_UTF8,    0, substrFunc },
    { "abs",                1, 0, SQLITE_UTF8,    0, absFunc    },
    { "round",              1, 0, SQLITE_UTF8,    0, roundFunc  },
    { "round",              2, 0, SQLITE_UTF8,    0, roundFunc  },
    { "upper",              1, 0, SQLITE_UTF8,    0, upperFunc  },
    { "lower",              1, 0, SQLITE_UTF8,    0, lowerFunc  },
    { "coalesce",          -1, 0, SQLITE_UTF8,    0, ifnullFunc },







>







1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
  } aFuncs[] = {
    { "min",               -1, 0, SQLITE_UTF8,    1, minmaxFunc },
    { "min",                0, 0, SQLITE_UTF8,    1, 0          },
    { "max",               -1, 1, SQLITE_UTF8,    1, minmaxFunc },
    { "max",                0, 1, SQLITE_UTF8,    1, 0          },
    { "typeof",             1, 0, SQLITE_UTF8,    0, typeofFunc },
    { "length",             1, 0, SQLITE_UTF8,    0, lengthFunc },
    { "substr",             2, 0, SQLITE_UTF8,    0, substrFunc },
    { "substr",             3, 0, SQLITE_UTF8,    0, substrFunc },
    { "abs",                1, 0, SQLITE_UTF8,    0, absFunc    },
    { "round",              1, 0, SQLITE_UTF8,    0, roundFunc  },
    { "round",              2, 0, SQLITE_UTF8,    0, roundFunc  },
    { "upper",              1, 0, SQLITE_UTF8,    0, upperFunc  },
    { "lower",              1, 0, SQLITE_UTF8,    0, lowerFunc  },
    { "coalesce",          -1, 0, SQLITE_UTF8,    0, ifnullFunc },
Changes to test/substr.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2007 May 14
#
# 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 the built-in SUBSTR() functions.
#
# $Id: substr.test,v 1.2 2007/09/12 17:01:45 danielk1977 Exp $

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

ifcapable !tclvar {
  finish_test
  return













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2007 May 14
#
# 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 the built-in SUBSTR() functions.
#
# $Id: substr.test,v 1.3 2007/10/12 19:11:55 drh Exp $

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

ifcapable !tclvar {
  finish_test
  return
101
102
103
104
105
106
107






















108
subblob-test 4.1 61E188B462E28D8563E3919663 1 1 61
subblob-test 4.2 61E188B462E28D8563E3919663 2 1 E1
subblob-test 4.3 61E188B462E28D8563E3919663 1 2 61E1
subblob-test 4.4 61E188B462E28D8563E3919663 -2 1 96
subblob-test 4.5 61E188B462E28D8563E3919663 -5 4 63E39196
subblob-test 4.6 61E188B462E28D8563E3919663 -100 98 61E188B462E28D8563E391 























finish_test







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

101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
subblob-test 4.1 61E188B462E28D8563E3919663 1 1 61
subblob-test 4.2 61E188B462E28D8563E3919663 2 1 E1
subblob-test 4.3 61E188B462E28D8563E3919663 1 2 61E1
subblob-test 4.4 61E188B462E28D8563E3919663 -2 1 96
subblob-test 4.5 61E188B462E28D8563E3919663 -5 4 63E39196
subblob-test 4.6 61E188B462E28D8563E3919663 -100 98 61E188B462E28D8563E391 

# Two-argument SUBSTR
#
proc substr-2-test {id string idx result} {
  db eval {
    DELETE FROM t1;
    INSERT INTO t1(t) VALUES($string)
  }
  do_test substr-$id.1 [subst {
    execsql {
      SELECT substr(t, $idx) FROM t1
    }
  }] [list $result]
  set qstr '[string map {' ''} $string]'
  do_test substr-$id.2 [subst {
    execsql {
      SELECT substr($qstr, $idx)
    }
  }] [list $result]
}
substr-2-test 5.1 abcdefghijklmnop 5 efghijklmnop
substr-2-test 5.2 abcdef -5 bcdef

finish_test
Changes to www/lang.tcl.
1
2
3
4
5
6
7
8
9
10
11
#
# Run this Tcl script to generate the lang-*.html files.
#
set rcsid {$Id: lang.tcl,v 1.136 2007/10/03 20:15:28 drh Exp $}
source common.tcl

if {[llength $argv]>0} {
  set outputdir [lindex $argv 0]
} else {
  set outputdir ""
}



|







1
2
3
4
5
6
7
8
9
10
11
#
# Run this Tcl script to generate the lang-*.html files.
#
set rcsid {$Id: lang.tcl,v 1.137 2007/10/12 19:11:55 drh Exp $}
source common.tcl

if {[llength $argv]>0} {
  set outputdir [lindex $argv 0]
} else {
  set outputdir ""
}
1495
1496
1497
1498
1499
1500
1501
1502


1503
1504


1505
1506
1507
1508
1509
1510
1511
<tr>
<td valign="top" align="right">sqlite_version(*)</td>
<td valign="top">Return the version string for the SQLite library
that is running.  Example:  "2.8.0"</td>
</tr>

<tr>
<td valign="top" align="right">substr(<i>X</i>,<i>Y</i>,<i>Z</i>)</td>


<td valign="top">Return a substring of input string <i>X</i> that begins
with the <i>Y</i>-th character and which is <i>Z</i> characters long.


The left-most character of <i>X</i> is number 1.  If <i>Y</i> is negative
the the first character of the substring is found by counting from the
right rather than the left.  If <i>X</i> is string
then characters indices refer to actual UTF-8 characters.  If
<i>X</i> is a BLOB then the indices refer to bytes.</td>
</tr>








|
>
>


>
>







1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
<tr>
<td valign="top" align="right">sqlite_version(*)</td>
<td valign="top">Return the version string for the SQLite library
that is running.  Example:  "2.8.0"</td>
</tr>

<tr>
<td valign="top" align="right">
  substr(<i>X</i>,<i>Y</i>,<i>Z</i>)<br>
  substr(<i>X</i>,<i>Y</i>)</td>
<td valign="top">Return a substring of input string <i>X</i> that begins
with the <i>Y</i>-th character and which is <i>Z</i> characters long.
If <i>Z</i> is omitted then all character through the end of the string
are returned.
The left-most character of <i>X</i> is number 1.  If <i>Y</i> is negative
the the first character of the substring is found by counting from the
right rather than the left.  If <i>X</i> is string
then characters indices refer to actual UTF-8 characters.  If
<i>X</i> is a BLOB then the indices refer to bytes.</td>
</tr>