/ Check-in [c9e3015f]
Login

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

Overview
Comment:A few more bugfixes. Test cases pass now. (CVS 1472)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:c9e3015faffb650d8dbf1f7f95a7057a36361bac
User & Date: danielk1977 2004-05-27 10:30:53
Context
2004-05-27
12:11
Alter the Tcl eval sub-command so that it supports blobs. (CVS 1473) check-in: b5d5f0ad user: danielk1977 tags: trunk
10:30
A few more bugfixes. Test cases pass now. (CVS 1472) check-in: c9e3015f user: danielk1977 tags: trunk
09:28
Various bugfixes. 68 Test cases still fail. (CVS 1471) check-in: 67a140cf user: danielk1977 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
..
38
39
40
41
42
43
44

45

46
47
48
49
50
51
52
...
103
104
105
106
107
108
109


110
111
112
113
114
115
116
117


118
119
120
121
122
123
124
125
** 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.60 2004/05/27 09:28:42 danielk1977 Exp $
*/
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include "sqliteInt.h"
#include "vdbeInt.h"
................................................................................
  int mask;    /* 0 for min() or 0xffffffff for max() */
  int iBest;

  if( argc==0 ) return;
  mask = (int)sqlite3_user_data(context);
  assert( mask==-1 || mask==0 );
  iBest = 0;

  for(i=1; i<argc; i++){

    if( (sqlite3MemCompare(argv[iBest], argv[i], 0)^mask)>=0 ){
      iBest = i;
    }
  }
  sqlite3_result_value(context, argv[iBest]);
}

................................................................................
/*
** Implementation of the abs() function
*/
static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  assert( argc==1 );
  switch( sqlite3_value_type(argv[0]) ){
    case SQLITE3_INTEGER: {


      sqlite3_result_int64(context, -sqlite3_value_int64(argv[0]));
      break;
    }
    case SQLITE3_NULL: {
      sqlite3_result_null(context);
      break;
    }
    default: {


      sqlite3_result_double(context, -sqlite3_value_double(argv[0]));
      break;
    }
  }
}

/*
** Implementation of the substr() function







|







 







>

>







 







>
>
|







>
>
|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
..
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
...
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
131
** 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.61 2004/05/27 10:30:53 danielk1977 Exp $
*/
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include "sqliteInt.h"
#include "vdbeInt.h"
................................................................................
  int mask;    /* 0 for min() or 0xffffffff for max() */
  int iBest;

  if( argc==0 ) return;
  mask = (int)sqlite3_user_data(context);
  assert( mask==-1 || mask==0 );
  iBest = 0;
  if( sqlite3_value_type(argv[0])==SQLITE3_NULL ) return;
  for(i=1; i<argc; i++){
    if( sqlite3_value_type(argv[i])==SQLITE3_NULL ) return;
    if( (sqlite3MemCompare(argv[iBest], argv[i], 0)^mask)>=0 ){
      iBest = i;
    }
  }
  sqlite3_result_value(context, argv[iBest]);
}

................................................................................
/*
** Implementation of the abs() function
*/
static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  assert( argc==1 );
  switch( sqlite3_value_type(argv[0]) ){
    case SQLITE3_INTEGER: {
      i64 iVal = sqlite3_value_int64(argv[0]);
      if( iVal<0 ) iVal = iVal * -1;
      sqlite3_result_int64(context, iVal);
      break;
    }
    case SQLITE3_NULL: {
      sqlite3_result_null(context);
      break;
    }
    default: {
      double rVal = sqlite3_value_double(argv[0]);
      if( rVal<0 ) rVal = rVal * -1.0;
      sqlite3_result_double(context, rVal);
      break;
    }
  }
}

