SQLite

Check-in [fd584d1ccf]
Login

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

Overview
Comment:Host parameter names conform to SQL-2003. (CVS 1902)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: fd584d1ccf6643b723c2ff0a7a16c2aea3f1142c
User & Date: drh 2004-08-25 04:07:02.000
Context
2004-08-26
00:56
Protect Tcl_Obj pointers from change using Tcl_IncrRefCount() while executing SQL statements in the TCL bindings. (CVS 1903) (check-in: 6199f2f243 user: drh tags: trunk)
2004-08-25
04:07
Host parameter names conform to SQL-2003. (CVS 1902) (check-in: fd584d1ccf user: drh tags: trunk)
2004-08-24
15:23
Fix a bug in the parsing of wildcards that begin with '$'. (CVS 1901) (check-in: 054dd8901d user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/parse.y.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** This file contains SQLite's grammar for SQL.  Process this file
** using the lemon parser generator to generate C code that runs
** the parser.  Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.134 2004/08/20 16:02:39 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
%default_type {Token}
%extra_argument {Parse *pParse}
%syntax_error {
  if( pParse->zErrMsg==0 ){







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** This file contains SQLite's grammar for SQL.  Process this file
** using the lemon parser generator to generate C code that runs
** the parser.  Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.135 2004/08/25 04:07:02 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
%default_type {Token}
%extra_argument {Parse *pParse}
%syntax_error {
  if( pParse->zErrMsg==0 ){
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
expr(A) ::= FLOAT(X).        {A = sqlite3Expr(@X, 0, 0, &X);}
expr(A) ::= STRING(X).       {A = sqlite3Expr(@X, 0, 0, &X);}
expr(A) ::= BLOB(X).         {A = sqlite3Expr(@X, 0, 0, &X);}
expr(A) ::= VARIABLE(X).     {
  Token *pToken = &X;
  Expr *pExpr = A = sqlite3Expr(TK_VARIABLE, 0, 0, pToken);
  if( pExpr ){
    if( pToken->z[0]==':' ){
      int n = pExpr->iTable = atoi(&pToken->z[1]);
      if( pParse->nVar<n ) pParse->nVar = n;
    }else{
      pExpr->iTable = ++pParse->nVar;
    }
  }
}
expr(A) ::= ID(X) LP exprlist(Y) RP(E). {
  A = sqlite3ExprFunction(Y, &X);
  sqlite3ExprSpan(A,&X,&E);
}
expr(A) ::= ID(X) LP STAR RP(E). {







<
<
<
<
|
<







557
558
559
560
561
562
563




564

565
566
567
568
569
570
571
expr(A) ::= FLOAT(X).        {A = sqlite3Expr(@X, 0, 0, &X);}
expr(A) ::= STRING(X).       {A = sqlite3Expr(@X, 0, 0, &X);}
expr(A) ::= BLOB(X).         {A = sqlite3Expr(@X, 0, 0, &X);}
expr(A) ::= VARIABLE(X).     {
  Token *pToken = &X;
  Expr *pExpr = A = sqlite3Expr(TK_VARIABLE, 0, 0, pToken);
  if( pExpr ){




    pExpr->iTable = ++pParse->nVar;

  }
}
expr(A) ::= ID(X) LP exprlist(Y) RP(E). {
  A = sqlite3ExprFunction(Y, &X);
  sqlite3ExprSpan(A,&X,&E);
}
expr(A) ::= ID(X) LP STAR RP(E). {
Changes to src/tclsqlite.c.
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.
**
*************************************************************************
** A TCL Interface to SQLite
**
** $Id: tclsqlite.c,v 1.101 2004/08/24 15:23:34 drh Exp $
*/
#ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */

#include "sqliteInt.h"
#include "hash.h"
#include "tcl.h"
#include <stdlib.h>













|







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.
**
*************************************************************************
** A TCL Interface to SQLite
**
** $Id: tclsqlite.c,v 1.102 2004/08/25 04:07:02 drh Exp $
*/
#ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */

#include "sqliteInt.h"
#include "hash.h"
#include "tcl.h"
#include <stdlib.h>
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
        }
      }

      /* Bind values to wildcards that begin with $ */  
      nVar = sqlite3_bind_parameter_count(pStmt);
      for(i=1; i<=nVar; i++){
        const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
        if( zVar[0]=='$' ){
          Tcl_Obj *pVar = Tcl_GetVar2Ex(interp, &zVar[1], 0, 0);
          if( pVar ){
            int n;
            u8 *data;
            char *zType = pVar->typePtr ? pVar->typePtr->name : "";
            char c = zType[0];
            if( c=='b' && strcmp(zType,"bytearray")==0 ){







|







741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
        }
      }

      /* Bind values to wildcards that begin with $ */  
      nVar = sqlite3_bind_parameter_count(pStmt);
      for(i=1; i<=nVar; i++){
        const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
        if( zVar[0]=='$' || zVar[0]==':' ){
          Tcl_Obj *pVar = Tcl_GetVar2Ex(interp, &zVar[1], 0, 0);
          if( pVar ){
            int n;
            u8 *data;
            char *zType = pVar->typePtr ? pVar->typePtr->name : "";
            char c = zType[0];
            if( c=='b' && strcmp(zType,"bytearray")==0 ){
Changes to src/tokenize.c.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.83 2004/08/24 15:23:34 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*







|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.84 2004/08/25 04:07:02 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
      return i;
    }
    case '?': {
      *tokenType = TK_VARIABLE;
      return 1;
    }
    case ':': {
      for(i=1; isdigit(z[i]); i++){}
      if( i>1 && z[i]==':' ){
        *tokenType = TK_VARIABLE;
        return i+1;
      }else{
        *tokenType = TK_ILLEGAL;
        return i;
      }
    }
    case '$': {
      int c;
      *tokenType = TK_VARIABLE;
      if( z[1]=='{' ){
        int nBrace = 1;
        for(i=2; (c=z[i])!=0 && nBrace; i++){







|
<
|
<
<
<
|
<







370
371
372
373
374
375
376
377

378



379

380
381
382
383
384
385
386
      return i;
    }
    case '?': {
      *tokenType = TK_VARIABLE;
      return 1;
    }
    case ':': {
      for(i=1; (z[i]&0x80)!=0 || isIdChar[z[i]]; i++){}

      *tokenType = i>1 ? TK_VARIABLE : TK_ILLEGAL;



      return i;

    }
    case '$': {
      int c;
      *tokenType = TK_VARIABLE;
      if( z[1]=='{' ){
        int nBrace = 1;
        for(i=2; (c=z[i])!=0 && nBrace; i++){
Changes to test/bind.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2003 September 6
#
# 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 script testing the sqlite_bind API.
#
# $Id: bind.test,v 1.17 2004/08/20 18:34:20 drh Exp $
#

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

proc sqlite_step {stmt N VALS COLS} {
  upvar VALS vals













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2003 September 6
#
# 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 script testing the sqlite_bind API.
#
# $Id: bind.test,v 1.18 2004/08/25 04:07:03 drh Exp $
#

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

proc sqlite_step {stmt N VALS COLS} {
  upvar VALS vals
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

  return $rc
}

do_test bind-1.1 {
  db close
  set DB [sqlite3 db test.db]
  execsql {CREATE TABLE t1(a,b,c)}
  set VM [sqlite3_prepare $DB {INSERT INTO t1 VALUES(:1:,?,:3:)} -1 TAIL]
  set TAIL
} {}
do_test bind-1.1.1 {
  sqlite3_bind_parameter_count $VM
} 3
do_test bind-1.1.2 {
  sqlite3_bind_parameter_name $VM 1
} {:1:}
do_test bind-1.1.3 {
  sqlite3_bind_parameter_name $VM 2
} {}
do_test bind-1.1.4 {
  sqlite3_bind_parameter_name $VM 3
} {:3:}
do_test bind-1.2 {
  sqlite_step $VM N VALUES COLNAMES
} {SQLITE_DONE}
do_test bind-1.3 {
  execsql {SELECT rowid, * FROM t1}
} {1 {} {} {}}
do_test bind-1.4 {







|
|







|





|







33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

  return $rc
}

do_test bind-1.1 {
  db close
  set DB [sqlite3 db test.db]
  execsql {CREATE TABLE t1(a,b,c);}
  set VM [sqlite3_prepare $DB {INSERT INTO t1 VALUES(:1,?,:abc)} -1 TAIL]
  set TAIL
} {}
do_test bind-1.1.1 {
  sqlite3_bind_parameter_count $VM
} 3
do_test bind-1.1.2 {
  sqlite3_bind_parameter_name $VM 1
} {:1}
do_test bind-1.1.3 {
  sqlite3_bind_parameter_name $VM 2
} {}
do_test bind-1.1.4 {
  sqlite3_bind_parameter_name $VM 3
} {:abc}
do_test bind-1.2 {
  sqlite_step $VM N VALUES COLNAMES
} {SQLITE_DONE}
do_test bind-1.3 {
  execsql {SELECT rowid, * FROM t1}
} {1 {} {} {}}
do_test bind-1.4 {
Changes to www/capi3ref.tcl.
1
2
3
4
5
6
7
8
set rcsid {$Id: capi3ref.tcl,v 1.8 2004/08/20 16:02:40 drh Exp $}
source common.tcl
header {C/C++ Interface For SQLite Version 3}
puts {
<h2>C/C++ Interface For SQLite Version 3</h2>
}

proc api {name prototype desc {notused x}} {
|







1
2
3
4
5
6
7
8
set rcsid {$Id: capi3ref.tcl,v 1.9 2004/08/25 04:07:03 drh Exp $}
source common.tcl
header {C/C++ Interface For SQLite Version 3}
puts {
<h2>C/C++ Interface For SQLite Version 3</h2>
}

proc api {name prototype desc {notused x}} {
76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91
92
93
94
95
96
97
  int sqlite3_bind_null(sqlite3_stmt*, int);
  int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
  int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
  #define SQLITE_STATIC      ((void(*)(void *))0)
  #define SQLITE_TRANSIENT   ((void(*)(void *))-1)
} {
 In the SQL strings input to sqlite3_prepare() and sqlite3_prepare16(),
 one or more literals can be replace by a wildcard "?" or ":N:" where

 N is an integer.  The value of these wildcard literals can be set
 using these routines.

 The first parameter is a pointer to the sqlite3_stmt
 structure returned from sqlite3_prepare().  The second parameter is the
 index of the wildcard.  The first "?" has an index of 1.  ":N:" wildcards
 use the index N.

 The fifth parameter to sqlite3_bind_blob(), sqlite3_bind_text(), and
 sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
 text after SQLite has finished with it.  If the fifth argument is the
 special value SQLITE_STATIC, then the library assumes that the information
 is in static, unmanaged space and does not need to be freed.  If the
 fifth argument has the value SQLITE_TRANSIENT, then SQLite makes its







|
>
|
|



|
<







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
  int sqlite3_bind_null(sqlite3_stmt*, int);
  int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
  int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
  #define SQLITE_STATIC      ((void(*)(void *))0)
  #define SQLITE_TRANSIENT   ((void(*)(void *))-1)
} {
 In the SQL strings input to sqlite3_prepare() and sqlite3_prepare16(),
 one or more literals can be replace by a wildcard "?" or ":AAA" where
 AAA is an alphanumeric identifier.
 The value of these wildcard literals (also called "host parameter names")
 can be set using these routines.

 The first parameter is a pointer to the sqlite3_stmt
 structure returned from sqlite3_prepare().  The second parameter is the
 index of the wildcard.  The first wildcard has an index of 1. 


 The fifth parameter to sqlite3_bind_blob(), sqlite3_bind_text(), and
 sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
 text after SQLite has finished with it.  If the fifth argument is the
 special value SQLITE_STATIC, then the library assumes that the information
 is in static, unmanaged space and does not need to be freed.  If the
 fifth argument has the value SQLITE_TRANSIENT, then SQLite makes its
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
  the argument.
}

api {} {
  const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int n);
} {
  Return the name of the n-th wildcard in the precompiled statement.
  Wildcards of the form ":N:" have a name which is the string ":N:".
  Wildcards of the form "?" have no name.

  If the value n is out of range or if the n-th wildcard is nameless,
  then NULL is returned.  The returned string is always in the
  UTF-8 encoding.
}








|







110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
  the argument.
}

api {} {
  const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int n);
} {
  Return the name of the n-th wildcard in the precompiled statement.
  Wildcards of the form ":AAA" have a name which is the string ":AAA".
  Wildcards of the form "?" have no name.

  If the value n is out of range or if the n-th wildcard is nameless,
  then NULL is returned.  The returned string is always in the
  UTF-8 encoding.
}