/ Check-in [c8a40218]
Login

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

Overview
Comment:Fix a bug in the sqlite3_column_decltype() API. (CVS 1486)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:c8a40218c20cf5d0abad330e8fa59ca4c36e7608
User & Date: danielk1977 2004-05-28 13:13:02
Context
2004-05-28
16:00
Factor common code for generating index keys into a procedure. Other speed improvements and bug fixes. (CVS 1487) check-in: 6661bb5f user: drh tags: trunk
13:13
Fix a bug in the sqlite3_column_decltype() API. (CVS 1486) check-in: c8a40218 user: danielk1977 tags: trunk
12:33
Allow CREATE and DROP VIEW on attached databases. (CVS 1485) check-in: ad879a95 user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/select.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
...
736
737
738
739
740
741
742

743
744
745
746
747
748
749
**    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.180 2004/05/27 23:56:16 danielk1977 Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.
................................................................................
    }else{
      switch( sqlite3ExprType(p) ){
        case SQLITE_AFF_TEXT:     zType = "TEXT";    break;
        case SQLITE_AFF_NUMERIC:  zType = "NUMERIC"; break;
        default:                  zType = "ANY";     break;
      }
    }
    sqlite3VdbeOp3(v, OP_ColumnName, i + pEList->nExpr, 0, zType, 0);
  }
}

/*
** Generate code that will tell the VDBE the names of columns
** in the result set.  This information is used to provide the
** azCol[] values in the callback.
................................................................................
    }else{
      char zName[30];
      assert( p->op!=TK_COLUMN || pTabList==0 );
      sprintf(zName, "column%d", i+1);
      sqlite3VdbeSetColName(v, i, zName, 0);
    }
  }

}

/*
** Name of the connection operator, used for error messages.
*/
static const char *selectOpName(int id){
  char *z;







|







 







|







 







>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
...
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
**    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.181 2004/05/28 13:13:02 danielk1977 Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.
................................................................................
    }else{
      switch( sqlite3ExprType(p) ){
        case SQLITE_AFF_TEXT:     zType = "TEXT";    break;
        case SQLITE_AFF_NUMERIC:  zType = "NUMERIC"; break;
        default:                  zType = "ANY";     break;
      }
    }
    sqlite3VdbeSetColName(v, i+pEList->nExpr, zType, P3_STATIC);
  }
}

/*
** Generate code that will tell the VDBE the names of columns
** in the result set.  This information is used to provide the
** azCol[] values in the callback.
................................................................................
    }else{
      char zName[30];
      assert( p->op!=TK_COLUMN || pTabList==0 );
      sprintf(zName, "column%d", i+1);
      sqlite3VdbeSetColName(v, i, zName, 0);
    }
  }
  generateColumnTypes(pParse, pTabList, pEList);
}

/*
** Name of the connection operator, used for error messages.
*/
static const char *selectOpName(int id){
  char *z;

Changes to src/vdbeapi.c.

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
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378

379
380
381
382
383
384
385
386
387
388
389
390
391
392
393


394
395
396
397
398
399
400
    return 0;
  }

  pColName = &(p->aColName[N]);
  return sqlite3_value_text16(pColName);
}


/*

** This routine returns either the column name, or declaration type (see
** sqlite3_column_decltype16() ) of the 'i'th column of the result set of
** SQL statement pStmt. The returned string is UTF-16 encoded.
**
** The declaration type is returned if 'decltype' is true, otherwise
** the column name.
*/
static const void *columnName16(sqlite3_stmt *pStmt, int i, int decltype){
  Vdbe *p = (Vdbe *)pStmt;


  if( i>=sqlite3_column_count(pStmt) || i<0 ){
    sqlite3Error(p->db, SQLITE_RANGE, 0);
    return 0;
  }

  if( decltype ){
    i += p->nResColumn;


  }

  if( !p->azColName16 ){
    p->azColName16 = (void **)sqliteMalloc(sizeof(void *)*p->nResColumn*2);
    if( !p->azColName16 ){
      sqlite3Error(p->db, SQLITE_NOMEM, 0);
      return 0;
    }
  }
  if( !p->azColName16[i] ){
    if( SQLITE3_BIGENDIAN ){
      p->azColName16[i] = sqlite3utf8to16be(p->azColName[i], -1);
    }
    if( !p->azColName16[i] ){
      sqlite3Error(p->db, SQLITE_NOMEM, 0);
      return 0;
    }
  }
  return p->azColName16[i];
}