/*
** Implementation of the substr() function

Changes to src/select.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
2115
2116
2117
2118
2119
2120
2121

2122
2123
2124
2125
2126
2127
2128
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.178 2004/05/26 16:54:44 drh Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.
................................................................................

  /* ORDER BY is ignored for some destinations.
  */
  switch( eDest ){
    case SRT_Union:
    case SRT_Except:
    case SRT_Discard:

      pOrderBy = 0;
      break;
    default:
      break;
  }

  /* At this point, we should have allocated all the cursors that we







|







 







>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.179 2004/05/27 10:30:53 danielk1977 Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.
................................................................................

  /* ORDER BY is ignored for some destinations.
  */
  switch( eDest ){
    case SRT_Union:
    case SRT_Except:
    case SRT_Discard:
    case SRT_Set:
      pOrderBy = 0;
      break;
    default:
      break;
  }

  /* At this point, we should have allocated all the cursors that we

Changes to src/test1.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
....
1581
1582
1583
1584
1585
1586
1587

1588
1589
1590
1591
1592
1593
1594
1595
1596


1597

1598
1599
1600
1601
1602
1603
1604
....
1623
1624
1625
1626
1627
1628
1629

1630
1631

1632
1633
1634
1635
1636
1637
1638
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.62 2004/05/27 09:28:43 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  sqlite3_stmt *pStmt;
  int col;
  const char *(*xFunc)(sqlite3_stmt*, int) = clientData;


  if( objc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", 
       Tcl_GetString(objv[0]), " STMT column", 0);
    return TCL_ERROR;
  }

  if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
  if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;


  Tcl_SetResult(interp, (char *)xFunc(pStmt, col), 0);

  return TCL_OK;
}

/*
** Usage: sqlite3_column_text STMT column
**
** Usage: sqlite3_column_decltype STMT column
................................................................................
    return TCL_ERROR;
  }

  if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
  if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;

  zName16 = xFunc(pStmt, col);

  pRet = Tcl_NewByteArrayObj(zName16, sqlite3utf16ByteLen(zName16, -1)+2);
  Tcl_SetObjResult(interp, pRet);


  return TCL_OK;
}

/*
** Usage: sqlite3_column_int STMT column
**







|







 







>









>
>
|
>







 







>
|
|
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
....
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
....
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.63 2004/05/27 10:31:10 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  sqlite3_stmt *pStmt;
  int col;
  const char *(*xFunc)(sqlite3_stmt*, int) = clientData;
  const char *zRet;

  if( objc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", 
       Tcl_GetString(objv[0]), " STMT column", 0);
    return TCL_ERROR;
  }

  if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
  if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
  zRet = xFunc(pStmt, col);
  if( zRet ){
    Tcl_SetResult(interp, (char *)zRet, 0);
  }
  return TCL_OK;
}

/*
** Usage: sqlite3_column_text STMT column
**
** Usage: sqlite3_column_decltype STMT column
................................................................................
    return TCL_ERROR;
  }

  if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
  if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;

  zName16 = xFunc(pStmt, col);
  if( zName16 ){
    pRet = Tcl_NewByteArrayObj(zName16, sqlite3utf16ByteLen(zName16, -1)+2);
    Tcl_SetObjResult(interp, pRet);
  }

  return TCL_OK;
}

/*
** Usage: sqlite3_column_int STMT column
**

Changes to src/vdbemem.c.

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
...
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
...
219
220
221
222
223
224
225
226
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
262
    pMem->flags &= ~(MEM_Ephem | MEM_Short | MEM_Static);
    pMem->flags |= MEM_Str | MEM_Dyn | MEM_Term;
  }else{
    /* Must be translating between UTF-16le and UTF-16be. */
    int i;
    u8 *pFrom, *pTo;
    sqlite3VdbeMemMakeWriteable(pMem);
    for(i=0, pFrom=pMem->z, pTo=&pMem->z[1]; i<pMem->n; i+=2, pFrom++, pTo++){
      u8 temp = *pFrom;
      *pFrom = *pTo;
      *pTo = temp;
    }
  }
  pMem->enc = desiredEnc;
  return SQLITE_OK;
................................................................................
    /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
    ** string representation of the value. Then, if the required encoding
    ** is UTF-16le or UTF-16be do a translation.
    ** 
    ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
    */
    u8 *z = pMem->zShort;
    if( fg & MEM_Real ){
      sqlite3_snprintf(NBFS, z, "%.15g", pMem->r);
    }else{
      assert( fg & MEM_Int );
      sqlite3_snprintf(NBFS, z, "%lld", pMem->i);
    }
    pMem->n = strlen(z);
    pMem->z = z;
................................................................................
      return SQLITE_NOMEM;
    }
    assert( pMem->z );
    sqlite3atoi64(pMem->z, &pMem->i);
  }else{
    pMem->i = 0;
  }
  releaseMem(pMem);
  pMem->flags = MEM_Int;
  pMem->type = SQLITE3_INTEGER;
  return SQLITE_OK;
}

