-C Towards\sgetting\sINSERT\sstatements\sto\sexcept\smany\sVALUE\sterms\s(more\sthan\nthe\slimit\simposed\sby\sSQLITE_LIMIT_COMPOUND_SELECT).\s\sThis\scheck-in\ssegfaults\non\sa\sstack\soverflow.\s\sAnd\sit\sis\sslow.
-D 2015-01-05T16:27:43.075
+C Handle\scompound-select\sstatements\soriginating\sfrom\sVALUES\sclauses\sas\sa\nspecial\scase\sthat\sdoes\snot\suse\srecursion.
+D 2015-01-05T19:16:42.892
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 335e2d3ff0f2455eacbfa3075fc37495e3321410
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/os_win.h 09e751b20bbc107ffbd46e13555dc73576d88e21
F src/pager.c 4120a49ecd37697e28f5ed807f470b9c0b88410c
F src/pager.h c3476e7c89cdf1c6914e50a11f3714e30b4e0a77
-F src/parse.y 075cad65e0393df1362b87e5cd766220b880f3a7
+F src/parse.y c5d0d964f9ac023e8154cad512e54b0b6058e086
F src/pcache.c b83d160ce81ca101f98f0d27498e6d6bd49f1599
F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8
F src/pcache1.c 1e77432b40b7d3288327d9cdf399dcdfd2b6d3bf
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
F src/resolve.c f6c46d3434439ab2084618d603e6d6dbeb0d6ada
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
-F src/select.c 28cf616a8791ff154be86bd9a3f888440f618e78
+F src/select.c 4776e16d19296f0f93ecd9431dca8bc3e3182714
F src/shell.c 45d9c9bd7cde07845af957f2d849933b990773cf
F src/sqlite.h.in ed799ff5c814227c7957eb4f4a217f67fdc0da48
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
-F src/sqliteInt.h 3e0079855cb7b3c85dffac5bcbb1cd712ac62e65
+F src/sqliteInt.h 5d5716d8b33a61606c6ee10112f4b6df56f42725
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 81712116e826b0089bb221b018929536b2b5406f
F src/table.c e7a09215315a978057fb42c640f890160dbcc45e
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P fe677d13f03e24fa667efc0c2e7f5bbb99521791
-R 54acf3852000e5cc7341ca33524e221b
-T *branch * many-VALUEs
-T *sym-many-VALUEs *
-T -sym-trunk *
+P c9d65f739ad56f016c676e79aa39080be3fe868a
+R 382474f6cec467234b3ff04ac38978b4
U drh
-Z 9fc3f9e17e26a0964cf77234a16c2176
+Z 33ab3e676dc0271c6784ea259fd00ed6
-c9d65f739ad56f016c676e79aa39080be3fe868a
\ No newline at end of file
+9ce9e43af38e6bc362734463d4bfc40ff0c98f8f
\ No newline at end of file
int cnt = 0, mxSelect;
p->pWith = W;
if( p->pPrior ){
+ u16 allValues = SF_Values;
pNext = 0;
for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){
pLoop->pNext = pNext;
pLoop->selFlags |= SF_Compound;
+ allValues &= pLoop->selFlags;
}
- if( (p->selFlags & SF_Values)==0
- && (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0
- && cnt>mxSelect
+ if( allValues ){
+ p->selFlags |= SF_AllValues;
+ }else if(
+ (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0
+ && cnt>mxSelect
){
sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
}
SelectDest *pDest /* What to do with query results */
);
+/*
+** Error message for when two or more terms of a compound select have different
+** size result sets.
+*/
+static void selectWrongNumTermsError(Parse *pParse, Select *p){
+ if( p->selFlags & SF_Values ){
+ sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms");
+ }else{
+ sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
+ " do not have the same number of result columns", selectOpName(p->op));
+ }
+}
+
+/*
+** Handle the special case of a compound-select that originates from a
+** VALUES clause. By handling this as a special case, we avoid deep
+** recursion, and thus do not need to enforce the SQLITE_LIMIT_COMPOUND_SELECT
+** on a VALUES clause.
+**
+** Because the Select object originates from a VALUES clause:
+** (1) It has no LIMIT or OFFSET
+** (2) All terms are UNION ALL
+** (3) There is no ORDER BY clause
+*/
+static int multiSelectValues(
+ Parse *pParse, /* Parsing context */
+ Select *p, /* The right-most of SELECTs to be coded */
+ SelectDest *pDest /* What to do with query results */
+){
+ Select *pPrior;
+ int nExpr = p->pEList->nExpr;
+ int nRow = 1;
+ int rc = 0;
+ assert( p->pNext==0 );
+ assert( p->selFlags & SF_AllValues );
+ do{
+ assert( p->selFlags & SF_Values );
+ assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
+ assert( p->pLimit==0 );
+ assert( p->pOffset==0 );
+ if( p->pEList->nExpr!=nExpr ){
+ selectWrongNumTermsError(pParse, p);
+ return 1;
+ }
+ if( p->pPrior==0 ) break;
+ assert( p->pPrior->pNext==p );
+ p = p->pPrior;
+ nRow++;
+ }while(1);
+ while( p ){
+ pPrior = p->pPrior;
+ p->pPrior = 0;
+ rc = sqlite3Select(pParse, p, pDest);
+ p->pPrior = pPrior;
+ if( rc ) break;
+ p->nSelectRow = nRow;
+ p = p->pNext;
+ }
+ return rc;
+}
/*
** This routine is called to process a compound query form from
dest.eDest = SRT_Table;
}
+ /* Special handling for a compound-select that originates as a VALUES clause.
+ */
+ if( p->selFlags & SF_AllValues ){
+ rc = multiSelectValues(pParse, p, &dest);
+ goto multi_select_end;
+ }
+
/* Make sure all SELECTs in the statement have the same number of elements
** in their result sets.
*/
assert( p->pEList && pPrior->pEList );
if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
- if( p->selFlags & SF_Values ){
- sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms");
- }else{
- sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
- " do not have the same number of result columns", selectOpName(p->op));
- }
+ selectWrongNumTermsError(pParse, p);
rc = 1;
goto multi_select_end;
}
#define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
#define SF_Compound 0x0040 /* Part of a compound query */
#define SF_Values 0x0080 /* Synthesized from VALUES clause */
- /* 0x0100 NOT USED */
+#define SF_AllValues 0x0100 /* All terms of compound are VALUES */
#define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */
#define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */
#define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */