SQLite

Check-in [fcde639119]
Login

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

Overview
Comment:Make sure memory does not leak when patching up column names so that they are unique in a join or view. Tickets #1952 and #2002. (CVS 3451)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: fcde639119c309c699ee9dd60ed60fd6e9c8c077
User & Date: drh 2006-09-29 14:01:05.000
Context
2006-10-01
18:41
Add a Porter stemmer option to the FTS1 module. (CVS 3452) (check-in: 936b06aaa8 user: drh tags: trunk)
2006-09-29
14:01
Make sure memory does not leak when patching up column names so that they are unique in a join or view. Tickets #1952 and #2002. (CVS 3451) (check-in: fcde639119 user: drh tags: trunk)
2006-09-28
19:43
Fix a bug in the handling of the OR operator in FTS1. Test cases added to prevent a repeat. (CVS 3450) (check-in: 8cdf1d6ae0 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.320 2006/08/11 19:08:27 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.321 2006/09/29 14:01:05 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
  pTab->nCol = pEList->nExpr;
  assert( pTab->nCol>0 );
  pTab->aCol = aCol = sqliteMalloc( sizeof(pTab->aCol[0])*pTab->nCol );
  for(i=0, pCol=aCol; i<pTab->nCol; i++, pCol++){
    Expr *p, *pR;
    char *zType;
    char *zName;
    char *zBasename;
    CollSeq *pColl;
    int cnt;
    NameContext sNC;
    
    /* Get an appropriate name for the column
    */
    p = pEList->a[i].pExpr;







|







1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
  pTab->nCol = pEList->nExpr;
  assert( pTab->nCol>0 );
  pTab->aCol = aCol = sqliteMalloc( sizeof(pTab->aCol[0])*pTab->nCol );
  for(i=0, pCol=aCol; i<pTab->nCol; i++, pCol++){
    Expr *p, *pR;
    char *zType;
    char *zName;
    int nName;
    CollSeq *pColl;
    int cnt;
    NameContext sNC;
    
    /* Get an appropriate name for the column
    */
    p = pEList->a[i].pExpr;
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109

1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
      sqlite3DeleteTable(0, pTab);
      return 0;
    }

    /* Make sure the column name is unique.  If the name is not unique,
    ** append a integer to the name so that it becomes unique.
    */
    zBasename = zName;
    for(j=cnt=0; j<i; j++){
      if( sqlite3StrICmp(aCol[j].zName, zName)==0 ){

        zName = sqlite3MPrintf("%s:%d", zBasename, ++cnt);
        j = -1;
        if( zName==0 ) break;
      }
    }
    if( zBasename!=zName ){
      sqliteFree(zBasename);
    }
    pCol->zName = zName;

    /* Get the typename, type affinity, and collating sequence for the
    ** column.
    */
    memset(&sNC, 0, sizeof(sNC));
    sNC.pSrcList = pSelect->pSrc;







|


>
|




<
<
<







1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115



1116
1117
1118
1119
1120
1121
1122
      sqlite3DeleteTable(0, pTab);
      return 0;
    }

    /* Make sure the column name is unique.  If the name is not unique,
    ** append a integer to the name so that it becomes unique.
    */
    nName = strlen(zName);
    for(j=cnt=0; j<i; j++){
      if( sqlite3StrICmp(aCol[j].zName, zName)==0 ){
        zName[nName] = 0;
        zName = sqlite3MPrintf("%z:%d", zName, ++cnt);
        j = -1;
        if( zName==0 ) break;
      }
    }



    pCol->zName = zName;

    /* Get the typename, type affinity, and collating sequence for the
    ** column.
    */
    memset(&sNC, 0, sizeof(sNC));
    sNC.pSrcList = pSelect->pSrc;
Changes to test/misc2.test.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for miscellanous features that were
# left out of other test files.
#
# $Id: misc2.test,v 1.25 2006/08/16 16:42:48 drh Exp $

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

ifcapable {trigger} {
# Test for ticket #360
#







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for miscellanous features that were
# left out of other test files.
#
# $Id: misc2.test,v 1.26 2006/09/29 14:01:07 drh Exp $

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

ifcapable {trigger} {
# Test for ticket #360
#
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

59
60
61
62
63
64
65









66
67
68
69
70
71
72
  execsql {
    CREATE TABLE t1(a,b,c);
    INSERT INTO t1 VALUES(1,2,3);
    CREATE TABLE t2(a,b,c);
    INSERT INTO t2 VALUES(7,8,9);
  }
} {}
ifcapable view {
  ifcapable subquery {
    do_test misc2-2.2 {
      execsql {
        SELECT rowid, * FROM (SELECT * FROM t1, t2);
      }
    } {{} 1 2 3 7 8 9}
  }

  do_test misc2-2.3 {
    execsql {
      CREATE VIEW v1 AS SELECT * FROM t1, t2;
      SELECT rowid, * FROM v1;
    }
  } {{} 1 2 3 7 8 9}
} ;# ifcapable view










# Check name binding precedence.  Ticket #387
#
do_test misc2-3.1 {
  catchsql {
    SELECT t1.b+t2.b AS a, t1.a, t2.a FROM t1, t2 WHERE a==10
  }







<
|
|
|
|
|
|
|
>







>
>
>
>
>
>
>
>
>







44
45
46
47
48
49
50

51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
  execsql {
    CREATE TABLE t1(a,b,c);
    INSERT INTO t1 VALUES(1,2,3);
    CREATE TABLE t2(a,b,c);
    INSERT INTO t2 VALUES(7,8,9);
  }
} {}

ifcapable subquery {
  do_test misc2-2.2 {
    execsql {
      SELECT rowid, * FROM (SELECT * FROM t1, t2);
    }
  } {{} 1 2 3 7 8 9}
}
ifcapable view {
  do_test misc2-2.3 {
    execsql {
      CREATE VIEW v1 AS SELECT * FROM t1, t2;
      SELECT rowid, * FROM v1;
    }
  } {{} 1 2 3 7 8 9}
} ;# ifcapable view

# Ticket #2002 and #1952.
ifcapable subquery {
  do_test misc2-2.4 {
    execsql2 {
      SELECT * FROM (SELECT a, b AS 'a', c AS 'a', 4 AS 'a' FROM t1)
    }
  } {a 1 a:1 2 a:2 3 a:3 4}
}

# Check name binding precedence.  Ticket #387
#
do_test misc2-3.1 {
  catchsql {
    SELECT t1.b+t2.b AS a, t1.a, t2.a FROM t1, t2 WHERE a==10
  }