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

📄 attach.c

📁 最新的sqlite3.6.2源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  if( sqlite3BtreeIsInReadTrans(pDb->pBt) ){    sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);    goto detach_error;  }  sqlite3BtreeClose(pDb->pBt);  pDb->pBt = 0;  pDb->pSchema = 0;  sqlite3ResetInternalSchema(db, 0);  return;detach_error:  sqlite3_result_error(context, zErr, -1);}/*** This procedure generates VDBE code for a single invocation of either the** sqlite_detach() or sqlite_attach() SQL user functions.*/static void codeAttach(  Parse *pParse,       /* The parser context */  int type,            /* Either SQLITE_ATTACH or SQLITE_DETACH */  const char *zFunc,   /* Either "sqlite_attach" or "sqlite_detach */  int nFunc,           /* Number of args to pass to zFunc */  Expr *pAuthArg,      /* Expression to pass to authorization callback */  Expr *pFilename,     /* Name of database file */  Expr *pDbname,       /* Name of the database to use internally */  Expr *pKey           /* Database key for encryption extension */){  int rc;  NameContext sName;  Vdbe *v;  FuncDef *pFunc;  sqlite3* db = pParse->db;  int regArgs;#ifndef SQLITE_OMIT_AUTHORIZATION  assert( db->mallocFailed || pAuthArg );  if( pAuthArg ){    char *zAuthArg = sqlite3NameFromToken(db, &pAuthArg->span);    if( !zAuthArg ){      goto attach_end;    }    rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0);    sqlite3DbFree(db, zAuthArg);    if(rc!=SQLITE_OK ){      goto attach_end;    }  }#endif /* SQLITE_OMIT_AUTHORIZATION */  memset(&sName, 0, sizeof(NameContext));  sName.pParse = pParse;  if(       SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) ||      SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) ||      SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey))  ){    pParse->nErr++;    goto attach_end;  }  v = sqlite3GetVdbe(pParse);  regArgs = sqlite3GetTempRange(pParse, 4);  sqlite3ExprCode(pParse, pFilename, regArgs);  sqlite3ExprCode(pParse, pDbname, regArgs+1);  sqlite3ExprCode(pParse, pKey, regArgs+2);  assert( v || db->mallocFailed );  if( v ){    sqlite3VdbeAddOp3(v, OP_Function, 0, regArgs+3-nFunc, regArgs+3);    sqlite3VdbeChangeP5(v, nFunc);    pFunc = sqlite3FindFunction(db, zFunc, strlen(zFunc), nFunc, SQLITE_UTF8,0);    sqlite3VdbeChangeP4(v, -1, (char *)pFunc, P4_FUNCDEF);    /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this    ** statement only). For DETACH, set it to false (expire all existing    ** statements).    */    sqlite3VdbeAddOp1(v, OP_Expire, (type==SQLITE_ATTACH));  }  attach_end:  sqlite3ExprDelete(db, pFilename);  sqlite3ExprDelete(db, pDbname);  sqlite3ExprDelete(db, pKey);}/*** Called by the parser to compile a DETACH statement.****     DETACH pDbname*/void sqlite3Detach(Parse *pParse, Expr *pDbname){  codeAttach(pParse, SQLITE_DETACH, "sqlite_detach", 1, pDbname, 0, 0, pDbname);}/*** Called by the parser to compile an ATTACH statement.****     ATTACH p AS pDbname KEY pKey*/void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){  codeAttach(pParse, SQLITE_ATTACH, "sqlite_attach", 3, p, p, pDbname, pKey);}#endif /* SQLITE_OMIT_ATTACH *//*** Register the functions sqlite_attach and sqlite_detach.*/void sqlite3AttachFunctions(sqlite3 *db){#ifndef SQLITE_OMIT_ATTACH  static const int enc = SQLITE_UTF8;  sqlite3CreateFunc(db, "sqlite_attach", 3, enc, 0, attachFunc, 0, 0);  sqlite3CreateFunc(db, "sqlite_detach", 1, enc, 0, detachFunc, 0, 0);#endif}/*** Initialize a DbFixer structure.  This routine must be called prior** to passing the structure to one of the sqliteFixAAAA() routines below.**** The return value indicates whether or not fixation is required.  TRUE** means we do need to fix the database references, FALSE means we do not.*/int sqlite3FixInit(  DbFixer *pFix,      /* The fixer to be initialized */  Parse *pParse,      /* Error messages will be written here */  int iDb,            /* This is the database that must be used */  const char *zType,  /* "view", "trigger", or "index" */  const Token *pName  /* Name of the view, trigger, or index */){  sqlite3 *db;  if( iDb<0 || iDb==1 ) return 0;  db = pParse->db;  assert( db->nDb>iDb );  pFix->pParse = pParse;  pFix->zDb = db->aDb[iDb].zName;  pFix->zType = zType;  pFix->pName = pName;  return 1;}/*** The following set of routines walk through the parse tree and assign** a specific database to all table references where the database name** was left unspecified in the original SQL statement.  The pFix structure** must have been initialized by a prior call to sqlite3FixInit().**** These routines are used to make sure that an index, trigger, or** view in one database does not refer to objects in a different database.** (Exception: indices, triggers, and views in the TEMP database are** allowed to refer to anything.)  If a reference is explicitly made** to an object in a different database, an error message is added to** pParse->zErrMsg and these routines return non-zero.  If everything** checks out, these routines return 0.*/int sqlite3FixSrcList(  DbFixer *pFix,       /* Context of the fixation */  SrcList *pList       /* The Source list to check and modify */){  int i;  const char *zDb;  struct SrcList_item *pItem;  if( pList==0 ) return 0;  zDb = pFix->zDb;  for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){    if( pItem->zDatabase==0 ){      pItem->zDatabase = sqlite3DbStrDup(pFix->pParse->db, zDb);    }else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){      sqlite3ErrorMsg(pFix->pParse,         "%s %T cannot reference objects in database %s",         pFix->zType, pFix->pName, pItem->zDatabase);      return 1;    }#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)    if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;    if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;#endif  }  return 0;}#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)int sqlite3FixSelect(  DbFixer *pFix,       /* Context of the fixation */  Select *pSelect      /* The SELECT statement to be fixed to one database */){  while( pSelect ){    if( sqlite3FixExprList(pFix, pSelect->pEList) ){      return 1;    }    if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){      return 1;    }    if( sqlite3FixExpr(pFix, pSelect->pWhere) ){      return 1;    }    if( sqlite3FixExpr(pFix, pSelect->pHaving) ){      return 1;    }    pSelect = pSelect->pPrior;  }  return 0;}int sqlite3FixExpr(  DbFixer *pFix,     /* Context of the fixation */  Expr *pExpr        /* The expression to be fixed to one database */){  while( pExpr ){    if( sqlite3FixSelect(pFix, pExpr->pSelect) ){      return 1;    }    if( sqlite3FixExprList(pFix, pExpr->pList) ){      return 1;    }    if( sqlite3FixExpr(pFix, pExpr->pRight) ){      return 1;    }    pExpr = pExpr->pLeft;  }  return 0;}int sqlite3FixExprList(  DbFixer *pFix,     /* Context of the fixation */  ExprList *pList    /* The expression to be fixed to one database */){  int i;  struct ExprList_item *pItem;  if( pList==0 ) return 0;  for(i=0, pItem=pList->a; i<pList->nExpr; i++, pItem++){    if( sqlite3FixExpr(pFix, pItem->pExpr) ){      return 1;    }  }  return 0;}#endif#ifndef SQLITE_OMIT_TRIGGERint sqlite3FixTriggerStep(  DbFixer *pFix,     /* Context of the fixation */  TriggerStep *pStep /* The trigger step be fixed to one database */){  while( pStep ){    if( sqlite3FixSelect(pFix, pStep->pSelect) ){      return 1;    }    if( sqlite3FixExpr(pFix, pStep->pWhere) ){      return 1;    }    if( sqlite3FixExprList(pFix, pStep->pExprList) ){      return 1;    }    pStep = pStep->pNext;  }  return 0;}#endif

⌨️ 快捷键说明

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