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

When the sqlite3WindowRewrite() routine detects and error, have it convert

the SELECT statement into just "SELECT null" so that it does not leave the
parse tree in a goofy state that can cause problems with subsequent code
before the stack has a chance to unwind and report the error.
Ticket [d87336c81c7d0873]

FossilOrigin-Name: fa58aad48a788802b13a819e49f9b8787f713bbe395c46c7295e821c52c81738
This commit is contained in:
drh
2019-12-25 23:54:21 +00:00
parent b44fec68a5
commit a9ebfe2030
7 changed files with 60 additions and 22 deletions

View File

@@ -594,6 +594,7 @@ static void codeVectorCompare(
int addrDone = sqlite3VdbeMakeLabel(pParse);
int isCommuted = ExprHasProperty(pExpr,EP_Commuted);
if( pParse->nErr ) return;
if( nLeft!=sqlite3ExprVectorSize(pRight) ){
sqlite3ErrorMsg(pParse, "row value misused");
return;
@@ -2686,8 +2687,10 @@ static char *exprINAffinity(Parse *pParse, Expr *pExpr){
** "sub-select returns N columns - expected M"
*/
void sqlite3SubselectError(Parse *pParse, int nActual, int nExpect){
const char *zFmt = "sub-select returns %d columns - expected %d";
sqlite3ErrorMsg(pParse, zFmt, nActual, nExpect);
if( pParse->nErr==0 ){
const char *zFmt = "sub-select returns %d columns - expected %d";
sqlite3ErrorMsg(pParse, zFmt, nActual, nExpect);
}
}
#endif

View File

@@ -84,7 +84,10 @@ struct SortCtx {
/*
** Delete all the content of a Select structure. Deallocate the structure
** itself only if bFree is true.
** itself depending on the value of bFree
**
** If bFree==1, call sqlite3DbFree() on the p object.
** If bFree==0, Leave the first Select object unfreed
*/
static void clearSelect(sqlite3 *db, Select *p, int bFree){
while( p ){
@@ -188,6 +191,20 @@ void sqlite3SelectDelete(sqlite3 *db, Select *p){
if( OK_IF_ALWAYS_TRUE(p) ) clearSelect(db, p, 1);
}
/*
** Delete all the substructure for p, but keep p allocated. Redefine
** p to be a single SELECT where every column of the result set has a
** value of NULL.
*/
void sqlite3SelectReset(Parse *pParse, Select *p){
if( ALWAYS(p) ){
clearSelect(pParse->db, p, 0);
memset(&p->iLimit, 0, sizeof(Select) - offsetof(Select,iLimit));
p->pEList = sqlite3ExprListAppend(pParse, 0,
sqlite3ExprAlloc(pParse->db,TK_NULL,0,0));
}
}
/*
** Return a pointer to the right-most SELECT statement in a compound.
*/
@@ -2711,9 +2728,9 @@ static int multiSelect(
** it is that we currently need.
*/
assert( unionTab==dest.iSDParm || dest.eDest!=priorOp );
if( dest.eDest!=priorOp ){
assert( p->pEList || db->mallocFailed );
if( dest.eDest!=priorOp && db->mallocFailed==0 ){
int iCont, iBreak, iStart;
assert( p->pEList );
iBreak = sqlite3VdbeMakeLabel(pParse);
iCont = sqlite3VdbeMakeLabel(pParse);
computeLimitRegisters(pParse, p, iBreak);
@@ -5738,7 +5755,9 @@ int sqlite3Select(
}
#ifndef SQLITE_OMIT_WINDOWFUNC
if( sqlite3WindowRewrite(pParse, p) ){
rc = sqlite3WindowRewrite(pParse, p);
if( rc ){
assert( pParse->nErr>0 );
goto select_end;
}
#if SELECTTRACE_ENABLED

View File

@@ -2918,13 +2918,13 @@ struct Upsert {
** sequences for the ORDER BY clause.
*/
struct Select {
ExprList *pEList; /* The fields of the result */
u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
LogEst nSelectRow; /* Estimated number of result rows */
u32 selFlags; /* Various SF_* values */
int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */
u32 selId; /* Unique identifier number for this SELECT */
int addrOpenEphm[2]; /* OP_OpenEphem opcodes related to this select */
ExprList *pEList; /* The fields of the result */
SrcList *pSrc; /* The FROM clause */
Expr *pWhere; /* The WHERE clause */
ExprList *pGroupBy; /* The GROUP BY clause */
@@ -4092,6 +4092,7 @@ int sqlite3Select(Parse*, Select*, SelectDest*);
Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
Expr*,ExprList*,u32,Expr*);
void sqlite3SelectDelete(sqlite3*, Select*);
void sqlite3SelectReset(Parse*, Select*);
Table *sqlite3SrcListLookup(Parse*, SrcList*);
int sqlite3IsReadOnly(Parse*, Table*, int);
void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);

View File

@@ -1021,6 +1021,9 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
pSub->selFlags |= SF_Expanded;
pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE);
if( pTab2==0 ){
/* Might actually be some other kind of error, but in that case
** pParse->nErr will be set, so if SQLITE_NOMEM is set, we will get
** the correct error message regardless. */
rc = SQLITE_NOMEM;
}else{
memcpy(pTab, pTab2, sizeof(Table));
@@ -1039,9 +1042,12 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
sqlite3DbFree(db, pTab);
}
if( rc && pParse->nErr==0 ){
assert( pParse->db->mallocFailed );
return sqlite3ErrorToParser(pParse->db, SQLITE_NOMEM);
if( rc ){
if( pParse->nErr==0 ){
assert( pParse->db->mallocFailed );
sqlite3ErrorToParser(pParse->db, SQLITE_NOMEM);
}
sqlite3SelectReset(pParse, p);
}
return rc;
}