delete.c
上传用户:sunhongbo
上传日期:2022-01-25
资源大小:3010k
文件大小:18k
源码类别:

数据库系统

开发平台:

C/C++

  1. /*
  2. ** 2001 September 15
  3. **
  4. ** The author disclaims copyright to this source code.  In place of
  5. ** a legal notice, here is a blessing:
  6. **
  7. **    May you do good and not evil.
  8. **    May you find forgiveness for yourself and forgive others.
  9. **    May you share freely, never taking more than you give.
  10. **
  11. *************************************************************************
  12. ** This file contains C code routines that are called by the parser
  13. ** in order to generate code for DELETE FROM statements.
  14. **
  15. ** $Id: delete.c,v 1.168 2008/04/15 14:36:42 drh Exp $
  16. */
  17. #include "sqliteInt.h"
  18. /*
  19. ** Look up every table that is named in pSrc.  If any table is not found,
  20. ** add an error message to pParse->zErrMsg and return NULL.  If all tables
  21. ** are found, return a pointer to the last table.
  22. */
  23. Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
  24.   Table *pTab = 0;
  25.   int i;
  26.   struct SrcList_item *pItem;
  27.   for(i=0, pItem=pSrc->a; i<pSrc->nSrc; i++, pItem++){
  28.     pTab = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase);
  29.     sqlite3DeleteTable(pItem->pTab);
  30.     pItem->pTab = pTab;
  31.     if( pTab ){
  32.       pTab->nRef++;
  33.     }
  34.   }
  35.   return pTab;
  36. }
  37. /*
  38. ** Check to make sure the given table is writable.  If it is not
  39. ** writable, generate an error message and return 1.  If it is
  40. ** writable return 0;
  41. */
  42. int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
  43.   if( (pTab->readOnly && (pParse->db->flags & SQLITE_WriteSchema)==0
  44.         && pParse->nested==0) 
  45. #ifndef SQLITE_OMIT_VIRTUALTABLE
  46.       || (pTab->pMod && pTab->pMod->pModule->xUpdate==0)
  47. #endif
  48.   ){
  49.     sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
  50.     return 1;
  51.   }
  52. #ifndef SQLITE_OMIT_VIEW
  53.   if( !viewOk && pTab->pSelect ){
  54.     sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
  55.     return 1;
  56.   }
  57. #endif
  58.   return 0;
  59. }
  60. /*
  61. ** Generate code that will open a table for reading.
  62. */
  63. void sqlite3OpenTable(
  64.   Parse *p,       /* Generate code into this VDBE */
  65.   int iCur,       /* The cursor number of the table */
  66.   int iDb,        /* The database index in sqlite3.aDb[] */
  67.   Table *pTab,    /* The table to be opened */
  68.   int opcode      /* OP_OpenRead or OP_OpenWrite */
  69. ){
  70.   Vdbe *v;
  71.   if( IsVirtual(pTab) ) return;
  72.   v = sqlite3GetVdbe(p);
  73.   assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
  74.   sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite), pTab->zName);
  75.   sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, pTab->nCol);
  76.   sqlite3VdbeAddOp3(v, opcode, iCur, pTab->tnum, iDb);
  77.   VdbeComment((v, "%s", pTab->zName));
  78. }
  79. #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
  80. /*
  81. ** Evaluate a view and store its result in an ephemeral table.  The
  82. ** pWhere argument is an optional WHERE clause that restricts the
  83. ** set of rows in the view that are to be added to the ephemeral table.
  84. */
  85. void sqlite3MaterializeView(
  86.   Parse *pParse,       /* Parsing context */
  87.   Select *pView,       /* View definition */
  88.   Expr *pWhere,        /* Optional WHERE clause to be added */
  89.   int iCur             /* Cursor number for ephemerial table */
  90. ){
  91.   SelectDest dest;
  92.   Select *pDup;
  93.   sqlite3 *db = pParse->db;
  94.   pDup = sqlite3SelectDup(db, pView);
  95.   if( pWhere ){
  96.     SrcList *pFrom;
  97.     
  98.     pWhere = sqlite3ExprDup(db, pWhere);
  99.     pFrom = sqlite3SrcListAppendFromTerm(pParse, 0, 0, 0, 0, pDup, 0, 0);
  100.     pDup = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0);
  101.   }
  102.   sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
  103.   sqlite3Select(pParse, pDup, &dest, 0, 0, 0, 0);
  104.   sqlite3SelectDelete(pDup);
  105. }
  106. #endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */
  107. /*
  108. ** Generate code for a DELETE FROM statement.
  109. **
  110. **     DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL;
  111. **                 ________/       ________________/
  112. **                  pTabList              pWhere
  113. */
  114. void sqlite3DeleteFrom(
  115.   Parse *pParse,         /* The parser context */
  116.   SrcList *pTabList,     /* The table from which we should delete things */
  117.   Expr *pWhere           /* The WHERE clause.  May be null */
  118. ){
  119.   Vdbe *v;               /* The virtual database engine */
  120.   Table *pTab;           /* The table from which records will be deleted */
  121.   const char *zDb;       /* Name of database holding pTab */
  122.   int end, addr = 0;     /* A couple addresses of generated code */
  123.   int i;                 /* Loop counter */
  124.   WhereInfo *pWInfo;     /* Information about the WHERE clause */
  125.   Index *pIdx;           /* For looping over indices of the table */
  126.   int iCur;              /* VDBE Cursor number for pTab */
  127.   sqlite3 *db;           /* Main database structure */
  128.   AuthContext sContext;  /* Authorization context */
  129.   int oldIdx = -1;       /* Cursor for the OLD table of AFTER triggers */
  130.   NameContext sNC;       /* Name context to resolve expressions in */
  131.   int iDb;               /* Database number */
  132.   int memCnt = 0;        /* Memory cell used for change counting */
  133. #ifndef SQLITE_OMIT_TRIGGER
  134.   int isView;                  /* True if attempting to delete from a view */
  135.   int triggers_exist = 0;      /* True if any triggers exist */
  136. #endif
  137.   int iBeginAfterTrigger;      /* Address of after trigger program */
  138.   int iEndAfterTrigger;        /* Exit of after trigger program */
  139.   int iBeginBeforeTrigger;     /* Address of before trigger program */
  140.   int iEndBeforeTrigger;       /* Exit of before trigger program */
  141.   u32 old_col_mask = 0;        /* Mask of OLD.* columns in use */
  142.   sContext.pParse = 0;
  143.   db = pParse->db;
  144.   if( pParse->nErr || db->mallocFailed ){
  145.     goto delete_from_cleanup;
  146.   }
  147.   assert( pTabList->nSrc==1 );
  148.   /* Locate the table which we want to delete.  This table has to be
  149.   ** put in an SrcList structure because some of the subroutines we
  150.   ** will be calling are designed to work with multiple tables and expect
  151.   ** an SrcList* parameter instead of just a Table* parameter.
  152.   */
  153.   pTab = sqlite3SrcListLookup(pParse, pTabList);
  154.   if( pTab==0 )  goto delete_from_cleanup;
  155.   /* Figure out if we have any triggers and if the table being
  156.   ** deleted from is a view
  157.   */
  158. #ifndef SQLITE_OMIT_TRIGGER
  159.   triggers_exist = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0);
  160.   isView = pTab->pSelect!=0;
  161. #else
  162. # define triggers_exist 0
  163. # define isView 0
  164. #endif
  165. #ifdef SQLITE_OMIT_VIEW
  166. # undef isView
  167. # define isView 0
  168. #endif
  169.   if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){
  170.     goto delete_from_cleanup;
  171.   }
  172.   iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  173.   assert( iDb<db->nDb );
  174.   zDb = db->aDb[iDb].zName;
  175.   if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
  176.     goto delete_from_cleanup;
  177.   }
  178.   /* If pTab is really a view, make sure it has been initialized.
  179.   */
  180.   if( sqlite3ViewGetColumnNames(pParse, pTab) ){
  181.     goto delete_from_cleanup;
  182.   }
  183.   /* Allocate a cursor used to store the old.* data for a trigger.
  184.   */
  185.   if( triggers_exist ){ 
  186.     oldIdx = pParse->nTab++;
  187.   }
  188.   /* Assign  cursor number to the table and all its indices.
  189.   */
  190.   assert( pTabList->nSrc==1 );
  191.   iCur = pTabList->a[0].iCursor = pParse->nTab++;
  192.   for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
  193.     pParse->nTab++;
  194.   }
  195.   /* Start the view context
  196.   */
  197.   if( isView ){
  198.     sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
  199.   }
  200.   /* Begin generating code.
  201.   */
  202.   v = sqlite3GetVdbe(pParse);
  203.   if( v==0 ){
  204.     goto delete_from_cleanup;
  205.   }
  206.   if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
  207.   sqlite3BeginWriteOperation(pParse, triggers_exist, iDb);
  208.   if( triggers_exist ){
  209.     int orconf = ((pParse->trigStack)?pParse->trigStack->orconf:OE_Default);
  210.     int iGoto = sqlite3VdbeAddOp0(v, OP_Goto);
  211.     addr = sqlite3VdbeMakeLabel(v);
  212.     iBeginBeforeTrigger = sqlite3VdbeCurrentAddr(v);
  213.     (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_BEFORE, pTab,
  214.         -1, oldIdx, orconf, addr, &old_col_mask, 0);
  215.     iEndBeforeTrigger = sqlite3VdbeAddOp0(v, OP_Goto);
  216.     iBeginAfterTrigger = sqlite3VdbeCurrentAddr(v);
  217.     (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_AFTER, pTab, -1,
  218.         oldIdx, orconf, addr, &old_col_mask, 0);
  219.     iEndAfterTrigger = sqlite3VdbeAddOp0(v, OP_Goto);
  220.     sqlite3VdbeJumpHere(v, iGoto);
  221.   }
  222.   /* If we are trying to delete from a view, realize that view into
  223.   ** a ephemeral table.
  224.   */
  225.   if( isView ){
  226.     sqlite3MaterializeView(pParse, pTab->pSelect, pWhere, iCur);
  227.   }
  228.   /* Resolve the column names in the WHERE clause.
  229.   */
  230.   memset(&sNC, 0, sizeof(sNC));
  231.   sNC.pParse = pParse;
  232.   sNC.pSrcList = pTabList;
  233.   if( sqlite3ExprResolveNames(&sNC, pWhere) ){
  234.     goto delete_from_cleanup;
  235.   }
  236.   /* Initialize the counter of the number of rows deleted, if
  237.   ** we are counting rows.
  238.   */
  239.   if( db->flags & SQLITE_CountRows ){
  240.     memCnt = ++pParse->nMem;
  241.     sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt);
  242.   }
  243.   /* Special case: A DELETE without a WHERE clause deletes everything.
  244.   ** It is easier just to erase the whole table.  Note, however, that
  245.   ** this means that the row change count will be incorrect.
  246.   */
  247.   if( pWhere==0 && !triggers_exist && !IsVirtual(pTab) ){
  248.     if( db->flags & SQLITE_CountRows ){
  249.       /* If counting rows deleted, just count the total number of
  250.       ** entries in the table. */
  251.       int addr2;
  252.       if( !isView ){
  253.         sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
  254.       }
  255.       sqlite3VdbeAddOp2(v, OP_Rewind, iCur, sqlite3VdbeCurrentAddr(v)+2);
  256.       addr2 = sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1);
  257.       sqlite3VdbeAddOp2(v, OP_Next, iCur, addr2);
  258.       sqlite3VdbeAddOp1(v, OP_Close, iCur);
  259.     }
  260.     if( !isView ){
  261.       sqlite3VdbeAddOp2(v, OP_Clear, pTab->tnum, iDb);
  262.       if( !pParse->nested ){
  263.         sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC);
  264.       }
  265.       for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
  266.         assert( pIdx->pSchema==pTab->pSchema );
  267.         sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb);
  268.       }
  269.     }
  270.   } 
  271.   /* The usual case: There is a WHERE clause so we have to scan through
  272.   ** the table and pick which records to delete.
  273.   */
  274.   else{
  275.     int iRowid = ++pParse->nMem;    /* Used for storing rowid values. */
  276.     /* Begin the database scan
  277.     */
  278.     pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0);
  279.     if( pWInfo==0 ) goto delete_from_cleanup;
  280.     /* Remember the rowid of every item to be deleted.
  281.     */
  282.     sqlite3VdbeAddOp2(v, IsVirtual(pTab) ? OP_VRowid : OP_Rowid, iCur, iRowid);
  283.     sqlite3VdbeAddOp1(v, OP_FifoWrite, iRowid);
  284.     if( db->flags & SQLITE_CountRows ){
  285.       sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1);
  286.     }
  287.     /* End the database scan loop.
  288.     */
  289.     sqlite3WhereEnd(pWInfo);
  290.     /* Open the pseudo-table used to store OLD if there are triggers.
  291.     */
  292.     if( triggers_exist ){
  293.       sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, pTab->nCol);
  294.       sqlite3VdbeAddOp1(v, OP_OpenPseudo, oldIdx);
  295.     }
  296.     /* Delete every item whose key was written to the list during the
  297.     ** database scan.  We have to delete items after the scan is complete
  298.     ** because deleting an item can change the scan order.
  299.     */
  300.     end = sqlite3VdbeMakeLabel(v);
  301.     if( !isView ){
  302.       /* Open cursors for the table we are deleting from and 
  303.       ** all its indices.
  304.       */
  305.       sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite);
  306.     }
  307.     /* This is the beginning of the delete loop. If a trigger encounters
  308.     ** an IGNORE constraint, it jumps back to here.
  309.     */
  310.     if( triggers_exist ){
  311.       sqlite3VdbeResolveLabel(v, addr);
  312.     }
  313.     addr = sqlite3VdbeAddOp2(v, OP_FifoRead, iRowid, end);
  314.     if( triggers_exist ){
  315.       int iData = ++pParse->nMem;   /* For storing row data of OLD table */
  316.       /* If the record is no longer present in the table, jump to the
  317.       ** next iteration of the loop through the contents of the fifo.
  318.       */
  319.       sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, iRowid);
  320.       /* Populate the OLD.* pseudo-table */
  321.       if( old_col_mask ){
  322.         sqlite3VdbeAddOp2(v, OP_RowData, iCur, iData);
  323.       }else{
  324.         sqlite3VdbeAddOp2(v, OP_Null, 0, iData);
  325.       }
  326.       sqlite3VdbeAddOp3(v, OP_Insert, oldIdx, iData, iRowid);
  327.       /* Jump back and run the BEFORE triggers */
  328.       sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginBeforeTrigger);
  329.       sqlite3VdbeJumpHere(v, iEndBeforeTrigger);
  330.     }
  331.     if( !isView ){
  332.       /* Delete the row */
  333. #ifndef SQLITE_OMIT_VIRTUALTABLE
  334.       if( IsVirtual(pTab) ){
  335.         const char *pVtab = (const char *)pTab->pVtab;
  336.         pParse->pVirtualLock = pTab;
  337.         sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVtab, P4_VTAB);
  338.       }else
  339. #endif
  340.       {
  341.         sqlite3GenerateRowDelete(pParse, pTab, iCur, iRowid, pParse->nested==0);
  342.       }
  343.     }
  344.     /* If there are row triggers, close all cursors then invoke
  345.     ** the AFTER triggers
  346.     */
  347.     if( triggers_exist ){
  348.       /* Jump back and run the AFTER triggers */
  349.       sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginAfterTrigger);
  350.       sqlite3VdbeJumpHere(v, iEndAfterTrigger);
  351.     }
  352.     /* End of the delete loop */
  353.     sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
  354.     sqlite3VdbeResolveLabel(v, end);
  355.     /* Close the cursors after the loop if there are no row triggers */
  356.     if( !isView  && !IsVirtual(pTab) ){
  357.       for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
  358.         sqlite3VdbeAddOp2(v, OP_Close, iCur + i, pIdx->tnum);
  359.       }
  360.       sqlite3VdbeAddOp1(v, OP_Close, iCur);
  361.     }
  362.   }
  363.   /*
  364.   ** Return the number of rows that were deleted. If this routine is 
  365.   ** generating code because of a call to sqlite3NestedParse(), do not
  366.   ** invoke the callback function.
  367.   */
  368.   if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){
  369.     sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1);
  370.     sqlite3VdbeSetNumCols(v, 1);
  371.     sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", P4_STATIC);
  372.   }
  373. delete_from_cleanup:
  374.   sqlite3AuthContextPop(&sContext);
  375.   sqlite3SrcListDelete(pTabList);
  376.   sqlite3ExprDelete(pWhere);
  377.   return;
  378. }
  379. /*
  380. ** This routine generates VDBE code that causes a single row of a
  381. ** single table to be deleted.
  382. **
  383. ** The VDBE must be in a particular state when this routine is called.
  384. ** These are the requirements:
  385. **
  386. **   1.  A read/write cursor pointing to pTab, the table containing the row
  387. **       to be deleted, must be opened as cursor number "base".
  388. **
  389. **   2.  Read/write cursors for all indices of pTab must be open as
  390. **       cursor number base+i for the i-th index.
  391. **
  392. **   3.  The record number of the row to be deleted must be stored in
  393. **       memory cell iRowid.
  394. **
  395. ** This routine pops the top of the stack to remove the record number
  396. ** and then generates code to remove both the table record and all index
  397. ** entries that point to that record.
  398. */
  399. void sqlite3GenerateRowDelete(
  400.   Parse *pParse,     /* Parsing context */
  401.   Table *pTab,       /* Table containing the row to be deleted */
  402.   int iCur,          /* Cursor number for the table */
  403.   int iRowid,        /* Memory cell that contains the rowid to delete */
  404.   int count          /* Increment the row change counter */
  405. ){
  406.   int addr;
  407.   Vdbe *v;
  408.   v = pParse->pVdbe;
  409.   addr = sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowid);
  410.   sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, 0);
  411.   sqlite3VdbeAddOp2(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));
  412.   if( count ){
  413.     sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC);
  414.   }
  415.   sqlite3VdbeJumpHere(v, addr);
  416. }
  417. /*
  418. ** This routine generates VDBE code that causes the deletion of all
  419. ** index entries associated with a single row of a single table.
  420. **
  421. ** The VDBE must be in a particular state when this routine is called.
  422. ** These are the requirements:
  423. **
  424. **   1.  A read/write cursor pointing to pTab, the table containing the row
  425. **       to be deleted, must be opened as cursor number "iCur".
  426. **
  427. **   2.  Read/write cursors for all indices of pTab must be open as
  428. **       cursor number iCur+i for the i-th index.
  429. **
  430. **   3.  The "iCur" cursor must be pointing to the row that is to be
  431. **       deleted.
  432. */
  433. void sqlite3GenerateRowIndexDelete(
  434.   Parse *pParse,     /* Parsing and code generating context */
  435.   Table *pTab,       /* Table containing the row to be deleted */
  436.   int iCur,          /* Cursor number for the table */
  437.   int *aRegIdx       /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
  438. ){
  439.   int i;
  440.   Index *pIdx;
  441.   int r1;
  442.   for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
  443.     if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue;
  444.     r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0);
  445.     sqlite3VdbeAddOp3(pParse->pVdbe, OP_IdxDelete, iCur+i, r1,pIdx->nColumn+1);
  446.   }
  447. }
  448. /*
  449. ** Generate code that will assemble an index key and put it in register
  450. ** regOut.  The key with be for index pIdx which is an index on pTab.
  451. ** iCur is the index of a cursor open on the pTab table and pointing to
  452. ** the entry that needs indexing.
  453. **
  454. ** Return a register number which is the first in a block of
  455. ** registers that holds the elements of the index key.  The
  456. ** block of registers has already been deallocated by the time
  457. ** this routine returns.
  458. */
  459. int sqlite3GenerateIndexKey(
  460.   Parse *pParse,     /* Parsing context */
  461.   Index *pIdx,       /* The index for which to generate a key */
  462.   int iCur,          /* Cursor number for the pIdx->pTable table */
  463.   int regOut,        /* Write the new index key to this register */
  464.   int doMakeRec      /* Run the OP_MakeRecord instruction if true */
  465. ){
  466.   Vdbe *v = pParse->pVdbe;
  467.   int j;
  468.   Table *pTab = pIdx->pTable;
  469.   int regBase;
  470.   int nCol;
  471.   nCol = pIdx->nColumn;
  472.   regBase = sqlite3GetTempRange(pParse, nCol+1);
  473.   sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol);
  474.   for(j=0; j<nCol; j++){
  475.     int idx = pIdx->aiColumn[j];
  476.     if( idx==pTab->iPKey ){
  477.       sqlite3VdbeAddOp2(v, OP_SCopy, regBase+nCol, regBase+j);
  478.     }else{
  479.       sqlite3VdbeAddOp3(v, OP_Column, iCur, idx, regBase+j);
  480.       sqlite3ColumnDefault(v, pTab, idx);
  481.     }
  482.   }
  483.   if( doMakeRec ){
  484.     sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut);
  485.     sqlite3IndexAffinityStr(v, pIdx);
  486.     sqlite3ExprCacheAffinityChange(pParse, regBase, nCol+1);
  487.   }
  488.   sqlite3ReleaseTempRange(pParse, regBase, nCol+1);
  489.   return regBase;
  490. }
  491. /* Make sure "isView" gets undefined in case this file becomes part of
  492. ** the amalgamation - so that subsequent files do not see isView as a
  493. ** macro. */
  494. #undef isView