mirror of https://github.com/sqlite/sqlite
Do vector comparison size checking early - at name resolution time - to
forestall future problems. FossilOrigin-Name: ae127bcc0a5827786853f47b229021435d6098d7
This commit is contained in:
commit
083aefc732
27
manifest
27
manifest
|
@ -1,5 +1,5 @@
|
|||
C Fix\sa\scrash\sthat\scould\soccur\sunder\scertain\scircumstances\sif\sthe\svectors\son\seither\sside\sof\sa\scomparison\soperator\swere\sof\sa\sdifferent\ssize.
|
||||
D 2016-09-05T09:44:45.878
|
||||
C Do\svector\scomparison\ssize\schecking\searly\s-\sat\sname\sresolution\stime\s-\sto\nforestall\sfuture\sproblems.
|
||||
D 2016-09-05T12:12:56.221
|
||||
F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c
|
||||
|
@ -338,7 +338,7 @@ F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7
|
|||
F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b
|
||||
F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d
|
||||
F src/delete.c 76c084f0265f4a3cd1ecf17eee112a94f1ccbc05
|
||||
F src/expr.c 750ed16649d655fef117c6d983c7382acd625bfd
|
||||
F src/expr.c 942c417e84e835ce51c6b732afa0b4572110e1c1
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c e2be0968c1adc679c87e467aa5b4f167588f38a8
|
||||
F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771
|
||||
|
@ -383,14 +383,14 @@ F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c
|
|||
F src/prepare.c 0fcf16eaacc90c1059055519a76b75b516a59a88
|
||||
F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1
|
||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||
F src/resolve.c d67b9a5cc33339256e2088c5a722745fc2ff5219
|
||||
F src/resolve.c 24f40fd0c3475821d1ad762a3f2c3455cc839b42
|
||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||
F src/select.c 38216d0b2d42a0f475abf86a84c3499e6421ba29
|
||||
F src/shell.c 79dda477be6c96eba6e952a934957ad36f87acc7
|
||||
F src/sqlite.h.in 4a030e254e204570444b34bf7d40fb4a5416089e
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae
|
||||
F src/sqliteInt.h e7afbfaa4033a4c1cf2aa7bbdd0eb27e4663ab3a
|
||||
F src/sqliteInt.h c9e010a79ab4ed7bdc910a24d8f08f3c6d5f822c
|
||||
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
|
||||
F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
|
||||
F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9
|
||||
|
@ -468,7 +468,7 @@ F src/walker.c 2d2cc7fb0f320f7f415215d7247f3c584141ac09
|
|||
F src/where.c 48d705e5196a0611a7be90698eade455ee238536
|
||||
F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613
|
||||
F src/wherecode.c 8a9a53cb52dd8a75e07c85e3bc12c1604c735954
|
||||
F src/whereexpr.c 571597ac8d761505f626e597884b2a03494053cd
|
||||
F src/whereexpr.c c5ec87e234faf62ac2d4e7f7ce18fb1f4bd475ff
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
|
@ -1020,10 +1020,10 @@ F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a
|
|||
F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc
|
||||
F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
|
||||
F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d
|
||||
F test/rowvalue.test 7d8482dde9023973615eaaca65647f33d70c1f01
|
||||
F test/rowvalue.test 753eb744b7efeb5ac643d35d6e1e5066452ccf79
|
||||
F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b
|
||||
F test/rowvalue3.test 01399b7bf150b0d41abce76c18072da777c2500c
|
||||
F test/rowvalue4.test 29494f1c66e73329d90027619ee6d22e7ffe0ebf
|
||||
F test/rowvalue4.test 4b556d7de161a0dd8cff095c336e913986398bea
|
||||
F test/rowvalue5.test a440d490c8c0bf606034c09d5c6bbf7840b98f95
|
||||
F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087
|
||||
F test/rowvalue7.test 5d06ff19d9e6969e574a2e662a531dd0c67801a8
|
||||
|
@ -1121,7 +1121,7 @@ F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1
|
|||
F test/stmt.test 64844332db69cf1a735fcb3e11548557fc95392f
|
||||
F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f
|
||||
F test/subquery2.test 438f8a7da1457277b22e4176510f7659b286995f
|
||||
F test/subselect.test ccec43f85d488c6c4b6f98ea2dfa95b6086871c0
|
||||
F test/subselect.test 0966aa8e720224dbd6a5e769a3ec2a723e332303
|
||||
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
|
||||
F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8
|
||||
F test/superlock.test ec94f0556b6488d97f71c79f9061ae08d9ab8f12
|
||||
|
@ -1522,7 +1522,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 7d9bd22c0715ede2592ee1fa7ebc215aded1ca1b
|
||||
R 26e65ef1f9dc6647fee64756ced37096
|
||||
U dan
|
||||
Z c125d50595ea7cb48721a8bf5a5398c8
|
||||
P 42670935aba152ba774c2a8bdcbe72b943309d68 56562a0346170cf7b72445976864b058437a8ac3
|
||||
R 9ea9c6d7e55a2e73634a9a6491229b09
|
||||
T +closed 56562a0346170cf7b72445976864b058437a8ac3
|
||||
U drh
|
||||
Z c545a18fc0ce61b83efad3cc467f4a6a
|
||||
|
|
|
@ -1 +1 @@
|
|||
42670935aba152ba774c2a8bdcbe72b943309d68
|
||||
ae127bcc0a5827786853f47b229021435d6098d7
|
139
src/expr.c
139
src/expr.c
|
@ -521,71 +521,69 @@ static void codeVectorCompare(
|
|||
Vdbe *v = pParse->pVdbe;
|
||||
Expr *pLeft = pExpr->pLeft;
|
||||
Expr *pRight = pExpr->pRight;
|
||||
int nLeft = sqlite3ExprVectorSize(pLeft);
|
||||
int i;
|
||||
int regLeft = 0;
|
||||
int regRight = 0;
|
||||
u8 opx = op;
|
||||
int addrDone = sqlite3VdbeMakeLabel(v);
|
||||
|
||||
if( sqlite3ExprCheckComparison(pParse, pLeft, pRight)==0 ){
|
||||
int nLeft = sqlite3ExprVectorSize(pLeft);
|
||||
int i;
|
||||
int regLeft = 0;
|
||||
int regRight = 0;
|
||||
u8 opx = op;
|
||||
int addrDone = sqlite3VdbeMakeLabel(v);
|
||||
assert( nLeft==sqlite3ExprVectorSize(pRight) );
|
||||
assert( pExpr->op==TK_EQ || pExpr->op==TK_NE
|
||||
|| pExpr->op==TK_IS || pExpr->op==TK_ISNOT
|
||||
|| pExpr->op==TK_LT || pExpr->op==TK_GT
|
||||
|| pExpr->op==TK_LE || pExpr->op==TK_GE
|
||||
);
|
||||
assert( pExpr->op==op || (pExpr->op==TK_IS && op==TK_EQ)
|
||||
|| (pExpr->op==TK_ISNOT && op==TK_NE) );
|
||||
assert( p5==0 || pExpr->op!=op );
|
||||
assert( p5==SQLITE_NULLEQ || pExpr->op==op );
|
||||
|
||||
assert( pExpr->op==TK_EQ || pExpr->op==TK_NE
|
||||
|| pExpr->op==TK_IS || pExpr->op==TK_ISNOT
|
||||
|| pExpr->op==TK_LT || pExpr->op==TK_GT
|
||||
|| pExpr->op==TK_LE || pExpr->op==TK_GE
|
||||
);
|
||||
assert( pExpr->op==op || (pExpr->op==TK_IS && op==TK_EQ)
|
||||
|| (pExpr->op==TK_ISNOT && op==TK_NE) );
|
||||
assert( p5==0 || pExpr->op!=op );
|
||||
assert( p5==SQLITE_NULLEQ || pExpr->op==op );
|
||||
p5 |= SQLITE_STOREP2;
|
||||
if( opx==TK_LE ) opx = TK_LT;
|
||||
if( opx==TK_GE ) opx = TK_GT;
|
||||
|
||||
p5 |= SQLITE_STOREP2;
|
||||
if( opx==TK_LE ) opx = TK_LT;
|
||||
if( opx==TK_GE ) opx = TK_GT;
|
||||
regLeft = exprCodeSubselect(pParse, pLeft);
|
||||
regRight = exprCodeSubselect(pParse, pRight);
|
||||
|
||||
regLeft = exprCodeSubselect(pParse, pLeft);
|
||||
regRight = exprCodeSubselect(pParse, pRight);
|
||||
|
||||
for(i=0; 1 /*Loop exits by "break"*/; i++){
|
||||
int regFree1 = 0, regFree2 = 0;
|
||||
Expr *pL, *pR;
|
||||
int r1, r2;
|
||||
assert( i>=0 && i<nLeft );
|
||||
if( i>0 ) sqlite3ExprCachePush(pParse);
|
||||
r1 = exprVectorRegister(pParse, pLeft, i, regLeft, &pL, ®Free1);
|
||||
r2 = exprVectorRegister(pParse, pRight, i, regRight, &pR, ®Free2);
|
||||
codeCompare(pParse, pL, pR, opx, r1, r2, dest, p5);
|
||||
testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
|
||||
testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
|
||||
testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
|
||||
testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
|
||||
testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
|
||||
testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
|
||||
sqlite3ReleaseTempReg(pParse, regFree1);
|
||||
sqlite3ReleaseTempReg(pParse, regFree2);
|
||||
if( i>0 ) sqlite3ExprCachePop(pParse);
|
||||
if( i==nLeft-1 ){
|
||||
break;
|
||||
}
|
||||
if( opx==TK_EQ ){
|
||||
sqlite3VdbeAddOp2(v, OP_IfNot, dest, addrDone); VdbeCoverage(v);
|
||||
p5 |= SQLITE_KEEPNULL;
|
||||
}else if( opx==TK_NE ){
|
||||
sqlite3VdbeAddOp2(v, OP_If, dest, addrDone); VdbeCoverage(v);
|
||||
p5 |= SQLITE_KEEPNULL;
|
||||
}else{
|
||||
assert( op==TK_LT || op==TK_GT || op==TK_LE || op==TK_GE );
|
||||
sqlite3VdbeAddOp2(v, OP_ElseNotEq, 0, addrDone);
|
||||
VdbeCoverageIf(v, op==TK_LT);
|
||||
VdbeCoverageIf(v, op==TK_GT);
|
||||
VdbeCoverageIf(v, op==TK_LE);
|
||||
VdbeCoverageIf(v, op==TK_GE);
|
||||
if( i==nLeft-2 ) opx = op;
|
||||
}
|
||||
for(i=0; 1 /*Loop exits by "break"*/; i++){
|
||||
int regFree1 = 0, regFree2 = 0;
|
||||
Expr *pL, *pR;
|
||||
int r1, r2;
|
||||
assert( i>=0 && i<nLeft );
|
||||
if( i>0 ) sqlite3ExprCachePush(pParse);
|
||||
r1 = exprVectorRegister(pParse, pLeft, i, regLeft, &pL, ®Free1);
|
||||
r2 = exprVectorRegister(pParse, pRight, i, regRight, &pR, ®Free2);
|
||||
codeCompare(pParse, pL, pR, opx, r1, r2, dest, p5);
|
||||
testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
|
||||
testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
|
||||
testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
|
||||
testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
|
||||
testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
|
||||
testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
|
||||
sqlite3ReleaseTempReg(pParse, regFree1);
|
||||
sqlite3ReleaseTempReg(pParse, regFree2);
|
||||
if( i>0 ) sqlite3ExprCachePop(pParse);
|
||||
if( i==nLeft-1 ){
|
||||
break;
|
||||
}
|
||||
if( opx==TK_EQ ){
|
||||
sqlite3VdbeAddOp2(v, OP_IfNot, dest, addrDone); VdbeCoverage(v);
|
||||
p5 |= SQLITE_KEEPNULL;
|
||||
}else if( opx==TK_NE ){
|
||||
sqlite3VdbeAddOp2(v, OP_If, dest, addrDone); VdbeCoverage(v);
|
||||
p5 |= SQLITE_KEEPNULL;
|
||||
}else{
|
||||
assert( op==TK_LT || op==TK_GT || op==TK_LE || op==TK_GE );
|
||||
sqlite3VdbeAddOp2(v, OP_ElseNotEq, 0, addrDone);
|
||||
VdbeCoverageIf(v, op==TK_LT);
|
||||
VdbeCoverageIf(v, op==TK_GT);
|
||||
VdbeCoverageIf(v, op==TK_LE);
|
||||
VdbeCoverageIf(v, op==TK_GE);
|
||||
if( i==nLeft-2 ) opx = op;
|
||||
}
|
||||
sqlite3VdbeResolveLabel(v, addrDone);
|
||||
}
|
||||
sqlite3VdbeResolveLabel(v, addrDone);
|
||||
}
|
||||
|
||||
#if SQLITE_MAX_EXPR_DEPTH>0
|
||||
|
@ -2651,29 +2649,6 @@ int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Expressions pLeft and pRight are the left and right sides of a comparison
|
||||
** operator. If either pLeft or pRight is a vector and the other is not, or
|
||||
** if they are both vectors but of a different size, leave an error message
|
||||
** in the Parse object and return non-zero. Or, if there is no problem,
|
||||
** return 0.
|
||||
*/
|
||||
int sqlite3ExprCheckComparison(Parse *pParse, Expr *pLeft, Expr *pRight){
|
||||
int nLeft = sqlite3ExprVectorSize(pLeft);
|
||||
int nRight = sqlite3ExprVectorSize(pRight);
|
||||
if( nLeft!=nRight ){
|
||||
if( (pRight->flags & EP_xIsSelect) ){
|
||||
sqlite3SubselectError(pParse, nRight, nLeft);
|
||||
}else if( pLeft->flags & EP_xIsSelect ){
|
||||
sqlite3SubselectError(pParse, nLeft, nRight);
|
||||
}else{
|
||||
sqlite3ErrorMsg(pParse, "row value misused");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_SUBQUERY
|
||||
/*
|
||||
** Generate code for an IN expression.
|
||||
|
|
|
@ -776,6 +776,33 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
|||
notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr);
|
||||
break;
|
||||
}
|
||||
case TK_EQ:
|
||||
case TK_NE:
|
||||
case TK_LT:
|
||||
case TK_LE:
|
||||
case TK_GT:
|
||||
case TK_GE:
|
||||
case TK_IS:
|
||||
case TK_ISNOT: {
|
||||
int nLeft, nRight;
|
||||
if( pParse->db->mallocFailed ) break;
|
||||
assert( pExpr->pRight!=0 );
|
||||
assert( pExpr->pLeft!=0 );
|
||||
nLeft = sqlite3ExprVectorSize(pExpr->pLeft);
|
||||
nRight = sqlite3ExprVectorSize(pExpr->pRight);
|
||||
if( nLeft!=nRight ){
|
||||
testcase( pExpr->op==TK_EQ );
|
||||
testcase( pExpr->op==TK_NE );
|
||||
testcase( pExpr->op==TK_LT );
|
||||
testcase( pExpr->op==TK_LE );
|
||||
testcase( pExpr->op==TK_GT );
|
||||
testcase( pExpr->op==TK_GE );
|
||||
testcase( pExpr->op==TK_IS );
|
||||
testcase( pExpr->op==TK_ISNOT );
|
||||
sqlite3ErrorMsg(pParse, "row value misused");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue;
|
||||
}
|
||||
|
|
|
@ -4009,7 +4009,6 @@ int sqlite3ExprCheckIN(Parse*, Expr*);
|
|||
#else
|
||||
# define sqlite3ExprCheckIN(x,y) SQLITE_OK
|
||||
#endif
|
||||
int sqlite3ExprCheckComparison(Parse*, Expr*, Expr*);
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
void sqlite3AnalyzeFunctions(void);
|
||||
|
|
|
@ -952,10 +952,6 @@ static void exprAnalyze(
|
|||
Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
|
||||
u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV;
|
||||
|
||||
if( pRight && sqlite3ExprCheckComparison(pParse, pLeft, pRight) ){
|
||||
return;
|
||||
}
|
||||
|
||||
if( pTerm->iField>0 ){
|
||||
assert( op==TK_IN );
|
||||
assert( pLeft->op==TK_VECTOR );
|
||||
|
@ -1192,22 +1188,21 @@ static void exprAnalyze(
|
|||
|| (pExpr->pRight->flags & EP_xIsSelect)==0
|
||||
)){
|
||||
int nLeft = sqlite3ExprVectorSize(pExpr->pLeft);
|
||||
if( nLeft==sqlite3ExprVectorSize(pExpr->pRight) ){
|
||||
int i;
|
||||
for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){
|
||||
int idxNew;
|
||||
Expr *pNew;
|
||||
Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i);
|
||||
Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i);
|
||||
int i;
|
||||
assert( nLeft==sqlite3ExprVectorSize(pExpr->pRight) );
|
||||
for(i=0; i<nLeft; i++){
|
||||
int idxNew;
|
||||
Expr *pNew;
|
||||
Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i);
|
||||
Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i);
|
||||
|
||||
pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight, 0);
|
||||
idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC);
|
||||
exprAnalyze(pSrc, pWC, idxNew);
|
||||
}
|
||||
pTerm = &pWC->a[idxTerm];
|
||||
pTerm->wtFlags = TERM_CODED|TERM_VIRTUAL; /* Disable the original */
|
||||
pTerm->eOperator = 0;
|
||||
pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight, 0);
|
||||
idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC);
|
||||
exprAnalyze(pSrc, pWC, idxNew);
|
||||
}
|
||||
pTerm = &pWC->a[idxTerm];
|
||||
pTerm->wtFlags = TERM_CODED|TERM_VIRTUAL; /* Disable the original */
|
||||
pTerm->eOperator = 0;
|
||||
}
|
||||
|
||||
/* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create
|
||||
|
|
|
@ -229,4 +229,31 @@ do_execsql_test 10.0 {
|
|||
AND (a,b,e) IN (SELECT 'a','b','d' FROM dual);
|
||||
}
|
||||
|
||||
do_catchsql_test 11.1 {
|
||||
CREATE TABLE t11(a);
|
||||
SELECT * FROM t11 WHERE (a,a)<=1;
|
||||
} {1 {row value misused}}
|
||||
do_catchsql_test 11.2 {
|
||||
SELECT * FROM t11 WHERE (a,a)<1;
|
||||
} {1 {row value misused}}
|
||||
do_catchsql_test 11.3 {
|
||||
SELECT * FROM t11 WHERE (a,a)>=1;
|
||||
} {1 {row value misused}}
|
||||
do_catchsql_test 11.4 {
|
||||
SELECT * FROM t11 WHERE (a,a)>1;
|
||||
} {1 {row value misused}}
|
||||
do_catchsql_test 11.5 {
|
||||
SELECT * FROM t11 WHERE (a,a)==1;
|
||||
} {1 {row value misused}}
|
||||
do_catchsql_test 11.6 {
|
||||
SELECT * FROM t11 WHERE (a,a)<>1;
|
||||
} {1 {row value misused}}
|
||||
do_catchsql_test 11.7 {
|
||||
SELECT * FROM t11 WHERE (a,a) IS 1;
|
||||
} {1 {row value misused}}
|
||||
do_catchsql_test 11.8 {
|
||||
SELECT * FROM t11 WHERE (a,a) IS NOT 1;
|
||||
} {1 {row value misused}}
|
||||
|
||||
|
||||
finish_test
|
||||
|
|
|
@ -308,6 +308,6 @@ do_catchsql_test 8.2 {
|
|||
SELECT * FROM c2 CROSS JOIN c3 WHERE
|
||||
( (a, b) == (SELECT x, y FROM c1) AND c3.d = c ) OR
|
||||
( c == (SELECT x, y FROM c1) AND c3.d = c )
|
||||
} {1 {sub-select returns 2 columns - expected 1}}
|
||||
} {1 {row value misused}}
|
||||
|
||||
finish_test
|
||||
|
|
|
@ -40,7 +40,7 @@ do_test subselect-1.1 {
|
|||
do_test subselect-1.2 {
|
||||
set v [catch {execsql {SELECT * FROM t1 WHERE a = (SELECT * FROM t1)}} msg]
|
||||
lappend v $msg
|
||||
} {1 {sub-select returns 2 columns - expected 1}}
|
||||
} {1 {row value misused}}
|
||||
|
||||
# A subselect without an aggregate.
|
||||
#
|
||||
|
|
Loading…
Reference in New Issue