/ Check-in [e2558c34]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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 Side-by-Side Diffs Show Whitespace Changes Patch

Changes to src/table.c.

    14     14   ** interface routine of sqlite_exec().
    15     15   **
    16     16   ** These routines are in a separate files so that they will not be linked
    17     17   ** if they are not used.
    18     18   */
    19     19   #include <stdlib.h>
    20     20   #include <string.h>
    21         -#include "sqlite.h"
           21  +#include "sqliteInt.h"
    22     22   
    23     23   /*
    24     24   ** This structure is used to pass data from sqlite_get_table() through
    25     25   ** to the callback function is uses to build the result.
    26     26   */
    27     27   typedef struct TabResult {
    28     28     char **azResult;
           29  +  char *zErrMsg;
    29     30     int nResult;
    30     31     int nAlloc;
    31     32     int nRow;
    32     33     int nColumn;
    33     34     int nData;
    34     35     int rc;
    35     36   } TabResult;
................................................................................
    78     79             p->rc = SQLITE_NOMEM;
    79     80             return 1;
    80     81           }
    81     82           strcpy(z, colv[i]);
    82     83         }
    83     84         p->azResult[p->nData++] = z;
    84     85       }
           86  +  }else if( p->nColumn!=nCol ){
           87  +    sqliteSetString(&p->zErrMsg,
           88  +       "sqlite_get_table() called with two or more incompatible queries", 0);
           89  +    p->rc = SQLITE_ERROR;
           90  +    return 1;
    85     91     }
    86     92   
    87     93     /* Copy over the row data
    88     94     */
    89     95     if( argv!=0 ){
    90     96       for(i=0; i<nCol; i++){
    91     97         if( argv[i]==0 ){
................................................................................
   125    131   ){
   126    132     int rc;
   127    133     TabResult res;
   128    134     if( pazResult==0 ){ return SQLITE_ERROR; }
   129    135     *pazResult = 0;
   130    136     if( pnColumn ) *pnColumn = 0;
   131    137     if( pnRow ) *pnRow = 0;
          138  +  res.zErrMsg = 0;
   132    139     res.nResult = 0;
   133    140     res.nRow = 0;
   134    141     res.nColumn = 0;
   135    142     res.nData = 1;
   136    143     res.nAlloc = 20;
   137    144     res.rc = SQLITE_OK;
   138    145     res.azResult = malloc( sizeof(char*)*res.nAlloc );
................................................................................
   142    149     res.azResult[0] = 0;
   143    150     rc = sqlite_exec(db, zSql, sqlite_get_table_cb, &res, pzErrMsg);
   144    151     if( res.azResult ){
   145    152       res.azResult[0] = (char*)res.nData;
   146    153     }
   147    154     if( rc==SQLITE_ABORT ){
   148    155       sqlite_free_table(&res.azResult[1]);
          156  +    if( res.zErrMsg ){
          157  +      if( pzErrMsg ){
          158  +        free(*pzErrMsg);
          159  +        *pzErrMsg = res.zErrMsg;
          160  +        sqliteStrRealloc(pzErrMsg);
          161  +      }else{
          162  +        sqliteFree(res.zErrMsg);
          163  +      }
          164  +    }
   149    165       return res.rc;
   150    166     }
          167  +  sqliteFree(res.zErrMsg);
   151    168     if( rc!=SQLITE_OK ){
   152    169       sqlite_free_table(&res.azResult[1]);
   153    170       return rc;
   154    171     }
   155    172     if( res.nAlloc>res.nData ){
   156    173       char **azNew;
   157    174       azNew = realloc( res.azResult, sizeof(char*)*(res.nData+1) );

Changes to test/tableapi.test.

     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this file is testing the sqlite_exec_printf() and
    13     13   # sqlite_get_table_printf() APIs.
    14     14   #
    15         -# $Id: tableapi.test,v 1.4 2001/10/20 12:30:12 drh Exp $
           15  +# $Id: tableapi.test,v 1.5 2002/03/23 00:52:01 drh Exp $
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20     20   do_test tableapi-1.0 {
    21     21     set ::dbx [sqlite_open testdb]
    22     22     catch {sqlite_exec_printf $::dbx {DROP TABLE xyz} {}}
................................................................................
   140    140   } {0 3 2 a b 52 NULL 50 (50) 42 (42)}
   141    141   do_test tableapi-3.7 {
   142    142     sqlite_get_table_printf $::dbx {
   143    143       SELECT * FROM xyz WHERE a>1000
   144    144     } {}
   145    145   } {0 0 2 a b}
   146    146   
          147  +do_test tableapi-4.1 {
          148  +  set rc [catch {
          149  +    sqlite_get_table_printf $::dbx {
          150  +      SELECT * FROM xyz;  SELECT * FROM sqlite_master
          151  +    } {}
          152  +  } msg]
          153  +  concat $rc $msg
          154  +} {0 1 {sqlite_get_table() called with two or more incompatible queries}}
          155  +
   147    156   do_test tableapi-99.0 {
   148    157     sqlite_close $::dbx
   149    158   } {}
   150    159   
   151    160   finish_test

Changes to www/changes.tcl.

    16     16     puts "<DT><B>$date</B></DT>"
    17     17     puts "<DD><P><UL>$desc</UL></P></DD>"
    18     18   }
    19     19   
    20     20   chng {2002 Mar 122 (2.4.3)} {
    21     21   <li>Fix a bug in SELECT that occurs when a compound SELECT is used as a
    22     22       subquery in the FROM of a SELECT.</li>
           23  +<li>The <b>sqlite_get_table()</b> function now returns an error if you
           24  +    give it two or more SELECTs that return different numbers of columns.</li>
    23     25   }
    24     26   
    25     27   chng {2002 Mar 14 (2.4.2)} {
    26     28   <li>Bug fix: Fix an assertion failure that occurred when ROWID was a column
    27     29       in a SELECT statement on a view.</li>
    28     30   <li>Bug fix: Fix an uninitialized variable in the VDBE that would could an
    29     31       assert failure.</li>