Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add the "CREATE INDEX idx ON tbl USING nm(...)" syntax. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
8ac71062f53c96ddbf9b513da5799b9f |
User & Date: | dan 2012-12-19 20:01:06.214 |
Context
2012-12-20
| ||
18:41 | Add "tokenizer=xxx" syntax to fts5. check-in: e0748900db user: dan tags: trunk | |
2012-12-19
| ||
20:01 | Add the "CREATE INDEX idx ON tbl USING nm(...)" syntax. check-in: 8ac71062f5 user: dan tags: trunk | |
2012-12-18
| ||
15:47 | Add support for NEAR to the fts expression parser. check-in: b1a2a17679 user: dan tags: trunk | |
Changes
Changes to src/build.c.
︙ | |||
2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 | 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | sqlite4VdbeAddOp2(v, OP_Next, iTab, addr1+1); sqlite4VdbeJumpHere(v, addr1); sqlite4ReleaseTempReg(pParse, regKey); sqlite4VdbeAddOp1(v, OP_Close, iTab); sqlite4VdbeAddOp1(v, OP_Close, iIdx); } /* ** The CreateIndex structure indicated by the first argument contains the ** results of parsing the first part of a CREATE INDEX statement. ** Specifically, everything up to and including the "ON tblname" clause. ** The index may be an ordinary index, or it may be a "USING fts5" index. ** This function performs processing common to both. */ static Table *createIndexFindTable( Parse *pParse, /* Parsing context */ CreateIndex *p, /* First part of CREATE INDEX statement */ Token **ppIdxName, /* OUT: Pointer to index name token */ char **pzIdxName, /* OUT: DbMalloc'd copy of index name */ int *piDb /* OUT: Database to create index in */ ){ DbFixer sFix; /* For assigning database names to pTblName */ sqlite4 *db = pParse->db; /* Database handle */ Token *pName = 0; /* Token containing unqualified index name */ char *zName; /* Name of index being created */ int iDb; /* Index of database in db->aDb[] */ Table *pTab; /* Table object to return */ /* Use the two-part index name to determine the database ** to search for the table. 'Fix' the table name to this db ** before looking up the table. */ iDb = sqlite4TwoPartName(pParse, &p->tName1, &p->tName2, &pName); if( iDb<0 ) return 0; assert( pName && pName->z ); #ifndef SQLITE4_OMIT_TEMPDB /* If the index name was unqualified, check if the the table ** is a temp table. If so, set the database to 1. Do not do this ** if initialising a database schema. */ if( !db->init.busy ){ pTab = sqlite4SrcListLookup(pParse, p->pTblName); if( p->tName2.n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){ iDb = 1; } } #endif if( sqlite4FixInit(&sFix, pParse, iDb, "index", pName) && sqlite4FixSrcList(&sFix, p->pTblName) ){ /* Because the parser constructs pTblName from a single identifier, ** sqlite4FixSrcList can never fail. */ assert(0); } pTab = sqlite4SrcListLookup(pParse, p->pTblName); if( !pTab || db->mallocFailed ) return 0; assert( db->aDb[iDb].pSchema==pTab->pSchema ); assert( pParse->nErr==0 ); /* TODO: We will need to reinstate this block when sqlite_master is ** modified to use an implicit primary key. */ #if 0 if( sqlite4StrNICmp(pTab->zName, "sqlite_", 7)==0 && memcmp(&pTab->zName[7],"altertab_",9)!=0 ){ sqlite4ErrorMsg(pParse, "table %s may not be indexed", pTab->zName); goto exit_create_index; } #endif /* Verify that this is not an attempt to create an index on a view or ** virtual table. */ if( IsView(pTab) ){ sqlite4ErrorMsg(pParse, "views may not be indexed"); return 0; } if( IsVirtual(pTab) ){ sqlite4ErrorMsg(pParse, "virtual tables may not be indexed"); return 0; } /* Ensure that the proposed index name is not reserved. */ assert( pName->z!=0 ); zName = sqlite4NameFromToken(db, pName); if( zName==0 || sqlite4CheckObjectName(pParse, zName) ) return 0; /* Unless SQLite is currently parsing an existing database schema, check ** that there is not already an index or table using the proposed name. */ if( !db->init.busy ){ char *zDb = db->aDb[iDb].zName; if( sqlite4FindTable(db, zName, zDb)!=0 ){ sqlite4ErrorMsg(pParse, "there is already a table named %s", zName); } else if( sqlite4FindIndex(db, zName, zDb)!=0 ){ if( p->bIfnotexist ){ assert( !db->init.busy ); sqlite4CodeVerifySchema(pParse, iDb); pTab = 0; }else{ sqlite4ErrorMsg(pParse, "index %s already exists", zName); } } } if( pParse->nErr || pTab==0 ){ sqlite4DbFree(db, zName); pTab = 0; zName = 0; } *ppIdxName = pName; *pzIdxName = zName; *piDb = iDb; return pTab; } #ifndef SQLITE4_OMIT_AUTHORIZATION static int createIndexAuth( Parse *pParse, /* Parser context */ Table *pTab, /* Table index is being created on */ const char *zIdx /* Name of index being created */ ){ sqlite4 *db; int iDb; int iOp; const char *zDb; db = pParse->db; iDb = sqlite4SchemaToIndex(db, pTab->pSchema); zDb = db->aDb[iDb].zName; if( sqlite4AuthCheck(pParse, SQLITE4_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){ return 1; } iOp = (!OMIT_TEMPDB && iDb==1)?SQLITE4_CREATE_TEMP_INDEX:SQLITE4_CREATE_INDEX; if( sqlite4AuthCheck(pParse, iOp, zIdx, pTab->zName, zDb) ){ return 1; } return 0; } #else # define createIndexAuth(a, b, c) 0 #endif // SQLITE4_OMIT_AUTHORIZATION static void createIndexWriteSchema( Parse *pParse, Index *pIdx, Token *pName, Token *pEnd ){ sqlite4 *db = pParse->db; int iDb; assert( db->init.busy==0 ); iDb = sqlite4SchemaToIndex(db, pIdx->pSchema); pIdx->tnum = ++pParse->nMem; allocateTableNumber(pParse, iDb, pIdx->tnum); if( pIdx->eIndexType!=SQLITE4_INDEX_PRIMARYKEY ){ Vdbe *v; char *zStmt; v = sqlite4GetVdbe(pParse); if( v==0 ) return; sqlite4BeginWriteOperation(pParse, 1, iDb); /* Unless this index is an automatic index created by a UNIQUE ** constraint, assemble a CREATE INDEX statement to write into the ** sqlite_master table. */ if( pIdx->eIndexType!=SQLITE4_INDEX_UNIQUE ){ int n = (int)(pEnd->z - pName->z) + pEnd->n; const char *zUnique = (pIdx->onError==OE_None ? "" : " UNIQUE"); zStmt = sqlite4MPrintf(db, "CREATE%s INDEX %.*s", zUnique, n, pName->z); }else{ /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */ zStmt = 0; } /* Add an entry in sqlite_master for this index */ sqlite4NestedParse(pParse, "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);", db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pIdx->zName, pIdx->pTable->zName, pIdx->tnum, zStmt ); sqlite4DbFree(db, zStmt); /* Fill the index with data and reparse the schema. Code an OP_Expire ** to invalidate all pre-compiled statements. */ if( pIdx->eIndexType!=SQLITE4_INDEX_UNIQUE ){ sqlite4RefillIndex(pParse, pIdx, 1); sqlite4ChangeCookie(pParse, iDb); sqlite4VdbeAddParseSchemaOp(v, iDb, sqlite4MPrintf(db, "name='%q' AND type='index'", pIdx->zName)); sqlite4VdbeAddOp1(v, OP_Expire, 0); } } } void sqlite4CreateUsingIndex( Parse *pParse, /* Parsing context */ CreateIndex *p, /* First part of CREATE INDEX statement */ Token *pUsing, /* Token following USING keyword */ Token *pEnd /* Final '(' in CREATE INDEX */ ){ sqlite4 *db = pParse->db; if( p->bUnique ){ sqlite4ErrorMsg(pParse, "USING %.*s index may not be UNIQUE", pUsing->n, pUsing->z ); }else{ Index *pIdx = 0; /* New index object */ Table *pTab; Token *pIdxName = 0; char *zIdx = 0; int iDb = 0; pTab = createIndexFindTable(pParse, p, &pIdxName, &zIdx, &iDb); if( pTab && 0==createIndexAuth(pParse, pTab, zIdx) ){ char *zExtra = 0; pIdx = newIndex(pParse, pTab, zIdx, 0, 0, 0, &zExtra); } if( pIdx ){ pIdx->eIndexType = SQLITE4_INDEX_FTS5; if( db->init.busy ){ db->flags |= SQLITE4_InternChanges; pIdx->tnum = db->init.newTnum; }else{ createIndexWriteSchema(pParse, pIdx, pIdxName, pEnd); } addIndexToHash(db, pIdx); if( pParse->nErr==0 ){ pIdx->pNext = pTab->pIndex; pTab->pIndex = pIdx; }else{ sqlite4DbFree(db, pIdx); } } sqlite4DbFree(db, zIdx); } sqlite4SrcListDelete(db, p->pTblName); } /* ** Create a new index for an SQL table. pName1.pName2 is the name of the index ** and pTblList is the name of the table that is to be indexed. Both will ** be NULL for a primary key or an index that is created to satisfy a ** UNIQUE constraint. If pTable and pIndex are NULL, use pParse->pNewTable ** as the table to be indexed. pParse->pNewTable is a table that is |
︙ | |||
2361 2362 2363 2364 2365 2366 2367 | 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 | - + - - - - - - - - + - - + - - - - - - - - - + - - - - - - + + + - - - - - - + + - - - + + + - - - - - - - - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - + + - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - + - - - - + + - - - - - - - | goto exit_create_index; } /* ** Find the table that is to be indexed. Return early if not found. */ if( pTblName!=0 ){ |
︙ | |||
2688 2689 2690 2691 2692 2693 2694 | 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - | ** ** If pTblName==0 it means this index is generated as a primary key ** or UNIQUE constraint of a CREATE TABLE statement. Since the table ** has just been created, it contains no data and the index initialization ** step can be skipped. */ else{ |
︙ | |||
2840 2841 2842 2843 2844 2845 2846 | 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 | - + + + | sqlite4ErrorMsg(pParse, "no such index: %S", pName, 0); }else{ sqlite4CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); } pParse->checkSchema = 1; goto exit_drop_index; } |
︙ |
Changes to src/fts5.c.
︙ | |||
9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | + + + | ** May you share freely, never taking more than you give. ** ************************************************************************* */ #include "sqliteInt.h" /* ** Default distance value for NEAR operators. */ #define FTS5_DEFAULT_NEAR 10 /* ** Token types used by expression parser. */ #define TOKEN_EOF 0 /* end of expression - no more tokens */ #define TOKEN_PRIMITIVE 1 /* quoted string or non-keyword */ |
︙ | |||
39 40 41 42 43 44 45 | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | - + | struct Fts5Tokenizer { char *zName; /* Name of tokenizer (nul-terminated) */ void *pCtx; int (*xCreate)(void*, const char**, int, sqlite4_tokenizer**); int (*xTokenize)(void*, sqlite4_tokenizer*, const char*, int, int(*x)(void*, int, const char*, int) ); |
︙ | |||
727 728 729 730 731 732 733 | 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 | - + | sqlite4 *db, const char *zName, void *pCtx, int (*xCreate)(void*, const char**, int, sqlite4_tokenizer**), int (*xTokenize)(void*, sqlite4_tokenizer*, const char*, int, int(*x)(void*, int, const char*, int) ), |
︙ | |||
872 873 874 875 876 877 878 | 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 | - + | sqlite4_context *pCtx, int nVal, sqlite4_value **aVal ){ int rc; Fts5Expr *pExpr = 0; Fts5Tokenizer *pTok; |
︙ | |||
933 934 935 936 937 938 939 940 941 942 943 944 945 946 | 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 | + | fts5PrintExpr(db, azCol, pExpr, &zRet); sqlite4_result_text(pCtx, zRet, -1, SQLITE4_TRANSIENT); fts5ExpressionFree(db, pExpr); sqlite4_free(sqlite4_db_env(db), zRet); fts5_parse_expr_out: if( p ) pTok->xDestroy(p); sqlite4DbFree(db, azCol); sqlite4_finalize(pStmt); if( zErr ){ sqlite4_result_error(pCtx, zErr, -1); sqlite4DbFree(db, zErr); } } |
︙ |
Changes to src/fts5func.c.
︙ | |||
19 20 21 22 23 24 25 | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | - + | int nArg, sqlite4_tokenizer **pp ){ *pp = (sqlite4_tokenizer *)pCtx; return SQLITE4_OK; } |
︙ |
Changes to src/parse.y.
︙ | |||
1083 1084 1085 1086 1087 1088 1089 | 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 | + + + - - - + + + + + + + + + + + + - - + | {A = sqlite4ExprListAppend(pParse,X,Y.pExpr);} nexprlist(A) ::= expr(Y). {A = sqlite4ExprListAppend(pParse,0,Y.pExpr);} ///////////////////////////// The CREATE INDEX command /////////////////////// // %type createindex {CreateIndex} %destructor createindex {sqlite4SrcListDelete(pParse->db, $$.pTblName);} |
︙ | |||
1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 | 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 | + + + + | sqlite4ExprListCheckLength(pParse, A, "index"); if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z; } %type collate {Token} collate(C) ::= . {C.z = 0; C.n = 0;} collate(C) ::= COLLATE ids(X). {C = X;} cmd ::= createindex(C) USING nm(F) LP RP(E). { sqlite4CreateUsingIndex(pParse, &C, &F, &E); } ///////////////////////////// The DROP INDEX command ///////////////////////// // cmd ::= DROP INDEX ifexists(E) fullname(X). {sqlite4DropIndex(pParse, X, E);} ///////////////////////////// The PRAGMA command ///////////////////////////// |
︙ | |||
1357 1358 1359 1360 1361 1362 1363 | 1372 1373 1374 1375 1376 1377 1378 1379 | + | vtabargtoken ::= ANY(X). {sqlite4VtabArgExtend(pParse,&X);} vtabargtoken ::= lp anylist RP(X). {sqlite4VtabArgExtend(pParse,&X);} lp ::= LP(X). {sqlite4VtabArgExtend(pParse,&X);} anylist ::= . anylist ::= anylist LP anylist RP. anylist ::= anylist ANY. %endif SQLITE4_OMIT_VIRTUALTABLE |
Changes to src/sqlite.h.in.
︙ | |||
4384 4385 4386 4387 4388 4389 4390 | 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 | - + | const char *zName, void *pCtx, int (*xCreate)(void*, const char**, int, sqlite4_tokenizer**), int (*xTokenize)(void*, sqlite4_tokenizer*, const char*, int, int(*x)(void *ctx, int iWeight, const char *zToken, int nToken) ), |
︙ |
Changes to src/sqliteInt.h.
︙ | |||
547 548 549 550 551 552 553 554 555 556 557 558 559 560 | 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 | + | typedef struct AggInfo AggInfo; typedef struct AggInfoCol AggInfoCol; typedef struct AggInfoFunc AggInfoFunc; typedef struct AuthContext AuthContext; typedef struct AutoincInfo AutoincInfo; typedef struct CollSeq CollSeq; typedef struct Column Column; typedef struct CreateIndex CreateIndex; typedef struct Db Db; typedef struct Schema Schema; typedef struct Expr Expr; typedef struct ExprList ExprList; typedef struct ExprListItem ExprListItem; typedef struct ExprSpan ExprSpan; typedef struct FKey FKey; |
︙ | |||
1433 1434 1435 1436 1437 1438 1439 | 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 | + - + | #endif }; /* Index.eIndexType must be set to one of the following. */ #define SQLITE4_INDEX_USER 0 /* Index created by CREATE INDEX statement */ #define SQLITE4_INDEX_UNIQUE 1 /* Index created by UNIQUE constraint */ #define SQLITE4_INDEX_PRIMARYKEY 2 /* Index is the tables PRIMARY KEY */ #define SQLITE4_INDEX_FTS5 3 /* Index is an FTS5 index */ |
︙ | |||
1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 | 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 | + + + + + + + + + + + + + + | ** may contain random values. Do not make any assumptions about Token.dyn ** and Token.n when Token.z==0. */ struct Token { const char *z; /* Text of the token. Not NULL-terminated! */ unsigned int n; /* Number of characters in this token */ }; /* ** An instance of this structure holds the results of parsing the first ** part of a CREATE INDEX statement. Instances exist only transiently ** during parsing. */ struct CreateIndex { int bUnique; /* True if the UNIQUE keyword was present */ int bIfnotexist; /* True if IF NOT EXISTS was present */ Token tCreate; /* CREATE token */ Token tName1; /* First part of two part name */ Token tName2; /* Second part of two part name */ SrcList *pTblName; /* Table index is created on */ }; /* ** One for each column used in source tables. */ struct AggInfoCol { Table *pTab; /* Source table */ int iTable; /* Cursor number of the source table */ |
︙ |
Changes to src/vdbecodec.c.
︙ | |||
331 332 333 334 335 336 337 338 339 340 341 342 343 344 | 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 | + | int nAlloc; /* Slots of aOut[] allocated */ }; /* ** Enlarge a memory allocation, if necessary */ static int enlargeEncoderAllocation(KeyEncoder *p, int needed){ assert( p->nOut<=p->nAlloc ); if( p->nOut+needed>p->nAlloc ){ u8 *aNew; p->nAlloc = p->nAlloc + needed + 10; aNew = sqlite4DbRealloc(p->db, p->aOut, p->nAlloc); if( aNew==0 ){ sqlite4DbFree(p->db, p->aOut); memset(p, 0, sizeof(*p)); |
︙ | |||
592 593 594 595 596 597 598 | 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 | - - + + | p->aOut[p->nOut++] = 0x24; /* Text */ if( pColl==0 || pColl->xMkKey==0 ){ memcpy(p->aOut+p->nOut, pEnc->z, pEnc->n); p->nOut += pEnc->n; }else{ int nSpc = p->nAlloc-p->nOut; n = pColl->xMkKey(pColl->pUser, pEnc->n, pEnc->z, nSpc, p->aOut+p->nOut); |
︙ | |||
632 633 634 635 636 637 638 639 640 641 642 643 644 645 | 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 | + | } if( s>1 ) p->aOut[p->nOut++] = 0x80 | t; p->aOut[p->nOut++] = 0x00; } if( sortOrder==SQLITE4_SO_DESC ){ for(i=iStart; i<p->nOut; i++) p->aOut[i] ^= 0xff; } assert( p->nOut<=p->nAlloc ); return SQLITE4_OK; } /* ** Variables aKey/nKey contain an encoded index key. This function returns ** the length (in bytes) of the key with all but the first nField fields ** removed. |
︙ |
Added test/fts5create.test.
|
Changes to test/simple.test.
︙ | |||
96 97 98 99 100 101 102 103 104 105 106 107 108 109 | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | + | # do_execsql_test 3.3 { INSERT INTO t1 VALUES('one', '111') } {} #------------------------------------------------------------------------- reset_db breakpoint do_execsql_test 4.1 { CREATE TABLE t1(k PRIMARY KEY, v) } do_execsql_test 4.2 { CREATE INDEX i1 ON t1(v) } do_execsql_test 4.3 { SELECT * FROM sqlite_master } { table t1 t1 2 {CREATE TABLE t1(k PRIMARY KEY, v)} |
︙ |