⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 insert.c

📁 sqlite的最新源码 This ZIP archive contains preprocessed C code for the SQLite library as individual sour
💻 C
📖 第 1 页 / 共 5 页
字号:
**                                sqlite3_exec() returns immediately with a**                                return code of SQLITE_CONSTRAINT.****  any              ABORT        Back out changes from the current command**                                only (do not do a complete rollback) then**                                cause sqlite3_exec() to return immediately**                                with SQLITE_CONSTRAINT.****  any              FAIL         Sqlite_exec() returns immediately with a**                                return code of SQLITE_CONSTRAINT.  The**                                transaction is not rolled back and any**                                prior changes are retained.****  any              IGNORE       The record number and data is popped from**                                the stack and there is an immediate jump**                                to label ignoreDest.****  NOT NULL         REPLACE      The NULL value is replace by the default**                                value for that column.  If the default value**                                is NULL, the action is the same as ABORT.****  UNIQUE           REPLACE      The other row that conflicts with the row**                                being inserted is removed.****  CHECK            REPLACE      Illegal.  The results in an exception.**** Which action to take is determined by the overrideError parameter.** Or if overrideError==OE_Default, then the pParse->onError parameter** is used.  Or if pParse->onError==OE_Default then the onError value** for the constraint is used.**** The calling routine must open a read/write cursor for pTab with** cursor number "baseCur".  All indices of pTab must also have open** read/write cursors with cursor number baseCur+i for the i-th cursor.** Except, if there is no possibility of a REPLACE action then** cursors do not need to be open for indices where aRegIdx[i]==0.*/void sqlite3GenerateConstraintChecks(  Parse *pParse,      /* The parser context */  Table *pTab,        /* the table into which we are inserting */  int baseCur,        /* Index of a read/write cursor pointing at pTab */  int regRowid,       /* Index of the range of input registers */  int *aRegIdx,       /* Register used by each index.  0 for unused indices */  int rowidChng,      /* True if the rowid might collide with existing entry */  int isUpdate,       /* True for UPDATE, False for INSERT */  int overrideError,  /* Override onError to this if not OE_Default */  int ignoreDest      /* Jump to this label on an OE_Ignore resolution */){  int i;  Vdbe *v;  int nCol;  int onError;  int j1, j2, j3;     /* Addresses of jump instructions */  int regData;        /* Register containing first data column */  int iCur;  Index *pIdx;  int seenReplace = 0;  int hasTwoRowids = (isUpdate && rowidChng);  v = sqlite3GetVdbe(pParse);  assert( v!=0 );  assert( pTab->pSelect==0 );  /* This table is not a VIEW */  nCol = pTab->nCol;  regData = regRowid + 1;  /* Test all NOT NULL constraints.  */  for(i=0; i<nCol; i++){    if( i==pTab->iPKey ){      continue;    }    onError = pTab->aCol[i].notNull;    if( onError==OE_None ) continue;    if( overrideError!=OE_Default ){      onError = overrideError;    }else if( onError==OE_Default ){      onError = OE_Abort;    }    if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){      onError = OE_Abort;    }    j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regData+i);    assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail        || onError==OE_Ignore || onError==OE_Replace );    switch( onError ){      case OE_Rollback:      case OE_Abort:      case OE_Fail: {        char *zMsg;        sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_CONSTRAINT, onError);        zMsg = sqlite3MPrintf(pParse->db, "%s.%s may not be NULL",                              pTab->zName, pTab->aCol[i].zName);        sqlite3VdbeChangeP4(v, -1, zMsg, P4_DYNAMIC);        break;      }      case OE_Ignore: {        sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);        break;      }      case OE_Replace: {        sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regData+i);        break;      }    }    sqlite3VdbeJumpHere(v, j1);  }  /* Test all CHECK constraints  */#ifndef SQLITE_OMIT_CHECK  if( pTab->pCheck && (pParse->db->flags & SQLITE_IgnoreChecks)==0 ){    int allOk = sqlite3VdbeMakeLabel(v);    pParse->ckBase = regData;    sqlite3ExprIfTrue(pParse, pTab->pCheck, allOk, SQLITE_JUMPIFNULL);    onError = overrideError!=OE_Default ? overrideError : OE_Abort;    if( onError==OE_Ignore ){      sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);    }else{      sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_CONSTRAINT, onError);    }    sqlite3VdbeResolveLabel(v, allOk);  }#endif /* !defined(SQLITE_OMIT_CHECK) */  /* If we have an INTEGER PRIMARY KEY, make sure the primary key  ** of the new record does not previously exist.  Except, if this  ** is an UPDATE and the primary key is not changing, that is OK.  */  if( rowidChng ){    onError = pTab->keyConf;    if( overrideError!=OE_Default ){      onError = overrideError;    }else if( onError==OE_Default ){      onError = OE_Abort;    }        if( onError!=OE_Replace || pTab->pIndex ){      if( isUpdate ){        j2 = sqlite3VdbeAddOp3(v, OP_Eq, regRowid, 0, regRowid-1);      }      j3 = sqlite3VdbeAddOp3(v, OP_NotExists, baseCur, 0, regRowid);      switch( onError ){        default: {          onError = OE_Abort;          /* Fall thru into the next case */        }        case OE_Rollback:        case OE_Abort:        case OE_Fail: {          sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0,                           "PRIMARY KEY must be unique", P4_STATIC);          break;        }        case OE_Replace: {          sqlite3GenerateRowIndexDelete(pParse, pTab, baseCur, 0);          seenReplace = 1;          break;        }        case OE_Ignore: {          assert( seenReplace==0 );          sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);          break;        }      }      sqlite3VdbeJumpHere(v, j3);      if( isUpdate ){        sqlite3VdbeJumpHere(v, j2);      }    }  }  /* Test all UNIQUE constraints by creating entries for each UNIQUE  ** index and making sure that duplicate entries do not already exist.  ** Add the new records to the indices as we go.  */  for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){    int regIdx;    int regR;    if( aRegIdx[iCur]==0 ) continue;  /* Skip unused indices */    /* Create a key for accessing the index entry */    regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);    for(i=0; i<pIdx->nColumn; i++){      int idx = pIdx->aiColumn[i];      if( idx==pTab->iPKey ){        sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);      }else{        sqlite3VdbeAddOp2(v, OP_SCopy, regData+idx, regIdx+i);      }    }    sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);    sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]);    sqlite3IndexAffinityStr(v, pIdx);    sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1);    sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);    /* Find out what action to take in case there is an indexing conflict */    onError = pIdx->onError;    if( onError==OE_None ) continue;  /* pIdx is not a UNIQUE index */    if( overrideError!=OE_Default ){      onError = overrideError;    }else if( onError==OE_Default ){      onError = OE_Abort;    }    if( seenReplace ){      if( onError==OE_Ignore ) onError = OE_Replace;      else if( onError==OE_Fail ) onError = OE_Abort;    }        /* Check to see if the new index entry will be unique */    j2 = sqlite3VdbeAddOp3(v, OP_IsNull, regIdx, 0, pIdx->nColumn);    regR = sqlite3GetTempReg(pParse);    sqlite3VdbeAddOp2(v, OP_SCopy, regRowid-hasTwoRowids, regR);    j3 = sqlite3VdbeAddOp4(v, OP_IsUnique, baseCur+iCur+1, 0,                           regR, SQLITE_INT_TO_PTR(aRegIdx[iCur]),                           P4_INT32);    /* Generate code that executes if the new index entry is not unique */    assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail        || onError==OE_Ignore || onError==OE_Replace );    switch( onError ){      case OE_Rollback:      case OE_Abort:      case OE_Fail: {        int j, n1, n2;        char zErrMsg[200];        sqlite3_snprintf(ArraySize(zErrMsg), zErrMsg,                         pIdx->nColumn>1 ? "columns " : "column ");        n1 = strlen(zErrMsg);        for(j=0; j<pIdx->nColumn && n1<ArraySize(zErrMsg)-30; j++){          char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;          n2 = strlen(zCol);          if( j>0 ){            sqlite3_snprintf(ArraySize(zErrMsg)-n1, &zErrMsg[n1], ", ");            n1 += 2;          }          if( n1+n2>ArraySize(zErrMsg)-30 ){            sqlite3_snprintf(ArraySize(zErrMsg)-n1, &zErrMsg[n1], "...");            n1 += 3;            break;          }else{            sqlite3_snprintf(ArraySize(zErrMsg)-n1, &zErrMsg[n1], "%s", zCol);            n1 += n2;          }        }        sqlite3_snprintf(ArraySize(zErrMsg)-n1, &zErrMsg[n1],             pIdx->nColumn>1 ? " are not unique" : " is not unique");        sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0, zErrMsg,0);        break;      }      case OE_Ignore: {        assert( seenReplace==0 );        sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);        break;      }      case OE_Replace: {        sqlite3GenerateRowDelete(pParse, pTab, baseCur, regR, 0);        seenReplace = 1;        break;      }    }    sqlite3VdbeJumpHere(v, j2);    sqlite3VdbeJumpHere(v, j3);    sqlite3ReleaseTempReg(pParse, regR);  }}/*** This routine generates code to finish the INSERT or UPDATE operation** that was started by a prior call to sqlite3GenerateConstraintChecks.** A consecutive range of registers starting at regRowid contains the** rowid and the content to be inserted.**** The arguments to this routine should be the same as the first six** arguments to sqlite3GenerateConstraintChecks.*/void sqlite3CompleteInsertion(  Parse *pParse,      /* The parser context */  Table *pTab,        /* the table into which we are inserting */  int baseCur,        /* Index of a read/write cursor pointing at pTab */  int regRowid,       /* Range of content */  int *aRegIdx,       /* Register used by each index.  0 for unused indices */  int isUpdate,       /* True for UPDATE, False for INSERT */  int newIdx,         /* Index of NEW table for triggers.  -1 if none */  int appendBias      /* True if this is likely to be an append */){  int i;  Vdbe *v;  int nIdx;  Index *pIdx;  int pik_flags;  int regData;  int regRec;  v = sqlite3GetVdbe(pParse);  assert( v!=0 );  assert( pTab->pSelect==0 );  /* This table is not a VIEW */  for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}  for(i=nIdx-1; i>=0; i--){    if( aRegIdx[i]==0 ) continue;    sqlite3VdbeAddOp2(v, OP_IdxInsert, baseCur+i+1, aRegIdx[i]);  }  regData = regRowid + 1;  regRec = sqlite3GetTempReg(pParse);  sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec);  sqlite3TableAffinityStr(v, pTab);  sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol);#ifndef SQLITE_OMIT_TRIGGER  if( newIdx>=0 ){    sqlite3VdbeAddOp3(v, OP_Insert, newIdx, regRec, regRowid);  }#endif  if( pParse->nested ){    pik_flags = 0;  }else{    pik_flags = OPFLAG_NCHANGE;    pik_flags |= (isUpdate?OPFLAG_ISUPDATE:OPFLAG_LASTROWID);  }  if( appendBias ){    pik_flags |= OPFLAG_APPEND;  }  sqlite3VdbeAddOp3(v, OP_Insert, baseCur, regRec, regRowid);  if( !pParse->nested ){    sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC);  }  sqlite3VdbeChangeP5(v, pik_flags);}/*** Generate code that will open cursors for a table and for all** indices of that table.  The "baseCur" parameter is the cursor number used** for the table.  Indices are opened on subsequent cursors.**** Return the number of indices on the table.*/int sqlite3OpenTableAndIndices(  Parse *pParse,   /* Parsing context */  Table *pTab,     /* Table to be opened */  int baseCur,     /* Cursor number assigned to the table */  int op           /* OP_OpenRead or OP_OpenWrite */){  int i;  int iDb;  Index *pIdx;  Vdbe *v;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -