/ Check-in [e2558c34]
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 | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: e2558c34034cf49524084ec819df58934a8af983
User & Date: drh 2002-03-23 00:52:01
Context
2002-03-23
01:00
Version 2.4.3 (CVS 440) check-in: 99d6764e 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: e2558c34 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: aaf7fd4c user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Show Whitespace Changes 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
..
78
79
80
81
82
83
84





85
86
87
88
89
90
91
...
125
126
127
128
129
130
131

132
133
134
135
136
137
138
...
142
143
144
145
146
147
148









149
150

151
152
153
154
155
156
157
** 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"

/*
** 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;

  int nResult;
  int nAlloc;
  int nRow;
  int nColumn;
  int nData;
  int rc;
} TabResult;
................................................................................
          p->rc = SQLITE_NOMEM;
          return 1;
        }
        strcpy(z, colv[i]);
      }
      p->azResult[p->nData++] = z;
    }





  }

  /* Copy over the row data
  */
  if( argv!=0 ){
    for(i=0; i<nCol; i++){
      if( argv[i]==0 ){
................................................................................
){
  int rc;
  TabResult res;
  if( pazResult==0 ){ return SQLITE_ERROR; }
  *pazResult = 0;
  if( pnColumn ) *pnColumn = 0;
  if( pnRow ) *pnRow = 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 );
................................................................................
  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]);









    return res.rc;
  }

  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) );







|







>







 







>
>
>
>
>







 







>







 







>
>
>
>
>
>
>
>
>


>







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
..
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
...
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
...
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
** 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 "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;
................................................................................
          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 ){
................................................................................
){
  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 );
................................................................................
  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
...
140
141
142
143
144
145
146









147
148
149
150
151
#    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 $

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} {}}
................................................................................
} {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-99.0 {
  sqlite_close $::dbx
} {}

finish_test







|







 







>
>
>
>
>
>
>
>
>





8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#    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.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} {}}
................................................................................
} {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
  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>


}

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>







>
>







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>