00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "sqliteInt.h"
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 void sqliteInsert(
00087 Parse *pParse,
00088 SrcList *pTabList,
00089 ExprList *pList,
00090 Select *pSelect,
00091 IdList *pColumn,
00092 int onError
00093 ){
00094 Table *pTab;
00095 char *zTab;
00096 const char *zDb;
00097 int i, j, idx;
00098 Vdbe *v;
00099 Index *pIdx;
00100 int nColumn;
00101 int base;
00102 int iCont, iBreak;
00103 sqlite *db;
00104 int keyColumn = -1;
00105 int endOfLoop;
00106 int useTempTable;
00107 int srcTab;
00108 int iSelectLoop;
00109 int iCleanup;
00110 int iInsertBlock;
00111 int iCntMem;
00112 int isView;
00113
00114 int row_triggers_exist = 0;
00115 int before_triggers;
00116 int after_triggers;
00117 int newIdx = -1;
00118
00119 if( pParse->nErr || sqlite_malloc_failed ) goto insert_cleanup;
00120 db = pParse->db;
00121
00122
00123
00124 assert( pTabList->nSrc==1 );
00125 zTab = pTabList->a[0].zName;
00126 if( zTab==0 ) goto insert_cleanup;
00127 pTab = sqliteSrcListLookup(pParse, pTabList);
00128 if( pTab==0 ){
00129 goto insert_cleanup;
00130 }
00131 assert( pTab->iDb<db->nDb );
00132 zDb = db->aDb[pTab->iDb].zName;
00133 if( sqliteAuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){
00134 goto insert_cleanup;
00135 }
00136
00137
00138
00139
00140
00141 before_triggers = sqliteTriggersExist(pParse, pTab->pTrigger, TK_INSERT,
00142 TK_BEFORE, TK_ROW, 0);
00143 after_triggers = sqliteTriggersExist(pParse, pTab->pTrigger, TK_INSERT,
00144 TK_AFTER, TK_ROW, 0);
00145 row_triggers_exist = before_triggers || after_triggers;
00146 isView = pTab->pSelect!=0;
00147 if( sqliteIsReadOnly(pParse, pTab, before_triggers) ){
00148 goto insert_cleanup;
00149 }
00150 if( pTab==0 ) goto insert_cleanup;
00151
00152
00153
00154 if( isView && sqliteViewGetColumnNames(pParse, pTab) ){
00155 goto insert_cleanup;
00156 }
00157
00158
00159
00160 v = sqliteGetVdbe(pParse);
00161 if( v==0 ) goto insert_cleanup;
00162 sqliteBeginWriteOperation(pParse, pSelect || row_triggers_exist, pTab->iDb);
00163
00164
00165 if( row_triggers_exist ){
00166 newIdx = pParse->nTab++;
00167 }
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 if( pSelect ){
00178
00179
00180 int rc, iInitCode;
00181 iInitCode = sqliteVdbeAddOp(v, OP_Goto, 0, 0);
00182 iSelectLoop = sqliteVdbeCurrentAddr(v);
00183 iInsertBlock = sqliteVdbeMakeLabel(v);
00184 rc = sqliteSelect(pParse, pSelect, SRT_Subroutine, iInsertBlock, 0,0,0);
00185 if( rc || pParse->nErr || sqlite_malloc_failed ) goto insert_cleanup;
00186 iCleanup = sqliteVdbeMakeLabel(v);
00187 sqliteVdbeAddOp(v, OP_Goto, 0, iCleanup);
00188 assert( pSelect->pEList );
00189 nColumn = pSelect->pEList->nExpr;
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 if( row_triggers_exist ){
00200 useTempTable = 1;
00201 }else{
00202 int addr = sqliteVdbeFindOp(v, OP_OpenRead, pTab->tnum);
00203 useTempTable = 0;
00204 if( addr>0 ){
00205 VdbeOp *pOp = sqliteVdbeGetOp(v, addr-2);
00206 if( pOp->opcode==OP_Integer && pOp->p1==pTab->iDb ){
00207 useTempTable = 1;
00208 }
00209 }
00210 }
00211
00212 if( useTempTable ){
00213
00214
00215
00216 srcTab = pParse->nTab++;
00217 sqliteVdbeResolveLabel(v, iInsertBlock);
00218 sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0);
00219 sqliteVdbeAddOp(v, OP_NewRecno, srcTab, 0);
00220 sqliteVdbeAddOp(v, OP_Pull, 1, 0);
00221 sqliteVdbeAddOp(v, OP_PutIntKey, srcTab, 0);
00222 sqliteVdbeAddOp(v, OP_Return, 0, 0);
00223
00224
00225
00226
00227
00228 sqliteVdbeChangeP2(v, iInitCode, sqliteVdbeCurrentAddr(v));
00229 sqliteVdbeAddOp(v, OP_OpenTemp, srcTab, 0);
00230 sqliteVdbeAddOp(v, OP_Goto, 0, iSelectLoop);
00231 sqliteVdbeResolveLabel(v, iCleanup);
00232 }else{
00233 sqliteVdbeChangeP2(v, iInitCode, sqliteVdbeCurrentAddr(v));
00234 }
00235 }else{
00236
00237
00238
00239 SrcList dummy;
00240 assert( pList!=0 );
00241 srcTab = -1;
00242 useTempTable = 0;
00243 assert( pList );
00244 nColumn = pList->nExpr;
00245 dummy.nSrc = 0;
00246 for(i=0; i<nColumn; i++){
00247 if( sqliteExprResolveIds(pParse, &dummy, 0, pList->a[i].pExpr) ){
00248 goto insert_cleanup;
00249 }
00250 if( sqliteExprCheck(pParse, pList->a[i].pExpr, 0, 0) ){
00251 goto insert_cleanup;
00252 }
00253 }
00254 }
00255
00256
00257
00258
00259 if( pColumn==0 && nColumn!=pTab->nCol ){
00260 sqliteErrorMsg(pParse,
00261 "table %S has %d columns but %d values were supplied",
00262 pTabList, 0, pTab->nCol, nColumn);
00263 goto insert_cleanup;
00264 }
00265 if( pColumn!=0 && nColumn!=pColumn->nId ){
00266 sqliteErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId);
00267 goto insert_cleanup;
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 if( pColumn ){
00282 for(i=0; i<pColumn->nId; i++){
00283 pColumn->a[i].idx = -1;
00284 }
00285 for(i=0; i<pColumn->nId; i++){
00286 for(j=0; j<pTab->nCol; j++){
00287 if( sqliteStrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){
00288 pColumn->a[i].idx = j;
00289 if( j==pTab->iPKey ){
00290 keyColumn = i;
00291 }
00292 break;
00293 }
00294 }
00295 if( j>=pTab->nCol ){
00296 if( sqliteIsRowid(pColumn->a[i].zName) ){
00297 keyColumn = i;
00298 }else{
00299 sqliteErrorMsg(pParse, "table %S has no column named %s",
00300 pTabList, 0, pColumn->a[i].zName);
00301 pParse->nErr++;
00302 goto insert_cleanup;
00303 }
00304 }
00305 }
00306 }
00307
00308
00309
00310
00311
00312 if( pColumn==0 ){
00313 keyColumn = pTab->iPKey;
00314 }
00315
00316
00317
00318 if( row_triggers_exist ){
00319 sqliteVdbeAddOp(v, OP_OpenPseudo, newIdx, 0);
00320 }
00321
00322
00323
00324 if( db->flags & SQLITE_CountRows ){
00325 iCntMem = pParse->nMem++;
00326 sqliteVdbeAddOp(v, OP_Integer, 0, 0);
00327 sqliteVdbeAddOp(v, OP_MemStore, iCntMem, 1);
00328 }
00329
00330
00331 if( !row_triggers_exist ){
00332 base = pParse->nTab;
00333 idx = sqliteOpenTableAndIndices(pParse, pTab, base);
00334 pParse->nTab += idx;
00335 }
00336
00337
00338
00339
00340
00341
00342 if( useTempTable ){
00343 iBreak = sqliteVdbeMakeLabel(v);
00344 sqliteVdbeAddOp(v, OP_Rewind, srcTab, iBreak);
00345 iCont = sqliteVdbeCurrentAddr(v);
00346 }else if( pSelect ){
00347 sqliteVdbeAddOp(v, OP_Goto, 0, iSelectLoop);
00348 sqliteVdbeResolveLabel(v, iInsertBlock);
00349 }
00350
00351
00352
00353 endOfLoop = sqliteVdbeMakeLabel(v);
00354 if( before_triggers ){
00355
00356
00357
00358
00359
00360
00361
00362 if( keyColumn<0 ){
00363 sqliteVdbeAddOp(v, OP_Integer, -1, 0);
00364 }else if( useTempTable ){
00365 sqliteVdbeAddOp(v, OP_Column, srcTab, keyColumn);
00366 }else if( pSelect ){
00367 sqliteVdbeAddOp(v, OP_Dup, nColumn - keyColumn - 1, 1);
00368 }else{
00369 sqliteExprCode(pParse, pList->a[keyColumn].pExpr);
00370 sqliteVdbeAddOp(v, OP_NotNull, -1, sqliteVdbeCurrentAddr(v)+3);
00371 sqliteVdbeAddOp(v, OP_Pop, 1, 0);
00372 sqliteVdbeAddOp(v, OP_Integer, -1, 0);
00373 sqliteVdbeAddOp(v, OP_MustBeInt, 0, 0);
00374 }
00375
00376
00377
00378 for(i=0; i<pTab->nCol; i++){
00379 if( pColumn==0 ){
00380 j = i;
00381 }else{
00382 for(j=0; j<pColumn->nId; j++){
00383 if( pColumn->a[j].idx==i ) break;
00384 }
00385 }
00386 if( pColumn && j>=pColumn->nId ){
00387 sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[i].zDflt, P3_STATIC);
00388 }else if( useTempTable ){
00389 sqliteVdbeAddOp(v, OP_Column, srcTab, j);
00390 }else if( pSelect ){
00391 sqliteVdbeAddOp(v, OP_Dup, nColumn-j-1, 1);
00392 }else{
00393 sqliteExprCode(pParse, pList->a[j].pExpr);
00394 }
00395 }
00396 sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
00397 sqliteVdbeAddOp(v, OP_PutIntKey, newIdx, 0);
00398
00399
00400 if( sqliteCodeRowTrigger(pParse, TK_INSERT, 0, TK_BEFORE, pTab,
00401 newIdx, -1, onError, endOfLoop) ){
00402 goto insert_cleanup;
00403 }
00404 }
00405
00406
00407
00408
00409 if( row_triggers_exist && !isView ){
00410 base = pParse->nTab;
00411 idx = sqliteOpenTableAndIndices(pParse, pTab, base);
00412 pParse->nTab += idx;
00413 }
00414
00415
00416
00417
00418
00419
00420 if( !isView ){
00421 if( keyColumn>=0 ){
00422 if( useTempTable ){
00423 sqliteVdbeAddOp(v, OP_Column, srcTab, keyColumn);
00424 }else if( pSelect ){
00425 sqliteVdbeAddOp(v, OP_Dup, nColumn - keyColumn - 1, 1);
00426 }else{
00427 sqliteExprCode(pParse, pList->a[keyColumn].pExpr);
00428 }
00429
00430
00431
00432 sqliteVdbeAddOp(v, OP_NotNull, -1, sqliteVdbeCurrentAddr(v)+3);
00433 sqliteVdbeAddOp(v, OP_Pop, 1, 0);
00434 sqliteVdbeAddOp(v, OP_NewRecno, base, 0);
00435 sqliteVdbeAddOp(v, OP_MustBeInt, 0, 0);
00436 }else{
00437 sqliteVdbeAddOp(v, OP_NewRecno, base, 0);
00438 }
00439
00440
00441
00442
00443 for(i=0; i<pTab->nCol; i++){
00444 if( i==pTab->iPKey ){
00445
00446
00447
00448
00449 sqliteVdbeAddOp(v, OP_String, 0, 0);
00450 continue;
00451 }
00452 if( pColumn==0 ){
00453 j = i;
00454 }else{
00455 for(j=0; j<pColumn->nId; j++){
00456 if( pColumn->a[j].idx==i ) break;
00457 }
00458 }
00459 if( pColumn && j>=pColumn->nId ){
00460 sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[i].zDflt, P3_STATIC);
00461 }else if( useTempTable ){
00462 sqliteVdbeAddOp(v, OP_Column, srcTab, j);
00463 }else if( pSelect ){
00464 sqliteVdbeAddOp(v, OP_Dup, i+nColumn-j, 1);
00465 }else{
00466 sqliteExprCode(pParse, pList->a[j].pExpr);
00467 }
00468 }
00469
00470
00471
00472
00473 sqliteGenerateConstraintChecks(pParse, pTab, base, 0, keyColumn>=0,
00474 0, onError, endOfLoop);
00475 sqliteCompleteInsertion(pParse, pTab, base, 0,0,0,
00476 after_triggers ? newIdx : -1);
00477 }
00478
00479
00480
00481 if( (db->flags & SQLITE_CountRows)!=0 ){
00482 sqliteVdbeAddOp(v, OP_MemIncr, iCntMem, 0);
00483 }
00484
00485 if( row_triggers_exist ){
00486
00487 if( !isView ){
00488 sqliteVdbeAddOp(v, OP_Close, base, 0);
00489 for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
00490 sqliteVdbeAddOp(v, OP_Close, idx+base, 0);
00491 }
00492 }
00493
00494
00495 if( sqliteCodeRowTrigger(pParse, TK_INSERT, 0, TK_AFTER, pTab, newIdx, -1,
00496 onError, endOfLoop) ){
00497 goto insert_cleanup;
00498 }
00499 }
00500
00501
00502
00503 sqliteVdbeResolveLabel(v, endOfLoop);
00504 if( useTempTable ){
00505 sqliteVdbeAddOp(v, OP_Next, srcTab, iCont);
00506 sqliteVdbeResolveLabel(v, iBreak);
00507 sqliteVdbeAddOp(v, OP_Close, srcTab, 0);
00508 }else if( pSelect ){
00509 sqliteVdbeAddOp(v, OP_Pop, nColumn, 0);
00510 sqliteVdbeAddOp(v, OP_Return, 0, 0);
00511 sqliteVdbeResolveLabel(v, iCleanup);
00512 }
00513
00514 if( !row_triggers_exist ){
00515
00516 sqliteVdbeAddOp(v, OP_Close, base, 0);
00517 for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
00518 sqliteVdbeAddOp(v, OP_Close, idx+base, 0);
00519 }
00520 }
00521
00522 sqliteVdbeAddOp(v, OP_SetCounts, 0, 0);
00523 sqliteEndWriteOperation(pParse);
00524
00525
00526
00527
00528 if( db->flags & SQLITE_CountRows ){
00529 sqliteVdbeOp3(v, OP_ColumnName, 0, 1, "rows inserted", P3_STATIC);
00530 sqliteVdbeAddOp(v, OP_MemLoad, iCntMem, 0);
00531 sqliteVdbeAddOp(v, OP_Callback, 1, 0);
00532 }
00533
00534 insert_cleanup:
00535 sqliteSrcListDelete(pTabList);
00536 if( pList ) sqliteExprListDelete(pList);
00537 if( pSelect ) sqliteSelectDelete(pSelect);
00538 sqliteIdListDelete(pColumn);
00539 }
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620 void sqliteGenerateConstraintChecks(
00621 Parse *pParse,
00622 Table *pTab,
00623 int base,
00624 char *aIdxUsed,
00625 int recnoChng,
00626 int isUpdate,
00627 int overrideError,
00628 int ignoreDest
00629 ){
00630 int i;
00631 Vdbe *v;
00632 int nCol;
00633 int onError;
00634 int addr;
00635 int extra;
00636 int iCur;
00637 Index *pIdx;
00638 int seenReplace = 0;
00639 int jumpInst1, jumpInst2;
00640 int contAddr;
00641 int hasTwoRecnos = (isUpdate && recnoChng);
00642
00643 v = sqliteGetVdbe(pParse);
00644 assert( v!=0 );
00645 assert( pTab->pSelect==0 );
00646 nCol = pTab->nCol;
00647
00648
00649
00650 for(i=0; i<nCol; i++){
00651 if( i==pTab->iPKey ){
00652 continue;
00653 }
00654 onError = pTab->aCol[i].notNull;
00655 if( onError==OE_None ) continue;
00656 if( overrideError!=OE_Default ){
00657 onError = overrideError;
00658 }else if( pParse->db->onError!=OE_Default ){
00659 onError = pParse->db->onError;
00660 }else if( onError==OE_Default ){
00661 onError = OE_Abort;
00662 }
00663 if( onError==OE_Replace && pTab->aCol[i].zDflt==0 ){
00664 onError = OE_Abort;
00665 }
00666 sqliteVdbeAddOp(v, OP_Dup, nCol-1-i, 1);
00667 addr = sqliteVdbeAddOp(v, OP_NotNull, 1, 0);
00668 switch( onError ){
00669 case OE_Rollback:
00670 case OE_Abort:
00671 case OE_Fail: {
00672 char *zMsg = 0;
00673 sqliteVdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError);
00674 sqliteSetString(&zMsg, pTab->zName, ".", pTab->aCol[i].zName,
00675 " may not be NULL", (char*)0);
00676 sqliteVdbeChangeP3(v, -1, zMsg, P3_DYNAMIC);
00677 break;
00678 }
00679 case OE_Ignore: {
00680 sqliteVdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 0);
00681 sqliteVdbeAddOp(v, OP_Goto, 0, ignoreDest);
00682 break;
00683 }
00684 case OE_Replace: {
00685 sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[i].zDflt, P3_STATIC);
00686 sqliteVdbeAddOp(v, OP_Push, nCol-i, 0);
00687 break;
00688 }
00689 default: assert(0);
00690 }
00691 sqliteVdbeChangeP2(v, addr, sqliteVdbeCurrentAddr(v));
00692 }
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702 if( recnoChng ){
00703 onError = pTab->keyConf;
00704 if( overrideError!=OE_Default ){
00705 onError = overrideError;
00706 }else if( pParse->db->onError!=OE_Default ){
00707 onError = pParse->db->onError;
00708 }else if( onError==OE_Default ){
00709 onError = OE_Abort;
00710 }
00711
00712 if( isUpdate ){
00713 sqliteVdbeAddOp(v, OP_Dup, nCol+1, 1);
00714 sqliteVdbeAddOp(v, OP_Dup, nCol+1, 1);
00715 jumpInst1 = sqliteVdbeAddOp(v, OP_Eq, 0, 0);
00716 }
00717 sqliteVdbeAddOp(v, OP_Dup, nCol, 1);
00718 jumpInst2 = sqliteVdbeAddOp(v, OP_NotExists, base, 0);
00719 switch( onError ){
00720 default: {
00721 onError = OE_Abort;
00722
00723 }
00724 case OE_Rollback:
00725 case OE_Abort:
00726 case OE_Fail: {
00727 sqliteVdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError,
00728 "PRIMARY KEY must be unique", P3_STATIC);
00729 break;
00730 }
00731 case OE_Replace: {
00732 sqliteGenerateRowIndexDelete(pParse->db, v, pTab, base, 0);
00733 if( isUpdate ){
00734 sqliteVdbeAddOp(v, OP_Dup, nCol+hasTwoRecnos, 1);
00735 sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
00736 }
00737 seenReplace = 1;
00738 break;
00739 }
00740 case OE_Ignore: {
00741 assert( seenReplace==0 );
00742 sqliteVdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 0);
00743 sqliteVdbeAddOp(v, OP_Goto, 0, ignoreDest);
00744 break;
00745 }
00746 }
00747 contAddr = sqliteVdbeCurrentAddr(v);
00748 sqliteVdbeChangeP2(v, jumpInst2, contAddr);
00749 if( isUpdate ){
00750 sqliteVdbeChangeP2(v, jumpInst1, contAddr);
00751 sqliteVdbeAddOp(v, OP_Dup, nCol+1, 1);
00752 sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
00753 }
00754 }
00755
00756
00757
00758
00759
00760 extra = -1;
00761 for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
00762 if( aIdxUsed && aIdxUsed[iCur]==0 ) continue;
00763 extra++;
00764
00765
00766 sqliteVdbeAddOp(v, OP_Dup, nCol+extra, 1);
00767 for(i=0; i<pIdx->nColumn; i++){
00768 int idx = pIdx->aiColumn[i];
00769 if( idx==pTab->iPKey ){
00770 sqliteVdbeAddOp(v, OP_Dup, i+extra+nCol+1, 1);
00771 }else{
00772 sqliteVdbeAddOp(v, OP_Dup, i+extra+nCol-idx, 1);
00773 }
00774 }
00775 jumpInst1 = sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
00776 if( pParse->db->file_format>=4 ) sqliteAddIdxKeyType(v, pIdx);
00777
00778
00779 onError = pIdx->onError;
00780 if( onError==OE_None ) continue;
00781 if( overrideError!=OE_Default ){
00782 onError = overrideError;
00783 }else if( pParse->db->onError!=OE_Default ){
00784 onError = pParse->db->onError;
00785 }else if( onError==OE_Default ){
00786 onError = OE_Abort;
00787 }
00788 if( seenReplace ){
00789 if( onError==OE_Ignore ) onError = OE_Replace;
00790 else if( onError==OE_Fail ) onError = OE_Abort;
00791 }
00792
00793
00794
00795 sqliteVdbeAddOp(v, OP_Dup, extra+nCol+1+hasTwoRecnos, 1);
00796 jumpInst2 = sqliteVdbeAddOp(v, OP_IsUnique, base+iCur+1, 0);
00797
00798
00799 switch( onError ){
00800 case OE_Rollback:
00801 case OE_Abort:
00802 case OE_Fail: {
00803 int j, n1, n2;
00804 char zErrMsg[200];
00805 strcpy(zErrMsg, pIdx->nColumn>1 ? "columns " : "column ");
00806 n1 = strlen(zErrMsg);
00807 for(j=0; j<pIdx->nColumn && n1<sizeof(zErrMsg)-30; j++){
00808 char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
00809 n2 = strlen(zCol);
00810 if( j>0 ){
00811 strcpy(&zErrMsg[n1], ", ");
00812 n1 += 2;
00813 }
00814 if( n1+n2>sizeof(zErrMsg)-30 ){
00815 strcpy(&zErrMsg[n1], "...");
00816 n1 += 3;
00817 break;
00818 }else{
00819 strcpy(&zErrMsg[n1], zCol);
00820 n1 += n2;
00821 }
00822 }
00823 strcpy(&zErrMsg[n1],
00824 pIdx->nColumn>1 ? " are not unique" : " is not unique");
00825 sqliteVdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError, zErrMsg, 0);
00826 break;
00827 }
00828 case OE_Ignore: {
00829 assert( seenReplace==0 );
00830 sqliteVdbeAddOp(v, OP_Pop, nCol+extra+3+hasTwoRecnos, 0);
00831 sqliteVdbeAddOp(v, OP_Goto, 0, ignoreDest);
00832 break;
00833 }
00834 case OE_Replace: {
00835 sqliteGenerateRowDelete(pParse->db, v, pTab, base, 0);
00836 if( isUpdate ){
00837 sqliteVdbeAddOp(v, OP_Dup, nCol+extra+1+hasTwoRecnos, 1);
00838 sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
00839 }
00840 seenReplace = 1;
00841 break;
00842 }
00843 default: assert(0);
00844 }
00845 contAddr = sqliteVdbeCurrentAddr(v);
00846 #if NULL_DISTINCT_FOR_UNIQUE
00847 sqliteVdbeChangeP2(v, jumpInst1, contAddr);
00848 #endif
00849 sqliteVdbeChangeP2(v, jumpInst2, contAddr);
00850 }
00851 }
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863 void sqliteCompleteInsertion(
00864 Parse *pParse,
00865 Table *pTab,
00866 int base,
00867 char *aIdxUsed,
00868 int recnoChng,
00869 int isUpdate,
00870 int newIdx
00871 ){
00872 int i;
00873 Vdbe *v;
00874 int nIdx;
00875 Index *pIdx;
00876
00877 v = sqliteGetVdbe(pParse);
00878 assert( v!=0 );
00879 assert( pTab->pSelect==0 );
00880 for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
00881 for(i=nIdx-1; i>=0; i--){
00882 if( aIdxUsed && aIdxUsed[i]==0 ) continue;
00883 sqliteVdbeAddOp(v, OP_IdxPut, base+i+1, 0);
00884 }
00885 sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
00886 if( newIdx>=0 ){
00887 sqliteVdbeAddOp(v, OP_Dup, 1, 0);
00888 sqliteVdbeAddOp(v, OP_Dup, 1, 0);
00889 sqliteVdbeAddOp(v, OP_PutIntKey, newIdx, 0);
00890 }
00891 sqliteVdbeAddOp(v, OP_PutIntKey, base,
00892 (pParse->trigStack?0:OPFLAG_NCHANGE) |
00893 (isUpdate?0:OPFLAG_LASTROWID) | OPFLAG_CSCHANGE);
00894 if( isUpdate && recnoChng ){
00895 sqliteVdbeAddOp(v, OP_Pop, 1, 0);
00896 }
00897 }
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907 int sqliteOpenTableAndIndices(Parse *pParse, Table *pTab, int base){
00908 int i;
00909 Index *pIdx;
00910 Vdbe *v = sqliteGetVdbe(pParse);
00911 assert( v!=0 );
00912 sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
00913 sqliteVdbeOp3(v, OP_OpenWrite, base, pTab->tnum, pTab->zName, P3_STATIC);
00914 for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
00915 sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
00916 sqliteVdbeOp3(v, OP_OpenWrite, i+base, pIdx->tnum, pIdx->zName, P3_STATIC);
00917 }
00918 return i;
00919 }