1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-08 03:22:21 +03:00

When expanding '*' in the result set of a SELECT, quote the expanded identifiers. Fix for #2450. (CVS 4111)

FossilOrigin-Name: d5b7224f37db1729dd042d48765d7a79247e1bde
This commit is contained in:
danielk1977
2007-06-24 06:32:17 +00:00
parent 53b4bd3252
commit f3b863ed07
5 changed files with 88 additions and 17 deletions

View File

@@ -1,5 +1,5 @@
C fix\slinking\sfailure\son\sOS/2\sthat\shappens\swith\sthe\samalgamation\sand\sthe\shigh\smemory\soption\senabled\s(CVS\s4110) C When\sexpanding\s'*'\sin\sthe\sresult\sset\sof\sa\sSELECT,\squote\sthe\sexpanded\sidentifiers.\sFix\sfor\s#2450.\s(CVS\s4111)
D 2007-06-22T20:17:38 D 2007-06-24T06:32:18
F Makefile.in 7f7485a4cc039476a42e534b3f26ec90e2f9753e F Makefile.in 7f7485a4cc039476a42e534b3f26ec90e2f9753e
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -101,9 +101,9 @@ F src/pager.h 94110a5570dca30d54a883e880a3633b2e4c05ae
F src/parse.y ad2ce25665be7f7303137f774a4e3e72e0d036ff F src/parse.y ad2ce25665be7f7303137f774a4e3e72e0d036ff
F src/pragma.c 0d25dad58bdfd6789943a10f1b9663c2eb85b96d F src/pragma.c 0d25dad58bdfd6789943a10f1b9663c2eb85b96d
F src/prepare.c 87c23644986b5e41a58bc76f05abebd899e00089 F src/prepare.c 87c23644986b5e41a58bc76f05abebd899e00089
F src/printf.c deaef57ea97557b8b53313d5c793fa4236036a0e F src/printf.c 9b3048d270e8bb2f8b910b491ac3aadece6cfab2
F src/random.c 6119474a6f6917f708c1dee25b9a8e519a620e88 F src/random.c 6119474a6f6917f708c1dee25b9a8e519a620e88
F src/select.c 33a258fc9c9dccb28ae2d3a02f1e1148d6433148 F src/select.c 2ee53f929fe3755a35de1fb937f22e2e60f7d3e5
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
F src/shell.c 4b0fc3c76a9f23a1c963e01703c0fbbca1b5c34d F src/shell.c 4b0fc3c76a9f23a1c963e01703c0fbbca1b5c34d
F src/sqlite.h.in 6f290b660b2e7c3359968bb4b344ec31a1178746 F src/sqlite.h.in 6f290b660b2e7c3359968bb4b344ec31a1178746
@@ -396,6 +396,7 @@ F test/tkt2332.test cb1bb0ed1ae6a3b9ff412520ed4a496745f4ffa5
F test/tkt2339.test 7016415bda86af1406a27260ac46f44885617606 F test/tkt2339.test 7016415bda86af1406a27260ac46f44885617606
F test/tkt2391.test ab7a11be7402da8b51a5be603425367aa0684567 F test/tkt2391.test ab7a11be7402da8b51a5be603425367aa0684567
F test/tkt2409.test f130054aedff681883466ad04332bd3f7db51a02 F test/tkt2409.test f130054aedff681883466ad04332bd3f7db51a02
F test/tkt2450.test 77ed94863f2049c1420288ddfea2d41e5e0971d6
F test/trace.test 75ffc1b992c780d054748a656e3e7fd674f18567 F test/trace.test 75ffc1b992c780d054748a656e3e7fd674f18567
F test/trans.test 9e6e7b886ea8093239801b5af0981ff784d9c541 F test/trans.test 9e6e7b886ea8093239801b5af0981ff784d9c541
F test/trigger1.test b361161cf20614024cc1e52ea0bdec250776b2ae F test/trigger1.test b361161cf20614024cc1e52ea0bdec250776b2ae
@@ -512,7 +513,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
P 12327ca049e62922bfb3c2a14e42554fd58265e8 P f35e20e19633d7b114fdf145820ca5d61b5aa925
R c4f5686bdc00846759c01fbdffa7f82b R 0028662710d587da4e5d82de686d252d
U pweilbacher U danielk1977
Z bbe405d266119d64ef43df21e50d3180 Z 13d4831b99a0601e7fdfc2a1c76b4c67