/*
** Return the column declaration type (if applicable) of the 'i'th column
** of the result set of SQL statement pStmt, encoded as UTF-8.
*/
const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int i){
  Vdbe *p = (Vdbe *)pStmt;


  if( i>=sqlite3_column_count(pStmt) || i<0 ){
    sqlite3Error(p->db, SQLITE_RANGE, 0);
    return 0;
  }

  return p->azColName[i+p->nResColumn];
}

/*
** Return the column declaration type (if applicable) of the 'i'th column
** of the result set of SQL statement pStmt, encoded as UTF-16.
*/
const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int i){
  return columnName16(pStmt, i, 1);


}

/******************************* sqlite3_bind_  ***************************
** 
** Routines used to attach values to wildcards in a compiled SQL statement.
*/
/*







<

>
|
<
<
<
<
<

|

>

|




<
<
>
>
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|

|

>

|




<
<
<
<
<
<
<
<
<
>
>







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
353
354
355
356
357
358
359
360
361
362









363
364
365
366
367
368
369
370
371
    return 0;
  }

  pColName = &(p->aColName[N]);
  return sqlite3_value_text16(pColName);
}


/*
** Return the column declaration type (if applicable) of the 'i'th column
** of the result set of SQL statement pStmt, encoded as UTF-8.





*/
const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
  Vdbe *p = (Vdbe *)pStmt;
  Mem *pColName;

  if( N>=sqlite3_column_count(pStmt) || N<0 ){
    sqlite3Error(p->db, SQLITE_RANGE, 0);
    return 0;
  }



  pColName = &(p->aColName[N+sqlite3_column_count(pStmt)]);
  return sqlite3_value_text(pColName);
}




















/*
** Return the column declaration type (if applicable) of the 'i'th column
** of the result set of SQL statement pStmt, encoded as UTF-16.
*/
const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
  Vdbe *p = (Vdbe *)pStmt;
  Mem *pColName;

  if( N>=sqlite3_column_count(pStmt) || N<0 ){
    sqlite3Error(p->db, SQLITE_RANGE, 0);
    return 0;
  }










  pColName = &(p->aColName[N+sqlite3_column_count(pStmt)]);
  return sqlite3_value_text16(pColName);
}

