SQLite

Check-in [ced6bbd228]
Login

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

Overview
Comment:Fix issues with bizarrely quoted column names. Tickets #3370, #3371, and #3372. (CVS 5696)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ced6bbd228b4a324ddb9c5ff15fd027811c8806a
User & Date: drh 2008-09-13 01:20:15.000
Context
2008-09-15
04:20
Check if error code ENOTSUP is supported before using it. Ticket #3375. (CVS 5697) (check-in: c32cb106c5 user: danielk1977 tags: trunk)
2008-09-13
01:20
Fix issues with bizarrely quoted column names. Tickets #3370, #3371, and #3372. (CVS 5696) (check-in: ced6bbd228 user: drh tags: trunk)
2008-09-12
18:25
Fix the NEAR connector in FTS3 so that it can take ranges in excess of 9. The maximum range is now 32767. (CVS 5695) (check-in: 8e9b955311 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/select.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 SELECT statements in SQLite.
**
** $Id: select.c,v 1.472 2008/09/01 15:52:11 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.







|







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 SELECT statements in SQLite.
**
** $Id: select.c,v 1.473 2008/09/13 01:20:15 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
200
201
202
203
204
205
206

207
208
209
210
211
212

213
214
215

216
217
218
219
220
221
222
** Set the token to the double-quoted and escaped version of the string pointed
** to by z. For example;
**
**    {a"bc}  ->  {"a""bc"}
*/
static void setQuotedToken(Parse *pParse, Token *p, const char *z){


  /* Check if the string contains any " characters. If it does, then
  ** this function will malloc space to create a quoted version of
  ** the string in. Otherwise, save a call to sqlite3MPrintf() by
  ** just copying the pointer to the string.
  */
  const char *z2 = z;

  while( *z2 ){
    if( *z2=='"' ) break;
    z2++;

  }

  if( *z2 ){
    /* String contains " characters - copy and quote the string. */
    p->z = (u8 *)sqlite3MPrintf(pParse->db, "\"%w\"", z);
    if( p->z ){
      p->n = strlen((char *)p->z);







>
|
|
<
|


>
|
|
|
>







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
** Set the token to the double-quoted and escaped version of the string pointed
** to by z. For example;
**
**    {a"bc}  ->  {"a""bc"}
*/
static void setQuotedToken(Parse *pParse, Token *p, const char *z){

  /* Check if the string appears to be quoted using "..." or `...`
  ** or [...] or '...' or if the string contains any " characters.  
  ** If it does, then record a version of the string with the special

  ** characters escaped.
  */
  const char *z2 = z;
  if( *z2!='[' && *z2!='`' && *z2!='\'' ){
    while( *z2 ){
      if( *z2=='"' ) break;
      z2++;
    }
  }

  if( *z2 ){
    /* String contains " characters - copy and quote the string. */
    p->z = (u8 *)sqlite3MPrintf(pParse->db, "\"%w\"", z);
    if( p->z ){
      p->n = strlen((char *)p->z);
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
  for(i=0; i<pEList->nExpr; i++){
    Expr *p;
    p = pEList->a[i].pExpr;
    if( p==0 ) continue;
    if( pEList->a[i].zName ){
      char *zName = pEList->a[i].zName;
      sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, strlen(zName));
    }else if( p->op==TK_COLUMN && pTabList ){
      Table *pTab;
      char *zCol;
      int iCol = p->iColumn;
      for(j=0; j<pTabList->nSrc && pTabList->a[j].iCursor!=p->iTable; j++){}
      assert( j<pTabList->nSrc );
      pTab = pTabList->a[j].pTab;
      if( iCol<0 ) iCol = pTab->iPKey;







|







1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
  for(i=0; i<pEList->nExpr; i++){
    Expr *p;
    p = pEList->a[i].pExpr;
    if( p==0 ) continue;
    if( pEList->a[i].zName ){
      char *zName = pEList->a[i].zName;
      sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, strlen(zName));
    }else if( (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN) && pTabList ){
      Table *pTab;
      char *zCol;
      int iCol = p->iColumn;
      for(j=0; j<pTabList->nSrc && pTabList->a[j].iCursor!=p->iTable; j++){}
      assert( j<pTabList->nSrc );
      pTab = pTabList->a[j].pTab;
      if( iCol<0 ) iCol = pTab->iPKey;
Changes to test/colname.test.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
#***********************************************************************
# This file implements regression tests for SQLite library. 
#
# The focus of this file is testing how SQLite generates the names
# of columns in a result set.
#
# $Id: colname.test,v 1.4 2008/08/02 20:09:37 drh Exp $

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

# Rules (applied in order):
#
# (1) If there is an AS clause, use it.







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
#***********************************************************************
# This file implements regression tests for SQLite library. 
#
# The focus of this file is testing how SQLite generates the names
# of columns in a result set.
#
# $Id: colname.test,v 1.5 2008/09/13 01:20:15 drh Exp $

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

# Rules (applied in order):
#
# (1) If there is an AS clause, use it.
250
251
252
253
254
255
256
257
















































258

# ticket #3229
do_test colname-5.1 {
  lreplace [db eval {
    SELECT x.* FROM sqlite_master X LIMIT 1;
  }] 3 3 x
} {table tabc tabc x {CREATE TABLE tabc(a,b,c)}}

















































finish_test








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

250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306

# ticket #3229
do_test colname-5.1 {
  lreplace [db eval {
    SELECT x.* FROM sqlite_master X LIMIT 1;
  }] 3 3 x
} {table tabc tabc x {CREATE TABLE tabc(a,b,c)}}

# ticket #3370, #3371, #3372
#
do_test colname-6.1 {
  db close
  sqlite3 db test.db
  db eval {
    CREATE TABLE t6(a, ['a'], ["a"], "[a]", [`a`]);
    INSERT INTO t6 VALUES(1,2,3,4,5);
  }
  execsql2 {SELECT * FROM t6}
} {a 1 'a' 2 {"a"} 3 {[a]} 4 `a` 5}
do_test colname-6.2 {
  execsql2 {SELECT ['a'], [`a`], "[a]", [a], ["a"] FROM t6}
} {'a' 2 `a` 5 {[a]} 4 a 1 {"a"} 3}
do_test colname-6.3 {
  execsql2 {SELECT "'a'", "`a`", "[a]", "a", """a""" FROM t6}
} {'a' 2 `a` 5 {[a]} 4 a 1 {"a"} 3}
do_test colname-6.4 {
  execsql2 {SELECT `'a'`, ```a```, `[a]`, `a`, `"a"` FROM t6}
} {'a' 2 `a` 5 {[a]} 4 a 1 {"a"} 3}
do_test colname-6.11 {
  execsql2 {SELECT a, max(a) AS m FROM t6}
} {a 1 m 1}
do_test colname-6.12 {
  execsql2 {SELECT `a`, max(a) AS m FROM t6}
} {a 1 m 1}
do_test colname-6.13 {
  execsql2 {SELECT "a", max(a) AS m FROM t6}
} {a 1 m 1}
do_test colname-6.14 {
  execsql2 {SELECT [a], max(a) AS m FROM t6}
} {a 1 m 1}
do_test colname-6.15 {
  execsql2 {SELECT t6.a, max(a) AS m FROM t6}
} {a 1 m 1}
do_test colname-6.16 {
  execsql2 {SELECT ['a'], max(['a']) AS m FROM t6}
} {'a' 2 m 2}
do_test colname-6.17 {
  execsql2 {SELECT ["a"], max(["a"]) AS m FROM t6}
} {{"a"} 3 m 3}
do_test colname-6.18 {
  execsql2 {SELECT "[a]", max("[a]") AS m FROM t6}
} {{[a]} 4 m 4}
do_test colname-6.19 {
  execsql2 {SELECT "`a`", max([`a`]) AS m FROM t6}
} {`a` 5 m 5}

finish_test