SQLite

Check-in [ec1f3fae6f]
Login

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

Overview
Comment:Allow general expressions in the VALUES clause of an INSERT statement. (CVS 376)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ec1f3fae6f8cd8466892cd370e1802e492a76e6e
User & Date: drh 2002-02-18 13:56:37.000
Context
2002-02-18
18:30
Add support for CREATE TABLE AS. (CVS 377) (check-in: 78a50971e9 user: drh tags: trunk)
13:56
Allow general expressions in the VALUES clause of an INSERT statement. (CVS 376) (check-in: ec1f3fae6f user: drh tags: trunk)
13:35
Additional tests for the sub-query feature. (CVS 375) (check-in: a0019fce70 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/insert.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    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 INSERT statements in SQLite.
**
** $Id: insert.c,v 1.42 2002/02/03 19:06:03 drh Exp $
*/
#include "sqliteInt.h"

/*
** This routine is call to handle SQL of the following forms:
**
**    insert into TABLE (IDLIST) values(EXPRLIST)







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    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 INSERT statements in SQLite.
**
** $Id: insert.c,v 1.43 2002/02/18 13:56:37 drh Exp $
*/
#include "sqliteInt.h"

/*
** This routine is call to handle SQL of the following forms:
**
**    insert into TABLE (IDLIST) values(EXPRLIST)
96
97
98
99
100
101
102

103
104
105
106









107
108
109
110
111
112
113
    srcTab = pParse->nTab++;
    sqliteVdbeAddOp(v, OP_OpenTemp, srcTab, 0);
    rc = sqliteSelect(pParse, pSelect, SRT_Table, srcTab);
    if( rc || pParse->nErr || sqlite_malloc_failed ) goto insert_cleanup;
    assert( pSelect->pEList );
    nColumn = pSelect->pEList->nExpr;
  }else{

    assert( pList!=0 );
    srcTab = -1;
    assert( pList );
    nColumn = pList->nExpr;









  }

  /* Make sure the number of columns in the source data matches the number
  ** of columns to be inserted into the table.
  */
  if( pColumn==0 && nColumn!=pTab->nCol ){
    char zNum1[30];







>




>
>
>
>
>
>
>
>
>







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
    srcTab = pParse->nTab++;
    sqliteVdbeAddOp(v, OP_OpenTemp, srcTab, 0);
    rc = sqliteSelect(pParse, pSelect, SRT_Table, srcTab);
    if( rc || pParse->nErr || sqlite_malloc_failed ) goto insert_cleanup;
    assert( pSelect->pEList );
    nColumn = pSelect->pEList->nExpr;
  }else{
    IdList dummy;
    assert( pList!=0 );
    srcTab = -1;
    assert( pList );
    nColumn = pList->nExpr;
    for(i=0; i<nColumn; i++){
      sqliteExprResolveInSelect(pParse, pList->a[i].pExpr);
    }
    dummy.nId = 0;
    for(i=0; i<nColumn; i++){
      if( sqliteExprResolveIds(pParse, &dummy, 0, pList->a[i].pExpr) ){
        goto insert_cleanup;
      }
    }
  }

  /* Make sure the number of columns in the source data matches the number
  ** of columns to be inserted into the table.
  */
  if( pColumn==0 && nColumn!=pTab->nCol ){
    char zNum1[30];
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.49 2002/02/18 01:17:00 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
%default_type {Token}
%extra_argument {Parse *pParse}
%syntax_error {
  sqliteSetString(&pParse->zErrMsg,"syntax error",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.50 2002/02/18 13:56:37 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
%default_type {Token}
%extra_argument {Parse *pParse}
%syntax_error {
  sqliteSetString(&pParse->zErrMsg,"syntax error",0);
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
%type insert_cmd {int}
insert_cmd(A) ::= INSERT orconf(R).   {A = R;}
insert_cmd(A) ::= REPLACE.            {A = OE_Replace;}


%type itemlist {ExprList*}
%destructor itemlist {sqliteExprListDelete($$);}
%type item {Expr*}
%destructor item {sqliteExprDelete($$);}

itemlist(A) ::= itemlist(X) COMMA item(Y).  {A = sqliteExprListAppend(X,Y,0);}
itemlist(A) ::= item(X).     {A = sqliteExprListAppend(0,X,0);}
item(A) ::= INTEGER(X).      {A = sqliteExpr(TK_INTEGER, 0, 0, &X);}
item(A) ::= PLUS INTEGER(X). {A = sqliteExpr(TK_INTEGER, 0, 0, &X);}
item(A) ::= MINUS INTEGER(X). {
  A = sqliteExpr(TK_UMINUS, 0, 0, 0);
  if( A ) A->pLeft = sqliteExpr(TK_INTEGER, 0, 0, &X);
}
item(A) ::= FLOAT(X).        {A = sqliteExpr(TK_FLOAT, 0, 0, &X);}
item(A) ::= PLUS FLOAT(X).   {A = sqliteExpr(TK_FLOAT, 0, 0, &X);}
item(A) ::= MINUS FLOAT(X).  {
  A = sqliteExpr(TK_UMINUS, 0, 0, 0);
  if( A ) A->pLeft = sqliteExpr(TK_FLOAT, 0, 0, &X);
}
item(A) ::= STRING(X).       {A = sqliteExpr(TK_STRING, 0, 0, &X);}
item(A) ::= NULL.            {A = sqliteExpr(TK_NULL, 0, 0, 0);}

%type inscollist_opt {IdList*}
%destructor inscollist_opt {sqliteIdListDelete($$);}
%type inscollist {IdList*}
%destructor inscollist {sqliteIdListDelete($$);}

inscollist_opt(A) ::= .                       {A = 0;}







<
<

|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<







343
344
345
346
347
348
349


350
351
352














353
354
355
356
357
358
359
%type insert_cmd {int}
insert_cmd(A) ::= INSERT orconf(R).   {A = R;}
insert_cmd(A) ::= REPLACE.            {A = OE_Replace;}


%type itemlist {ExprList*}
%destructor itemlist {sqliteExprListDelete($$);}



itemlist(A) ::= itemlist(X) COMMA expr(Y).  {A = sqliteExprListAppend(X,Y,0);}
itemlist(A) ::= expr(X).                    {A = sqliteExprListAppend(0,X,0);}















%type inscollist_opt {IdList*}
%destructor inscollist_opt {sqliteIdListDelete($$);}
%type inscollist {IdList*}
%destructor inscollist {sqliteIdListDelete($$);}

inscollist_opt(A) ::= .                       {A = 0;}
Changes to test/insert.test.
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.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the INSERT statement.
#
# $Id: insert.test,v 1.7 2002/02/03 19:06:03 drh Exp $

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

# Try to insert into a non-existant table.
#
do_test insert-1.1 {













|







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.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the INSERT statement.
#
# $Id: insert.test,v 1.8 2002/02/18 13:56:37 drh Exp $

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

# Try to insert into a non-existant table.
#
do_test insert-1.1 {
158
159
160
161
162
163
164





165

























166
} {22 -4.44 hi abc-123 wham}
do_test insert-3.5 {
  set x [execsql {PRAGMA sanity_check}]
  if {$x==""} {set x ok}
  set x
} {ok}
































finish_test







>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

158
159
160
161
162
163
164
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
} {22 -4.44 hi abc-123 wham}
do_test insert-3.5 {
  set x [execsql {PRAGMA sanity_check}]
  if {$x==""} {set x ok}
  set x
} {ok}

do_test insert-4.1 {
  execsql {
    CREATE TABLE t3(a,b,c);
    INSERT INTO t3 VALUES(1+2+3,4,5);
    SELECT * FROM t3;
  }
} {6 4 5}
do_test insert-4.2 {
  execsql {
    INSERT INTO t3 VALUES((SELECT max(a) FROM t3)+1,5,6);
    SELECT * FROM t3 ORDER BY a;
  }
} {6 4 5 7 5 6}
do_test insert-4.3 {
  catchsql {
    INSERT INTO t3 VALUES((SELECT max(a) FROM t3)+1,t3.a,6);
    SELECT * FROM t3 ORDER BY a;
  }
} {1 {no such column: t3.a}}
do_test insert-4.4 {
  execsql {
    INSERT INTO t3 VALUES((SELECT b FROM t3 WHERE a=0),6,7);
    SELECT * FROM t3 ORDER BY a;
  }
} {{} 6 7 6 4 5 7 5 6}
do_test insert-4.5 {
  execsql {
    SELECT b,c FROM t3 WHERE a IS NULL;
  }
} {6 7}

finish_test
Changes to www/changes.tcl.
19
20
21
22
23
24
25


26
27
28
29
30
31
32

chng {2002 Feb * (2.3.3)} {
<li>Allow identifiers to be quoted in square brackets, for compatibility
    with MS-Access.</li>
<li>Added support for sub-queries in the FROM clause of a SELECT.</li>
<li>More efficient implementation of sqliteFileExists() under Windows.
    (by Joel Luscy)</li>


}

chng {2002 Feb 14 (2.3.2)} {
<li>Bug fix: There was an incorrect assert() in pager.c.  The real code was
    all correct (as far as is known) so everything should work OK if you
    compile with -DNDEBUG=1.  But without disability the assertions, there
    could be a fault.</li>







>
>







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

chng {2002 Feb * (2.3.3)} {
<li>Allow identifiers to be quoted in square brackets, for compatibility
    with MS-Access.</li>
<li>Added support for sub-queries in the FROM clause of a SELECT.</li>
<li>More efficient implementation of sqliteFileExists() under Windows.
    (by Joel Luscy)</li>
<li>The VALUES clause of an INSERT can now contain expressions, including
    scalar SELECT clauses.</li>
}

chng {2002 Feb 14 (2.3.2)} {
<li>Bug fix: There was an incorrect assert() in pager.c.  The real code was
    all correct (as far as is known) so everything should work OK if you
    compile with -DNDEBUG=1.  But without disability the assertions, there
    could be a fault.</li>