/*
** Add MEM_Real to the set of representations for pMem.  Prior
** prior representations other than MEM_Null retained.  NULL is
** converted into 0.0.
*/
int sqlite3VdbeMemRealify(Mem *pMem){
  if( pMem->flags & MEM_Int ){


    pMem->r = pMem->i;
    pMem->flags |= MEM_Real;
  }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
    if( sqlite3VdbeChangeEncoding(pMem, TEXT_Utf8)
       || sqlite3VdbeMemNulTerminate(pMem) ){
      return SQLITE_NOMEM;
    }
    assert( pMem->z );
    pMem->r = sqlite3AtoF(pMem->z, 0);
    releaseMem(pMem);
    pMem->flags = MEM_Real;
    pMem->type = SQLITE3_FLOAT;
  }else{
    pMem->r = 0.0;
    pMem->flags = MEM_Real;
    pMem->type = SQLITE3_FLOAT;
  }

  return SQLITE_OK;
}

/*
** Delete any previous value and set the value stored in *pMem to NULL.
*/
void sqlite3VdbeMemSetNull(Mem *pMem){







|







 







|







 







<
|
<









|
>
>

<







<
<
<


<
<

>







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
...
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
...
219
220
221
222
223
224
225

226

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
    pMem->flags &= ~(MEM_Ephem | MEM_Short | MEM_Static);
    pMem->flags |= MEM_Str | MEM_Dyn | MEM_Term;
  }else{
    /* Must be translating between UTF-16le and UTF-16be. */
    int i;
    u8 *pFrom, *pTo;
    sqlite3VdbeMemMakeWriteable(pMem);
    for(i=0, pFrom=pMem->z, pTo=&pMem->z[1]; i<pMem->n; i+=2, pFrom+=2,pTo+=2){
      u8 temp = *pFrom;
      *pFrom = *pTo;
      *pTo = temp;
    }
  }
  pMem->enc = desiredEnc;
  return SQLITE_OK;
................................................................................
    /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
    ** string representation of the value. Then, if the required encoding
    ** is UTF-16le or UTF-16be do a translation.
    ** 
    ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
    */
    u8 *z = pMem->zShort;
    if( fg & MEM_Real || (pMem->type==SQLITE3_FLOAT) ){
      sqlite3_snprintf(NBFS, z, "%.15g", pMem->r);
    }else{
      assert( fg & MEM_Int );
      sqlite3_snprintf(NBFS, z, "%lld", pMem->i);
    }
    pMem->n = strlen(z);
    pMem->z = z;
................................................................................
      return SQLITE_NOMEM;
    }
    assert( pMem->z );
    sqlite3atoi64(pMem->z, &pMem->i);
  }else{
    pMem->i = 0;
  }

  pMem->flags |= MEM_Int;

  return SQLITE_OK;
}

/*
** Add MEM_Real to the set of representations for pMem.  Prior
** prior representations other than MEM_Null retained.  NULL is
** converted into 0.0.
*/
int sqlite3VdbeMemRealify(Mem *pMem){
  if( pMem->flags & MEM_Real ){
    /* Do nothing */
  }else if( (pMem->flags & MEM_Int) && pMem->type!=SQLITE3_TEXT ){
    pMem->r = pMem->i;

  }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
    if( sqlite3VdbeChangeEncoding(pMem, TEXT_Utf8)
       || sqlite3VdbeMemNulTerminate(pMem) ){
      return SQLITE_NOMEM;
    }
    assert( pMem->z );
    pMem->r = sqlite3AtoF(pMem->z, 0);



  }else{
    pMem->r = 0.0;


  }
  pMem->flags |= MEM_Real;
  return SQLITE_OK;
}