View File

@@ -1 +1 @@
f35e20e19633d7b114fdf145820ca5d61b5aa925 d5b7224f37db1729dd042d48765d7a79247e1bde

View File

@@ -74,6 +74,7 @@
#define etTOKEN 13 /* a pointer to a Token structure */ #define etTOKEN 13 /* a pointer to a Token structure */
#define etSRCLIST 14 /* a pointer to a SrcList */ #define etSRCLIST 14 /* a pointer to a SrcList */
#define etPOINTER 15 /* The %p conversion */ #define etPOINTER 15 /* The %p conversion */
#define etSQLESCAPE3 16 /* %w -> Strings with '\"' doubled */
/* /*
@@ -115,6 +116,7 @@ static const et_info fmtinfo[] = {
{ 'z', 0, 6, etDYNSTRING, 0, 0 }, { 'z', 0, 6, etDYNSTRING, 0, 0 },
{ 'q', 0, 4, etSQLESCAPE, 0, 0 }, { 'q', 0, 4, etSQLESCAPE, 0, 0 },
{ 'Q', 0, 4, etSQLESCAPE2, 0, 0 }, { 'Q', 0, 4, etSQLESCAPE2, 0, 0 },
{ 'w', 0, 4, etSQLESCAPE3, 0, 0 },
{ 'c', 0, 0, etCHARX, 0, 0 }, { 'c', 0, 0, etCHARX, 0, 0 },
{ 'o', 8, 0, etRADIX, 0, 2 }, { 'o', 8, 0, etRADIX, 0, 2 },
{ 'u', 10, 0, etRADIX, 0, 0 }, { 'u', 10, 0, etRADIX, 0, 0 },
@@ -611,14 +613,16 @@ static int vxprintf(
if( precision>=0 && precision<length ) length = precision; if( precision>=0 && precision<length ) length = precision;
break; break;
case etSQLESCAPE: case etSQLESCAPE:
case etSQLESCAPE2: { case etSQLESCAPE2:
case etSQLESCAPE3: {
int i, j, n, ch, isnull; int i, j, n, ch, isnull;
int needQuote; int needQuote;
char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote character */
char *escarg = va_arg(ap,char*); char *escarg = va_arg(ap,char*);
isnull = escarg==0; isnull = escarg==0;
if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)"); if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
for(i=n=0; (ch=escarg[i])!=0; i++){ for(i=n=0; (ch=escarg[i])!=0; i++){
if( ch=='\'' ) n++; if( ch==q ) n++;
} }
needQuote = !isnull && xtype==etSQLESCAPE2; needQuote = !isnull && xtype==etSQLESCAPE2;
n += i + 1 + needQuote*2; n += i + 1 + needQuote*2;
@@ -629,12 +633,12 @@ static int vxprintf(
bufpt = buf; bufpt = buf;
} }
j = 0; j = 0;
if( needQuote ) bufpt[j++] = '\''; if( needQuote ) bufpt[j++] = q;
for(i=0; (ch=escarg[i])!=0; i++){ for(i=0; (ch=escarg[i])!=0; i++){
bufpt[j++] = ch; bufpt[j++] = ch;
if( ch=='\'' ) bufpt[j++] = ch; if( ch==q ) bufpt[j++] = ch;
} }
if( needQuote ) bufpt[j++] = '\''; if( needQuote ) bufpt[j++] = q;
bufpt[j] = 0; bufpt[j] = 0;
length = j; length = j;
/* The precision is ignored on %q and %Q */ /* The precision is ignored on %q and %Q */

