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

📄 alter.c

📁 sqlite-3.4.1,嵌入式数据库.是一个功能强大的开源数据库,给学习和研发以及小型公司的发展带来了全所未有的好处.
💻 C
📖 第 1 页 / 共 2 页
字号:
  ** that the table is being renamed to.  */  if( strlen(pTab->zName)>6 && 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) ){    sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName);    goto exit_rename_table;  }  if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){    goto exit_rename_table;  }#ifndef SQLITE_OMIT_AUTHORIZATION  /* Invoke the authorization callback. */  if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){    goto exit_rename_table;  }#endif#ifndef SQLITE_OMIT_VIRTUALTABLE  if( sqlite3ViewGetColumnNames(pParse, pTab) ){    goto exit_rename_table;  }  if( IsVirtual(pTab) && pTab->pMod->pModule->xRename ){    isVirtualRename = 1;  }#endif  /* Begin a transaction and code the VerifyCookie for database iDb.   ** Then modify the schema cookie (since the ALTER TABLE modifies the  ** schema). Open a statement transaction if the table is a virtual  ** table.  */  v = sqlite3GetVdbe(pParse);  if( v==0 ){    goto exit_rename_table;  }  sqlite3BeginWriteOperation(pParse, isVirtualRename, iDb);  sqlite3ChangeCookie(db, v, iDb);  /* If this is a virtual table, invoke the xRename() function if  ** one is defined. The xRename() callback will modify the names  ** of any resources used by the v-table implementation (including other  ** SQLite tables) that are identified by the name of the virtual table.  */#ifndef SQLITE_OMIT_VIRTUALTABLE  if( isVirtualRename ){    sqlite3VdbeOp3(v, OP_String8, 0, 0, zName, 0);    sqlite3VdbeOp3(v, OP_VRename, 0, 0, (const char*)pTab->pVtab, P3_VTAB);  }#endif  /* figure out how many UTF-8 characters are in zName */  zTabName = pTab->zName;  nTabName = sqlite3Utf8CharLen(zTabName, -1);  /* Modify the sqlite_master table to use the new table name. */  sqlite3NestedParse(pParse,      "UPDATE %Q.%s SET "#ifdef SQLITE_OMIT_TRIGGER          "sql = sqlite_rename_table(sql, %Q), "#else          "sql = CASE "            "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)"            "ELSE sqlite_rename_table(sql, %Q) END, "#endif          "tbl_name = %Q, "          "name = CASE "            "WHEN type='table' THEN %Q "            "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN "             "'sqlite_autoindex_' || %Q || substr(name,%d+18,10) "            "ELSE name END "      "WHERE tbl_name=%Q AND "          "(type='table' OR type='index' OR type='trigger');",       zDb, SCHEMA_TABLE(iDb), zName, zName, zName, #ifndef SQLITE_OMIT_TRIGGER      zName,#endif      zName, nTabName, zTabName  );#ifndef SQLITE_OMIT_AUTOINCREMENT  /* If the sqlite_sequence table exists in this database, then update   ** it with the new table name.  */  if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){    sqlite3NestedParse(pParse,        "UPDATE %Q.sqlite_sequence set name = %Q WHERE name = %Q",        zDb, zName, pTab->zName);  }#endif#ifndef SQLITE_OMIT_TRIGGER  /* If there are TEMP triggers on this table, modify the sqlite_temp_master  ** table. Don't do this if the table being ALTERed is itself located in  ** the temp database.  */  if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){    sqlite3NestedParse(pParse,         "UPDATE sqlite_temp_master SET "            "sql = sqlite_rename_trigger(sql, %Q), "            "tbl_name = %Q "            "WHERE %s;", zName, zName, zWhere);    sqliteFree(zWhere);  }#endif  /* Drop and reload the internal table schema. */  reloadTableSchema(pParse, pTab, zName);exit_rename_table:  sqlite3SrcListDelete(pSrc);  sqliteFree(zName);}/*** This function is called after an "ALTER TABLE ... ADD" statement** has been parsed. Argument pColDef contains the text of the new** column definition.**** The Table structure pParse->pNewTable was extended to include** the new column during parsing.*/void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){  Table *pNew;              /* Copy of pParse->pNewTable */  Table *pTab;              /* Table being altered */  int iDb;                  /* Database number */  const char *zDb;          /* Database name */  const char *zTab;         /* Table name */  char *zCol;               /* Null-terminated column definition */  Column *pCol;             /* The new column */  Expr *pDflt;              /* Default value for the new column */  if( pParse->nErr ) return;  pNew = pParse->pNewTable;  assert( pNew );  iDb = sqlite3SchemaToIndex(pParse->db, pNew->pSchema);  zDb = pParse->db->aDb[iDb].zName;  zTab = pNew->zName;  pCol = &pNew->aCol[pNew->nCol-1];  pDflt = pCol->pDflt;  pTab = sqlite3FindTable(pParse->db, zTab, zDb);  assert( pTab );#ifndef SQLITE_OMIT_AUTHORIZATION  /* Invoke the authorization callback. */  if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){    return;  }#endif  /* If the default value for the new column was specified with a   ** literal NULL, then set pDflt to 0. This simplifies checking  ** for an SQL NULL default below.  */  if( pDflt && pDflt->op==TK_NULL ){    pDflt = 0;  }  /* Check that the new column is not specified as PRIMARY KEY or UNIQUE.  ** If there is a NOT NULL constraint, then the default value for the  ** column must not be NULL.  */  if( pCol->isPrimKey ){    sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");    return;  }  if( pNew->pIndex ){    sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column");    return;  }  if( pCol->notNull && !pDflt ){    sqlite3ErrorMsg(pParse,         "Cannot add a NOT NULL column with default value NULL");    return;  }  /* Ensure the default expression is something that sqlite3ValueFromExpr()  ** can handle (i.e. not CURRENT_TIME etc.)  */  if( pDflt ){    sqlite3_value *pVal;    if( sqlite3ValueFromExpr(pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){      /* malloc() has failed */      return;    }    if( !pVal ){      sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default");      return;    }    sqlite3ValueFree(pVal);  }  /* Modify the CREATE TABLE statement. */  zCol = sqliteStrNDup((char*)pColDef->z, pColDef->n);  if( zCol ){    char *zEnd = &zCol[pColDef->n-1];    while( (zEnd>zCol && *zEnd==';') || isspace(*(unsigned char *)zEnd) ){      *zEnd-- = '\0';    }    sqlite3NestedParse(pParse,         "UPDATE %Q.%s SET "          "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d,length(sql)) "        "WHERE type = 'table' AND name = %Q",       zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1,      zTab    );    sqliteFree(zCol);  }  /* If the default value of the new column is NULL, then set the file  ** format to 2. If the default value of the new column is not NULL,  ** the file format becomes 3.  */  sqlite3MinimumFileFormat(pParse, iDb, pDflt ? 3 : 2);  /* Reload the schema of the modified table. */  reloadTableSchema(pParse, pTab, pTab->zName);}/*** This function is called by the parser after the table-name in** an "ALTER TABLE <table-name> ADD" statement is parsed. Argument ** pSrc is the full-name of the table being altered.**** This routine makes a (partial) copy of the Table structure** for the table being altered and sets Parse.pNewTable to point** to it. Routines called by the parser as the column definition** is parsed (i.e. sqlite3AddColumn()) add the new Column data to ** the copy. The copy of the Table structure is deleted by tokenize.c ** after parsing is finished.**** Routine sqlite3AlterFinishAddColumn() will be called to complete** coding the "ALTER TABLE ... ADD" statement.*/void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){  Table *pNew;  Table *pTab;  Vdbe *v;  int iDb;  int i;  int nAlloc;  /* Look up the table being altered. */  assert( pParse->pNewTable==0 );  if( sqlite3MallocFailed() ) goto exit_begin_add_column;  pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase);  if( !pTab ) goto exit_begin_add_column;#ifndef SQLITE_OMIT_VIRTUALTABLE  if( IsVirtual(pTab) ){    sqlite3ErrorMsg(pParse, "virtual tables may not be altered");    goto exit_begin_add_column;  }#endif  /* Make sure this is not an attempt to ALTER a view. */  if( pTab->pSelect ){    sqlite3ErrorMsg(pParse, "Cannot add a column to a view");    goto exit_begin_add_column;  }  assert( pTab->addColOffset>0 );  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);  /* Put a copy of the Table struct in Parse.pNewTable for the  ** sqlite3AddColumn() function and friends to modify.  */  pNew = (Table *)sqliteMalloc(sizeof(Table));  if( !pNew ) goto exit_begin_add_column;  pParse->pNewTable = pNew;  pNew->nRef = 1;  pNew->nCol = pTab->nCol;  assert( pNew->nCol>0 );  nAlloc = (((pNew->nCol-1)/8)*8)+8;  assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 );  pNew->aCol = (Column *)sqliteMalloc(sizeof(Column)*nAlloc);  pNew->zName = sqliteStrDup(pTab->zName);  if( !pNew->aCol || !pNew->zName ){    goto exit_begin_add_column;  }  memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol);  for(i=0; i<pNew->nCol; i++){    Column *pCol = &pNew->aCol[i];    pCol->zName = sqliteStrDup(pCol->zName);    pCol->zColl = 0;    pCol->zType = 0;    pCol->pDflt = 0;  }  pNew->pSchema = pParse->db->aDb[iDb].pSchema;  pNew->addColOffset = pTab->addColOffset;  pNew->nRef = 1;  /* Begin a transaction and increment the schema cookie.  */  sqlite3BeginWriteOperation(pParse, 0, iDb);  v = sqlite3GetVdbe(pParse);  if( !v ) goto exit_begin_add_column;  sqlite3ChangeCookie(pParse->db, v, iDb);exit_begin_add_column:  sqlite3SrcListDelete(pSrc);  return;}#endif  /* SQLITE_ALTER_TABLE */

⌨️ 快捷键说明

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