/*
** Delete any previous value and set the value stored in *pMem to NULL.
*/
void sqlite3VdbeMemSetNull(Mem *pMem){

Changes to test/capi3.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
#    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 script testing the callback-free C/C++ API.
#
# $Id: capi3.test,v 1.8 2004/05/27 09:28:44 danielk1977 Exp $
#

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

# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.
................................................................................
check_header $STMT capi3-5.1 {a b c} {VARIANT BLOB VARCHAR(16)}

do_test capi3-5.2 {
  sqlite3_step $STMT
} SQLITE_ROW

check_header $STMT capi3-5.3 {a b c} {VARIANT BLOB VARCHAR(16)}
check_data $STMT capi3-5.4 {INTEGER INTEGER TEXT} {1 2 3} {1 2 3} {1 2 3}

do_test capi3-5.5 {
  sqlite3_step $STMT
} SQLITE_ROW

check_header $STMT capi3-5.6 {a b c} {VARIANT BLOB VARCHAR(16)}
check_data $STMT capi3-5.7 {TEXT TEXT NULL} {0 0 0} {0 0 0} {one two {}}

do_test capi3-5.8 {
  sqlite3_step $STMT
} SQLITE_ROW

check_header $STMT capi3-5.9 {a b c} {VARIANT BLOB VARCHAR(16)}
check_data $STMT capi3-5.10 {REAL REAL TEXT} {1 1 1} {1.2 1.3 1.4} {1.2 1.3 1.4}

do_test capi3-5.11 {
  sqlite3_step $STMT
} SQLITE_DONE

do_test capi3-5.12 {
  sqlite3_finalize $STMT







|







 







|






|






|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
#    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 script testing the callback-free C/C++ API.
#
# $Id: capi3.test,v 1.9 2004/05/27 10:31:12 danielk1977 Exp $
#

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

# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.
................................................................................
check_header $STMT capi3-5.1 {a b c} {VARIANT BLOB VARCHAR(16)}

do_test capi3-5.2 {
  sqlite3_step $STMT
} SQLITE_ROW

check_header $STMT capi3-5.3 {a b c} {VARIANT BLOB VARCHAR(16)}
check_data $STMT capi3-5.4 {INTEGER INTEGER TEXT} {1 2 3} {1.0 2.0 3.0} {1 2 3}

do_test capi3-5.5 {
  sqlite3_step $STMT
} SQLITE_ROW

check_header $STMT capi3-5.6 {a b c} {VARIANT BLOB VARCHAR(16)}
check_data $STMT capi3-5.7 {TEXT TEXT NULL} {0 0 0} {0.0 0.0 0.0} {one two {}}

do_test capi3-5.8 {
  sqlite3_step $STMT
} SQLITE_ROW

check_header $STMT capi3-5.9 {a b c} {VARIANT BLOB VARCHAR(16)}
check_data $STMT capi3-5.10 {FLOAT FLOAT TEXT} {1 1 1} {1.2 1.3 1.4} {1.2 1.3 1.4}

do_test capi3-5.11 {
  sqlite3_step $STMT
} SQLITE_DONE

do_test capi3-5.12 {
  sqlite3_finalize $STMT

Changes to test/func.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#    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.17 2004/05/14 11:00:53 danielk1977 Exp $

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

# Create a table to work with.
#
do_test func-0.0 {
................................................................................
  catchsql {SELECT abs(c) FROM t1 ORDER BY a}
} {0 {3 12345.6789 5}}
do_test func-4.4.1 {
  execsql {SELECT abs(a) FROM t2}
} {1 {} 345 {} 67890}
do_test func-4.4.2 {
  execsql {SELECT abs(t1) FROM tbl1}
} {this program is free software}

do_test func-4.5 {
  catchsql {SELECT round(a,b,c) FROM t1}
} {1 {wrong number of arguments to function round()}}
do_test func-4.6 {
  catchsql {SELECT round(b,2) FROM t1 ORDER BY b}
} {0 {-2.00 1.23 2.00}}







|







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#    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.18 2004/05/27 10:31:12 danielk1977 Exp $

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

# Create a table to work with.
#
do_test func-0.0 {
................................................................................
  catchsql {SELECT abs(c) FROM t1 ORDER BY a}
} {0 {3 12345.6789 5}}
do_test func-4.4.1 {
  execsql {SELECT abs(a) FROM t2}
} {1 {} 345 {} 67890}
do_test func-4.4.2 {
  execsql {SELECT abs(t1) FROM tbl1}
} {0 0 0 0 0}

do_test func-4.5 {
  catchsql {SELECT round(a,b,c) FROM t1}
} {1 {wrong number of arguments to function round()}}
do_test func-4.6 {
  catchsql {SELECT round(b,2) FROM t1 ORDER BY b}
} {0 {-2.00 1.23 2.00}}