View File

@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser ** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite. ** to handle SELECT statements in SQLite.
** **
** $Id: select.c,v 1.351 2007/06/15 15:31:50 drh Exp $ ** $Id: select.c,v 1.352 2007/06/24 06:32:18 danielk1977 Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -185,6 +185,20 @@ static void setToken(Token *p, const char *z){
p->dyn = 0; p->dyn = 0;
} }
/*
** 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(Token *p, const char *z){
p->z = (u8 *)sqlite3MPrintf("\"%w\"", z);
p->dyn = 1;
if( p->z ){
p->n = strlen((char *)p->z);
}
}
/* /*
** Create an expression node for an identifier with the name of zName ** Create an expression node for an identifier with the name of zName
*/ */
@@ -1336,12 +1350,12 @@ static int prepSelectStmt(Parse *pParse, Select *p){
} }
pRight = sqlite3Expr(TK_ID, 0, 0, 0); pRight = sqlite3Expr(TK_ID, 0, 0, 0);
if( pRight==0 ) break; if( pRight==0 ) break;
setToken(&pRight->token, zName); setQuotedToken(&pRight->token, zName);
if( zTabName && (longNames || pTabList->nSrc>1) ){ if( zTabName && (longNames || pTabList->nSrc>1) ){
Expr *pLeft = sqlite3Expr(TK_ID, 0, 0, 0); Expr *pLeft = sqlite3Expr(TK_ID, 0, 0, 0);
pExpr = sqlite3Expr(TK_DOT, pLeft, pRight, 0); pExpr = sqlite3Expr(TK_DOT, pLeft, pRight, 0);
if( pExpr==0 ) break; if( pExpr==0 ) break;
setToken(&pLeft->token, zTabName); setQuotedToken(&pLeft->token, zTabName);
setToken(&pExpr->span, sqlite3MPrintf("%s.%s", zTabName, zName)); setToken(&pExpr->span, sqlite3MPrintf("%s.%s", zTabName, zName));
pExpr->span.dyn = 1; pExpr->span.dyn = 1;
pExpr->token.z = 0; pExpr->token.z = 0;
@@ -1350,6 +1364,7 @@ static int prepSelectStmt(Parse *pParse, Select *p){
}else{ }else{
pExpr = pRight; pExpr = pRight;
pExpr->span = pExpr->token; pExpr->span = pExpr->token;
pExpr->span.dyn = 0;
} }
if( longNames ){ if( longNames ){
pNew = sqlite3ExprListAppend(pNew, pExpr, &pExpr->span); pNew = sqlite3ExprListAppend(pNew, pExpr, &pExpr->span);
@@ -1376,6 +1391,9 @@ static int prepSelectStmt(Parse *pParse, Select *p){
sqlite3ErrorMsg(pParse, "too many columns in result set"); sqlite3ErrorMsg(pParse, "too many columns in result set");
rc = SQLITE_ERROR; rc = SQLITE_ERROR;
} }
if( sqlite3MallocFailed() ){
rc = SQLITE_NOMEM;
}
return rc; return rc;
} }

48
test/tkt2450.test Normal file
View File

@@ -0,0 +1,48 @@
# 2007 June 24
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file is to test that ticket #2450 has been fixed.
#
# $Id: tkt2450.test,v 1.1 2007/06/24 06:32:18 danielk1977 Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
do_test tkt2450-1 {
execsql {
CREATE TABLE "t a" ("""cb""");
INSERT INTO "t a" ("""cb""") VALUES (1);
SELECT """cb""" FROM "t a";
}
} {1}
do_test tkt2450-2 {
execsql {
SELECT * FROM "t a";
}
} {1}
do_test tkt2450-3 {
execsql {
SELECT "t a".* FROM "t a";
}
} {1}
do_test tkt2450-3 {
execsql {
CREATE TABLE t1(a);
INSERT INTO t1 VALUES(2);
SELECT * FROM "t a", t1;
}
} {1 2}
finish_test