/******************************* sqlite3_bind_  ***************************
** 
** Routines used to attach values to wildcards in a compiled SQL statement.
*/
/*

Changes to src/vdbeaux.c.

917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
** This call must be made after a call to sqlite3VdbeSetNumCols().
**
** Parameter N may be either P3_DYNAMIC or P3_STATIC.
*/
int sqlite3VdbeSetColName(Vdbe *p, int idx, const char *zName, int N){
  int rc;
  Mem *pColName;
  assert( idx<p->nResColumn );

  /* If the Vdbe.aColName array has not yet been allocated, allocate
  ** it now.
  */
  if( !p->aColName ){
    int i;
    p->aColName = (Mem *)sqliteMalloc(sizeof(Mem)*p->nResColumn);
    if( !p->aColName ){
      return SQLITE_NOMEM;
    }
    for(i=0; i<p->nResColumn; i++){
      p->aColName[i].flags = MEM_Null;
    }
  }

  pColName = &(p->aColName[idx]);
  if( N==0 ){
    rc = sqlite3VdbeMemSetStr(pColName, zName, -1, TEXT_Utf8, 1);







|






|



|







917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
** This call must be made after a call to sqlite3VdbeSetNumCols().
**
** Parameter N may be either P3_DYNAMIC or P3_STATIC.
*/
int sqlite3VdbeSetColName(Vdbe *p, int idx, const char *zName, int N){
  int rc;
  Mem *pColName;
  assert( idx<(2*p->nResColumn) );

  /* If the Vdbe.aColName array has not yet been allocated, allocate
  ** it now.
  */
  if( !p->aColName ){
    int i;
    p->aColName = (Mem *)sqliteMalloc(sizeof(Mem)*p->nResColumn*2);
    if( !p->aColName ){
      return SQLITE_NOMEM;
    }
    for(i=0; i<(2*p->nResColumn); i++){
      p->aColName[i].flags = MEM_Null;
    }
  }

  pColName = &(p->aColName[idx]);
  if( N==0 ){
    rc = sqlite3VdbeMemSetStr(pColName, zName, -1, TEXT_Utf8, 1);

Changes to test/capi3.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
189
190
191
192
193
194
195

196

197
198
199
200
201
202
203
204
205
206
207
208
209

210

211
212

















213
214
215
216
217
218
219
...
317
318
319
320
321
322
323
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
#    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.
................................................................................
    foreach i $idxlist {lappend cnamelist [sqlite3_column_name $STMT $i]} 
    set cnamelist
  } $names

  # Column names in UTF-16
  do_test $test.2 {
    set cnamelist [list]

    foreach i $idxlist {lappend cnamelist [utf8 [sqlite3_column_name16 $STMT $i]]}

    set cnamelist
  } $names

  # Column names in UTF-8
  do_test $test.3 {
    set cnamelist [list]
    foreach i $idxlist {lappend cnamelist [sqlite3_column_name $STMT $i]} 
    set cnamelist
  } $names

  # Column names in UTF-16
  do_test $test.4 {
    set cnamelist [list]

    foreach i $idxlist {lappend cnamelist [utf8 [sqlite3_column_name16 $STMT $i]]}

    set cnamelist
  } $names

















} 

# This proc is used to test the following APIs:
#
# sqlite3_data_count
# sqlite3_column_type
# sqlite3_column_int
................................................................................
  }
  set sql "SELECT * FROM t1"
  set STMT [sqlite3_prepare $DB $sql -1 TAIL]

  sqlite3_column_count $STMT
} 3

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 {







|







 







>
|
>













>
|
>


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







 







|





|






|






|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
...
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
#    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.10 2004/05/28 13:13:04 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.
................................................................................
    foreach i $idxlist {lappend cnamelist [sqlite3_column_name $STMT $i]} 
    set cnamelist
  } $names

  # Column names in UTF-16
  do_test $test.2 {
    set cnamelist [list]
    foreach i $idxlist {
      lappend cnamelist [utf8 [sqlite3_column_name16 $STMT $i]]
    }
    set cnamelist
  } $names

  # Column names in UTF-8
  do_test $test.3 {
    set cnamelist [list]
    foreach i $idxlist {lappend cnamelist [sqlite3_column_name $STMT $i]} 
    set cnamelist
  } $names

  # Column names in UTF-16
  do_test $test.4 {
    set cnamelist [list]
    foreach i $idxlist {
      lappend cnamelist [utf8 [sqlite3_column_name16 $STMT $i]]
    }
    set cnamelist
  } $names

  # Column names in UTF-8
  do_test $test.5 {
    set cnamelist [list]
    foreach i $idxlist {lappend cnamelist [sqlite3_column_decltype $STMT $i]} 
    set cnamelist
  } $decltypes

  # Column declaration types in UTF-16
  do_test $test.6 {
    set cnamelist [list]
    foreach i $idxlist {
      lappend cnamelist [utf8 [sqlite3_column_decltype16 $STMT $i]]
    }
    set cnamelist
  } $decltypes

} 

# This proc is used to test the following APIs:
#
# sqlite3_data_count
# sqlite3_column_type
# sqlite3_column_int
................................................................................
  }
  set sql "SELECT * FROM t1"
  set STMT [sqlite3_prepare $DB $sql -1 TAIL]

  sqlite3_column_count $STMT
} 3

check_header $STMT capi3-5.1 {a b c} {VARINT BLOB VARCHAR(16)}

do_test capi3-5.2 {
  sqlite3_step $STMT
} SQLITE_ROW

check_header $STMT capi3-5.3 {a b c} {VARINT 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} {VARINT 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} {VARINT 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 {