Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix for ticket #136: Added the OP_RenameCursor VDBE instruction and used it to make cursor numbers right on nested subqueries. Also added OP_Gosub and OP_Return but have not actually used them for anything yet. (CVS 727) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
c602603e7cd8dc5c8bb9db2748eacab6 |
User & Date: | drh 2002-08-25 19:20:40.000 |
Context
2002-08-25
| ||
20:11 | Documentation updates prior to the releae of 2.7.0. (CVS 728) (check-in: e2d95f85a3 user: drh tags: trunk) | |
19:20 | Fix for ticket #136: Added the OP_RenameCursor VDBE instruction and used it to make cursor numbers right on nested subqueries. Also added OP_Gosub and OP_Return but have not actually used them for anything yet. (CVS 727) (check-in: c602603e7c user: drh tags: trunk) | |
18:29 | Fix the memory leak introduced by check-in (725). (CVS 726) (check-in: b957dafc26 user: drh tags: trunk) | |
Changes
Changes to src/select.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** ** $Id: select.c,v 1.110 2002/08/25 19:20:40 drh Exp $ */ #include "sqliteInt.h" /* ** Allocate a new Select structure and return a pointer to that ** structure. */ |
︙ | ︙ | |||
1399 1400 1401 1402 1403 1404 1405 | ** ** If flattening is not attempted, this routine is a no-op and return 0. ** If flattening is attempted this routine returns 1. ** ** All of the expression analysis must occur on both the outer query and ** the subquery before this routine runs. */ | | > > > > > > | 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 | ** ** If flattening is not attempted, this routine is a no-op and return 0. ** If flattening is attempted this routine returns 1. ** ** All of the expression analysis must occur on both the outer query and ** the subquery before this routine runs. */ static int flattenSubquery( Parse *pParse, /* The parsing context */ Select *p, /* The parent or outer SELECT statement */ int iFrom, /* Index in p->pSrc->a[] of the inner subquery */ int isAgg, /* True if outer SELECT uses aggregate functions */ int subqueryIsAgg /* True if the subquery uses aggregate functions */ ){ Select *pSub; /* The inner query or "subquery" */ SrcList *pSrc; /* The FROM clause of the outer query */ SrcList *pSubSrc; /* The FROM clause of the subquery */ ExprList *pList; /* The result set of the outer query */ int i; int iParent, iSub; Expr *pWhere; |
︙ | ︙ | |||
1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 | }else{ substExpr(p->pWhere, iParent, pSub->pEList, iSub); if( pWhere ){ p->pWhere = sqliteExpr(TK_AND, p->pWhere, pWhere, 0); } } p->isDistinct = p->isDistinct || pSub->isDistinct; if( pSub->nLimit>=0 ){ if( p->nLimit<0 ){ p->nLimit = pSub->nLimit; }else if( p->nLimit+p->nOffset > pSub->nLimit+pSub->nOffset ){ p->nLimit = pSub->nLimit + pSub->nOffset - p->nOffset; } } p->nOffset += pSub->nOffset; if( pSrc->a[iFrom].pTab && pSrc->a[iFrom].pTab->isTransient ){ sqliteDeleteTable(0, pSrc->a[iFrom].pTab); } pSrc->a[iFrom].pTab = pSubSrc->a[0].pTab; pSubSrc->a[0].pTab = 0; assert( pSrc->a[iFrom].pSelect==pSub ); pSrc->a[iFrom].pSelect = pSubSrc->a[0].pSelect; | > > > > > > > > > > > > > > > | 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 | }else{ substExpr(p->pWhere, iParent, pSub->pEList, iSub); if( pWhere ){ p->pWhere = sqliteExpr(TK_AND, p->pWhere, pWhere, 0); } } p->isDistinct = p->isDistinct || pSub->isDistinct; if( pSub->nLimit>=0 ){ if( p->nLimit<0 ){ p->nLimit = pSub->nLimit; }else if( p->nLimit+p->nOffset > pSub->nLimit+pSub->nOffset ){ p->nLimit = pSub->nLimit + pSub->nOffset - p->nOffset; } } p->nOffset += pSub->nOffset; /* If the subquery contains subqueries of its own, that were not ** flattened, then code will have already been generated to put ** the results of those sub-subqueries into VDBE cursors relative ** to the subquery. We must translate the cursor number into values ** suitable for use by the outer query. */ for(i=0; i<pSubSrc->nSrc; i++){ Vdbe *v; if( pSubSrc->a[i].pSelect==0 ) continue; v = sqliteGetVdbe(pParse); sqliteVdbeAddOp(v, OP_RenameCursor, pSub->base+i, p->base+i); } if( pSrc->a[iFrom].pTab && pSrc->a[iFrom].pTab->isTransient ){ sqliteDeleteTable(0, pSrc->a[iFrom].pTab); } pSrc->a[iFrom].pTab = pSubSrc->a[0].pTab; pSubSrc->a[0].pTab = 0; assert( pSrc->a[iFrom].pSelect==pSub ); pSrc->a[iFrom].pSelect = pSubSrc->a[0].pSelect; |
︙ | ︙ | |||
1879 1880 1881 1882 1883 1884 1885 | isDistinct = p->isDistinct; } /* Check to see if this is a subquery that can be "flattened" into its parent. ** If flattening is a possiblity, do so and return immediately. */ if( pParent && pParentAgg && | | | 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 | isDistinct = p->isDistinct; } /* Check to see if this is a subquery that can be "flattened" into its parent. ** If flattening is a possiblity, do so and return immediately. */ if( pParent && pParentAgg && flattenSubquery(pParse, pParent, parentTab, *pParentAgg, isAgg) ){ if( isAgg ) *pParentAgg = 1; return rc; } /* If the output is destined for a temporary table, open that table. */ if( eDest==SRT_TempTable ){ |
︙ | ︙ |
Changes to src/trigger.c.
︙ | ︙ | |||
16 17 18 19 20 21 22 | ** Delete a linked list of TriggerStep structures. */ static void sqliteDeleteTriggerStep(TriggerStep *pTriggerStep){ while( pTriggerStep ){ TriggerStep * pTmp = pTriggerStep; pTriggerStep = pTriggerStep->pNext; | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | ** Delete a linked list of TriggerStep structures. */ static void sqliteDeleteTriggerStep(TriggerStep *pTriggerStep){ while( pTriggerStep ){ TriggerStep * pTmp = pTriggerStep; pTriggerStep = pTriggerStep->pNext; if( pTmp->target.dyn ) sqliteFree((char*)pTmp->target.z); sqliteExprDelete(pTmp->pWhere); sqliteExprListDelete(pTmp->pExprList); sqliteSelectDelete(pTmp->pSelect); sqliteIdListDelete(pTmp->pIdList); sqliteFree(pTmp); } |
︙ | ︙ | |||
308 309 310 311 312 313 314 | return pTriggerStep; } /* ** Recursively delete a Trigger structure */ void sqliteDeleteTrigger(Trigger *pTrigger){ | < < | 308 309 310 311 312 313 314 315 316 317 318 319 320 321 | return pTriggerStep; } /* ** Recursively delete a Trigger structure */ void sqliteDeleteTrigger(Trigger *pTrigger){ sqliteDeleteTriggerStep(pTrigger->step_list); sqliteFree(pTrigger->name); sqliteFree(pTrigger->table); sqliteExprDelete(pTrigger->pWhen); sqliteIdListDelete(pTrigger->pColumns); sqliteFree(pTrigger); } |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
26 27 28 29 30 31 32 | ** type to the other occurs as necessary. ** ** Most of the code in this file is taken up by the sqliteVdbeExec() ** function which does the work of interpreting a VDBE program. ** But other routines are also provided to help in building up ** a program instruction by instruction. ** | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | ** type to the other occurs as necessary. ** ** Most of the code in this file is taken up by the sqliteVdbeExec() ** function which does the work of interpreting a VDBE program. ** But other routines are also provided to help in building up ** a program instruction by instruction. ** ** $Id: vdbe.c,v 1.171 2002/08/25 19:20:40 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** The following global variable is incremented every time a cursor ** moves, either by the OP_MoveTo or the OP_Next opcode. The test |
︙ | ︙ | |||
1063 1064 1065 1066 1067 1068 1069 | ** "opNames.awk" awk script which is part of the source tree to regenerate ** this array, then copy and paste it into this file, if you want. */ static char *zOpName[] = { 0, "Transaction", "Checkpoint", "Commit", "Rollback", "ReadCookie", "SetCookie", "VerifyCookie", "Open", "OpenTemp", "OpenWrite", "OpenAux", "OpenWrAux", | | | | | | | | | | | | | | | | | | > | | | | | | | | | | | | | 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 | ** "opNames.awk" awk script which is part of the source tree to regenerate ** this array, then copy and paste it into this file, if you want. */ static char *zOpName[] = { 0, "Transaction", "Checkpoint", "Commit", "Rollback", "ReadCookie", "SetCookie", "VerifyCookie", "Open", "OpenTemp", "OpenWrite", "OpenAux", "OpenWrAux", "RenameCursor", "Close", "MoveTo", "NewRecno", "PutIntKey", "PutStrKey", "Distinct", "Found", "NotFound", "IsUnique", "NotExists", "Delete", "Column", "KeyAsData", "Recno", "FullKey", "NullRow", "Last", "Rewind", "Next", "Destroy", "Clear", "CreateIndex", "CreateTable", "IntegrityCk", "IdxPut", "IdxDelete", "IdxRecno", "IdxGT", "IdxGE", "MemLoad", "MemStore", "MemIncr", "ListWrite", "ListRewind", "ListRead", "ListReset", "ListPush", "ListPop", "SortPut", "SortMakeRec", "SortMakeKey", "Sort", "SortNext", "SortCallback", "SortReset", "FileOpen", "FileRead", "FileColumn", "AggReset", "AggFocus", "AggNext", "AggSet", "AggGet", "AggFunc", "AggInit", "AggPush", "AggPop", "SetInsert", "SetFound", "SetNotFound", "SetFirst", "SetNext", "MakeRecord", "MakeKey", "MakeIdxKey", "IncrKey", "Goto", "If", "IfNot", "Halt", "Gosub", "Return", "ColumnCount", "ColumnName", "Callback", "NullCallback", "Integer", "String", "Pop", "Dup", "Pull", "Push", "MustBeInt", "Add", "AddImm", "Subtract", "Multiply", "Divide", "Remainder", "BitAnd", "BitOr", "BitNot", "ShiftLeft", "ShiftRight", "AbsValue", "Eq", "Ne", "Lt", "Le", "Gt", "Ge", "StrEq", "StrNe", "StrLt", "StrLe", "StrGt", "StrGe", "IsNull", "NotNull", "Negative", "And", "Or", "Not", "Concat", "Noop", "Function", }; /* ** Given the name of an opcode, return its number. Return 0 if ** there is no match. ** ** This routine is used for testing and debugging. |
︙ | ︙ | |||
1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 | } if( pOut==0 ) pOut = stdout; fprintf(pOut,"%4d %-12s %4d %4d %s\n", pc, zOpName[pOp->opcode], pOp->p1, pOp->p2, zP3 ? zP3 : ""); fflush(pOut); } #endif /* ** Execute the program in the VDBE. ** ** If an error occurs, an error message is written to memory obtained ** from sqliteMalloc() and *pzErrMsg is made to point to that memory. ** The return parameter is the number of errors. | > > > > > > > > > > > > > > > > > > > | 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 | } if( pOut==0 ) pOut = stdout; fprintf(pOut,"%4d %-12s %4d %4d %s\n", pc, zOpName[pOp->opcode], pOp->p1, pOp->p2, zP3 ? zP3 : ""); fflush(pOut); } #endif /* ** Make sure there is space in the Vdbe structure to hold at least ** mxCursor cursors. If there is not currently enough space, then ** allocate more. ** ** If a memory allocation error occurs, return 1. Return 0 if ** everything works. */ static int expandCursorArraySize(Vdbe *p, int mxCursor){ if( mxCursor>=p->nCursor ){ Cursor *aCsr = sqliteRealloc( p->aCsr, (mxCursor+1)*sizeof(Cursor) ); if( aCsr==0 ) return 1; p->aCsr = aCsr; memset(&p->aCsr[p->nCursor], 0, sizeof(Cursor)*(mxCursor+1-p->nCursor)); p->nCursor = mxCursor+1; } return 0; } /* ** Execute the program in the VDBE. ** ** If an error occurs, an error message is written to memory obtained ** from sqliteMalloc() and *pzErrMsg is made to point to that memory. ** The return parameter is the number of errors. |
︙ | ︙ | |||
1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 | sqlite *db = p->db; /* The database */ char **zStack; /* Text stack */ Stack *aStack; /* Additional stack information */ unsigned uniqueCnt = 0; /* Used by OP_MakeRecord when P2!=0 */ int errorAction = OE_Abort; /* Recovery action to do in case of an error */ int undoTransOnError = 0; /* If error, either ROLLBACK or COMMIT */ char zBuf[100]; /* Space to sprintf() an integer */ /* No instruction ever pushes more than a single element onto the ** stack. And the stack never grows on successive executions of the ** same loop. So the total number of instructions is an upper bound ** on the maximum stack depth required. ** | > > | 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 | sqlite *db = p->db; /* The database */ char **zStack; /* Text stack */ Stack *aStack; /* Additional stack information */ unsigned uniqueCnt = 0; /* Used by OP_MakeRecord when P2!=0 */ int errorAction = OE_Abort; /* Recovery action to do in case of an error */ int undoTransOnError = 0; /* If error, either ROLLBACK or COMMIT */ char zBuf[100]; /* Space to sprintf() an integer */ int returnStack[100]; /* Return address stack for OP_Gosub & OP_Return */ int returnDepth = 0; /* Next unused element in returnStack[] */ /* No instruction ever pushes more than a single element onto the ** stack. And the stack never grows on successive executions of the ** same loop. So the total number of instructions is an upper bound ** on the maximum stack depth required. ** |
︙ | ︙ | |||
1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 | ** the one at index P2 from the beginning of ** the program. */ case OP_Goto: { pc = pOp->p2 - 1; break; } /* Opcode: Halt P1 P2 * ** ** Exit immediately. All open cursors, Lists, Sorts, etc are closed ** automatically. ** ** P1 is the result code returned by sqlite_exec(). For a normal | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 | ** the one at index P2 from the beginning of ** the program. */ case OP_Goto: { pc = pOp->p2 - 1; break; } /* Opcode: Gosub * P2 * ** ** Push the current address plus 1 onto the return address stack ** and then jump to address P2. ** ** The return address stack is of limited depth. If too many ** OP_Gosub operations occur without intervening OP_Returns, then ** the return address stack will fill up and processing will abort ** with a fatal error. */ case OP_Gosub: { if( returnDepth>=sizeof(returnStack)/sizeof(returnStack[0]) ){ sqliteSetString(pzErrMsg, "return address stack overflow", 0); rc = SQLITE_INTERNAL; goto cleanup; } returnStack[returnDepth++] = pc+1; pc = pOp->p2 - 1; break; } /* Opcode: Return * * * ** ** Jump immediately to the next instruction after the last unreturned ** OP_Gosub. If an OP_Return has occurred for all OP_Gosubs, then ** processing aborts with a fatal error. */ case OP_Return: { if( returnDepth<=0 ){ sqliteSetString(pzErrMsg, "return address stack underflow", 0); rc = SQLITE_INTERNAL; goto cleanup; } returnDepth--; pc = returnStack[returnDepth] - 1; break; } /* Opcode: Halt P1 P2 * ** ** Exit immediately. All open cursors, Lists, Sorts, etc are closed ** automatically. ** ** P1 is the result code returned by sqlite_exec(). For a normal |
︙ | ︙ | |||
3101 3102 3103 3104 3105 3106 3107 | if( p2<2 ){ sqliteSetString(pzErrMsg, "root page number less than 2", 0); rc = SQLITE_INTERNAL; goto cleanup; } } VERIFY( if( i<0 ) goto bad_instruction; ) | < < < | < < < < < < | 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 | if( p2<2 ){ sqliteSetString(pzErrMsg, "root page number less than 2", 0); rc = SQLITE_INTERNAL; goto cleanup; } } VERIFY( if( i<0 ) goto bad_instruction; ) if( expandCursorArraySize(p, i) ) goto no_mem; cleanupCursor(&p->aCsr[i]); memset(&p->aCsr[i], 0, sizeof(Cursor)); p->aCsr[i].nullRow = 1; if( pX==0 ) break; do{ rc = sqliteBtreeCursor(pX, p2, wrFlag, &p->aCsr[i].pCursor); switch( rc ){ |
︙ | ︙ | |||
3159 3160 3161 3162 3163 3164 3165 | ** whereas "Temporary" in the context of CREATE TABLE means for the duration ** of the connection to the database. Same word; different meanings. */ case OP_OpenTemp: { int i = pOp->p1; Cursor *pCx; VERIFY( if( i<0 ) goto bad_instruction; ) | < < < | < < < < < < | 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 | ** whereas "Temporary" in the context of CREATE TABLE means for the duration ** of the connection to the database. Same word; different meanings. */ case OP_OpenTemp: { int i = pOp->p1; Cursor *pCx; VERIFY( if( i<0 ) goto bad_instruction; ) if( expandCursorArraySize(p, i) ) goto no_mem; pCx = &p->aCsr[i]; cleanupCursor(pCx); memset(pCx, 0, sizeof(*pCx)); pCx->nullRow = 1; rc = sqliteBtreeOpen(0, 0, TEMP_PAGES, &pCx->pBt); if( rc==SQLITE_OK ){ rc = sqliteBtreeBeginTrans(pCx->pBt); |
︙ | ︙ | |||
3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 | } }else{ rc = sqliteBtreeCursor(pCx->pBt, 2, 1, &pCx->pCursor); } } break; } /* Opcode: Close P1 * * ** ** Close a cursor previously opened as P1. If P1 is not ** currently open, this instruction is a no-op. */ case OP_Close: { | > > > > > > > > > > > > > > > > > > > > > | 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 | } }else{ rc = sqliteBtreeCursor(pCx->pBt, 2, 1, &pCx->pCursor); } } break; } /* ** Opcode: RenameCursor P1 P2 * ** ** Rename cursor number P1 as cursor number P2. If P2 was previously ** opened is is closed before the renaming occurs. */ case OP_RenameCursor: { int from = pOp->p1; int to = pOp->p2; VERIFY( if( from<0 || to<0 ) goto bad_instruction; ) if( to<p->nCursor && p->aCsr[to].pCursor ){ cleanupCursor(&p->aCsr[to]); } expandCursorArraySize(p, to); if( from<p->nCursor ){ memcpy(&p->aCsr[to], &p->aCsr[from], sizeof(p->aCsr[0])); memset(&p->aCsr[from], 0, sizeof(p->aCsr[0])); } break; } /* Opcode: Close P1 * * ** ** Close a cursor previously opened as P1. If P1 is not ** currently open, this instruction is a no-op. */ case OP_Close: { |
︙ | ︙ |
Changes to src/vdbe.h.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** Header file for the Virtual DataBase Engine (VDBE) ** ** This header defines the interface to the virtual database engine ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** Header file for the Virtual DataBase Engine (VDBE) ** ** This header defines the interface to the virtual database engine ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** ** $Id: vdbe.h,v 1.58 2002/08/25 19:20:42 drh Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ #include <stdio.h> /* ** A single VDBE is an opaque structure named "Vdbe". Only routines |
︙ | ︙ | |||
78 79 80 81 82 83 84 | #define OP_VerifyCookie 7 #define OP_Open 8 #define OP_OpenTemp 9 #define OP_OpenWrite 10 #define OP_OpenAux 11 #define OP_OpenWrAux 12 | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | #define OP_VerifyCookie 7 #define OP_Open 8 #define OP_OpenTemp 9 #define OP_OpenWrite 10 #define OP_OpenAux 11 #define OP_OpenWrAux 12 #define OP_RenameCursor 13 #define OP_Close 14 #define OP_MoveTo 15 #define OP_NewRecno 16 #define OP_PutIntKey 17 #define OP_PutStrKey 18 #define OP_Distinct 19 #define OP_Found 20 #define OP_NotFound 21 #define OP_IsUnique 22 #define OP_NotExists 23 #define OP_Delete 24 #define OP_Column 25 #define OP_KeyAsData 26 #define OP_Recno 27 #define OP_FullKey 28 #define OP_NullRow 29 #define OP_Last 30 #define OP_Rewind 31 #define OP_Next 32 #define OP_Destroy 33 #define OP_Clear 34 #define OP_CreateIndex 35 #define OP_CreateTable 36 #define OP_IntegrityCk 37 #define OP_IdxPut 38 #define OP_IdxDelete 39 #define OP_IdxRecno 40 #define OP_IdxGT 41 #define OP_IdxGE 42 #define OP_MemLoad 43 #define OP_MemStore 44 #define OP_MemIncr 45 #define OP_ListWrite 46 #define OP_ListRewind 47 #define OP_ListRead 48 #define OP_ListReset 49 #define OP_ListPush 50 #define OP_ListPop 51 #define OP_SortPut 52 #define OP_SortMakeRec 53 #define OP_SortMakeKey 54 #define OP_Sort 55 #define OP_SortNext 56 #define OP_SortCallback 57 #define OP_SortReset 58 #define OP_FileOpen 59 #define OP_FileRead 60 #define OP_FileColumn 61 #define OP_AggReset 62 #define OP_AggFocus 63 #define OP_AggNext 64 #define OP_AggSet 65 #define OP_AggGet 66 #define OP_AggFunc 67 #define OP_AggInit 68 #define OP_AggPush 69 #define OP_AggPop 70 #define OP_SetInsert 71 #define OP_SetFound 72 #define OP_SetNotFound 73 #define OP_SetFirst 74 #define OP_SetNext 75 #define OP_MakeRecord 76 #define OP_MakeKey 77 #define OP_MakeIdxKey 78 #define OP_IncrKey 79 #define OP_Goto 80 #define OP_If 81 #define OP_IfNot 82 #define OP_Halt 83 #define OP_Gosub 84 #define OP_Return 85 #define OP_ColumnCount 86 #define OP_ColumnName 87 #define OP_Callback 88 #define OP_NullCallback 89 #define OP_Integer 90 #define OP_String 91 #define OP_Pop 92 #define OP_Dup 93 #define OP_Pull 94 #define OP_Push 95 #define OP_MustBeInt 96 #define OP_Add 97 #define OP_AddImm 98 #define OP_Subtract 99 #define OP_Multiply 100 #define OP_Divide 101 #define OP_Remainder 102 #define OP_BitAnd 103 #define OP_BitOr 104 #define OP_BitNot 105 #define OP_ShiftLeft 106 #define OP_ShiftRight 107 #define OP_AbsValue 108 /***** IMPORTANT NOTE: The code generator assumes that OP_XX+6==OP_StrXX *****/ #define OP_Eq 109 #define OP_Ne 110 #define OP_Lt 111 #define OP_Le 112 #define OP_Gt 113 #define OP_Ge 114 #define OP_StrEq 115 #define OP_StrNe 116 #define OP_StrLt 117 #define OP_StrLe 118 #define OP_StrGt 119 #define OP_StrGe 120 /***** IMPORTANT NOTE: the code generator assumes that OP_XX+6==OP_StrXX *****/ #define OP_IsNull 121 #define OP_NotNull 122 #define OP_Negative 123 #define OP_And 124 #define OP_Or 125 #define OP_Not 126 #define OP_Concat 127 #define OP_Noop 128 #define OP_Function 129 #define OP_MAX 129 /* ** Prototypes for the VDBE interface. See comments on the implementation ** for a description of what each of these routines does. */ Vdbe *sqliteVdbeCreate(sqlite*); void sqliteVdbeCreateCallback(Vdbe*, int*); |
︙ | ︙ |
Changes to test/view.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2002 February 26 # # 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 implements regression tests for SQLite library. The # focus of this file is testing VIEW statements. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2002 February 26 # # 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 implements regression tests for SQLite library. The # focus of this file is testing VIEW statements. # # $Id: view.test,v 1.11 2002/08/25 19:20:43 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl do_test view-1.0 { execsql { CREATE TABLE t1(a,b,c); INSERT INTO t1 VALUES(1,2,3); |
︙ | ︙ | |||
280 281 282 283 284 285 286 | } {7 2 13 5 19 8 27 12} do_test view-8.3 { execsql { CREATE VIEW v7 AS SELECT pqr+xyz AS a FROM v6; SELECT * FROM v7 ORDER BY a; } } {9 18 27 39} | < | | > > > | > | 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 | } {7 2 13 5 19 8 27 12} do_test view-8.3 { execsql { CREATE VIEW v7 AS SELECT pqr+xyz AS a FROM v6; SELECT * FROM v7 ORDER BY a; } } {9 18 27 39} do_test view-8.4 { execsql { CREATE VIEW v8 AS SELECT max(cnt) AS mx FROM (SELECT a%2 AS eo, count(*) AS cnt FROM t1 GROUP BY eo); SELECT * FROM v8; } } 3 do_test view-8.5 { execsql { SELECT mx+10, mx*2 FROM v8; } } {13 6} finish_test |