SQLite

Check-in [e2558c3403]
Login

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

Overview
Comment:The sqlite_get_table() function now returns an error if you pass in two or more SELECT statements that return different numbers of columns. (CVS 436)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: e2558c34034cf49524084ec819df58934a8af983
User & Date: drh 2002-03-23 00:52:01.000
Context
2002-03-23
01:00
Version 2.4.3 (CVS 440) (check-in: 99d6764e57 user: drh tags: trunk)
00:52
The sqlite_get_table() function now returns an error if you pass in two or more SELECT statements that return different numbers of columns. (CVS 436) (check-in: e2558c3403 user: drh tags: trunk)
00:31
Fix a bug in subquery generation when the subquery is a compound select. Also added new tests to cover this case. (CVS 435) (check-in: aaf7fd4cef user: drh tags: trunk)
Changes
Side-by-Side Diff Ignore Whitespace Patch
Changes to src/table.c.
14
15
16
17
18
19
20
21

22
23
24
25
26
27
28

29
30
31
32
33
34
35
14
15
16
17
18
19
20

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36







-
+







+







** interface routine of sqlite_exec().
**
** These routines are in a separate files so that they will not be linked
** if they are not used.
*/
#include <stdlib.h>
#include <string.h>
#include "sqlite.h"
#include "sqliteInt.h"

/*
** This structure is used to pass data from sqlite_get_table() through
** to the callback function is uses to build the result.
*/
typedef struct TabResult {
  char **azResult;
  char *zErrMsg;
  int nResult;
  int nAlloc;
  int nRow;
  int nColumn;
  int nData;
  int rc;
} TabResult;
78
79
80
81
82
83
84





85
86
87
88
89
90
91
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97







+
+
+
+
+







          p->rc = SQLITE_NOMEM;
          return 1;
        }
        strcpy(z, colv[i]);
      }
      p->azResult[p->nData++] = z;
    }
  }else if( p->nColumn!=nCol ){
    sqliteSetString(&p->zErrMsg,
       "sqlite_get_table() called with two or more incompatible queries", 0);
    p->rc = SQLITE_ERROR;
    return 1;
  }

  /* Copy over the row data
  */
  if( argv!=0 ){
    for(i=0; i<nCol; i++){
      if( argv[i]==0 ){
125
126
127
128
129
130
131

132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148









149
150

151
152
153
154
155
156
157
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174







+

















+
+
+
+
+
+
+
+
+


+







){
  int rc;
  TabResult res;
  if( pazResult==0 ){ return SQLITE_ERROR; }
  *pazResult = 0;
  if( pnColumn ) *pnColumn = 0;
  if( pnRow ) *pnRow = 0;
  res.zErrMsg = 0;
  res.nResult = 0;
  res.nRow = 0;
  res.nColumn = 0;
  res.nData = 1;
  res.nAlloc = 20;
  res.rc = SQLITE_OK;
  res.azResult = malloc( sizeof(char*)*res.nAlloc );
  if( res.azResult==0 ){
    return SQLITE_NOMEM;
  }
  res.azResult[0] = 0;
  rc = sqlite_exec(db, zSql, sqlite_get_table_cb, &res, pzErrMsg);
  if( res.azResult ){
    res.azResult[0] = (char*)res.nData;
  }
  if( rc==SQLITE_ABORT ){
    sqlite_free_table(&res.azResult[1]);
    if( res.zErrMsg ){
      if( pzErrMsg ){
        free(*pzErrMsg);
        *pzErrMsg = res.zErrMsg;
        sqliteStrRealloc(pzErrMsg);
      }else{
        sqliteFree(res.zErrMsg);
      }
    }
    return res.rc;
  }
  sqliteFree(res.zErrMsg);
  if( rc!=SQLITE_OK ){
    sqlite_free_table(&res.azResult[1]);
    return rc;
  }
  if( res.nAlloc>res.nData ){
    char **azNew;
    azNew = realloc( res.azResult, sizeof(char*)*(res.nData+1) );
Changes to test/tableapi.test.
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22







-
+







#    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 sqlite_exec_printf() and
# sqlite_get_table_printf() APIs.
#
# $Id: tableapi.test,v 1.4 2001/10/20 12:30:12 drh Exp $
# $Id: tableapi.test,v 1.5 2002/03/23 00:52:01 drh Exp $

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

do_test tableapi-1.0 {
  set ::dbx [sqlite_open testdb]
  catch {sqlite_exec_printf $::dbx {DROP TABLE xyz} {}}
140
141
142
143
144
145
146









147
148
149
150
151
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160







+
+
+
+
+
+
+
+
+





} {0 3 2 a b 52 NULL 50 (50) 42 (42)}
do_test tableapi-3.7 {
  sqlite_get_table_printf $::dbx {
    SELECT * FROM xyz WHERE a>1000
  } {}
} {0 0 2 a b}

do_test tableapi-4.1 {
  set rc [catch {
    sqlite_get_table_printf $::dbx {
      SELECT * FROM xyz;  SELECT * FROM sqlite_master
    } {}
  } msg]
  concat $rc $msg
} {0 1 {sqlite_get_table() called with two or more incompatible queries}}

do_test tableapi-99.0 {
  sqlite_close $::dbx
} {}

finish_test
Changes to www/changes.tcl.
16
17
18
19
20
21
22


23
24
25
26
27
28
29
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31







+
+







  puts "<DT><B>$date</B></DT>"
  puts "<DD><P><UL>$desc</UL></P></DD>"
}

chng {2002 Mar 122 (2.4.3)} {
<li>Fix a bug in SELECT that occurs when a compound SELECT is used as a
    subquery in the FROM of a SELECT.</li>
<li>The <b>sqlite_get_table()</b> function now returns an error if you
    give it two or more SELECTs that return different numbers of columns.</li>
}

chng {2002 Mar 14 (2.4.2)} {
<li>Bug fix: Fix an assertion failure that occurred when ROWID was a column
    in a SELECT statement on a view.</li>
<li>Bug fix: Fix an uninitialized variable in the VDBE that would could an
    assert failure.</li>