/ Check-in [ced6bbd2]
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 | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:ced6bbd228b4a324ddb9c5ff15fd027811c8806a
User & Date: drh 2008-09-13 01:20:15
Context
2008-09-15
04:20
Check if error code ENOTSUP is supported before using it. Ticket #3375. (CVS 5697) check-in: c32cb106 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: ced6bbd2 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: 8e9b9553 user: drh 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
...
200
201
202
203
204
205
206

207
208
209
210
211
212

213
214
215

216
217
218
219
220
221
222
....
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
**    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.
................................................................................
** 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);
................................................................................
  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;







|







 







>
|
<
|
|


>
|
|
|
>







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
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
....
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
**    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.
................................................................................
** 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);
................................................................................
  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
...
250
251
252
253
254
255
256
257
















































258
#
#***********************************************************************
# 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.
................................................................................

# 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







|







 








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

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
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
#
#***********************************************************************
# 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.
................................................................................

# 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