azArg[3] = master_schema;
azArg[3] = zMasterSchema;
static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){  int rc;  BtCursor *curMain;  int size;  Table *pTab;  char *azArg[6];  char zDbNum[30];  int meta[SQLITE_N_BTREE_META];  InitData initData;  /*  ** The master database table has a structure like this  */  static char master_schema[] =      "CREATE TABLE sqlite_master(\n"     "  type text,\n"     "  name text,\n"     "  tbl_name text,\n"     "  rootpage integer,\n"     "  sql text\n"     ")"  ;  static char temp_master_schema[] =      "CREATE TEMP TABLE sqlite_temp_master(\n"     "  type text,\n"     "  name text,\n"     "  tbl_name text,\n"     "  rootpage integer,\n"     "  sql text\n"     ")"  ;  /* The following SQL will read the schema from the master tables.  ** The first version works with SQLite file formats 2 or greater.  ** The second version is for format 1 files.  **  ** Beginning with file format 2, the rowid for new table entries  ** (including entries in sqlite_master) is an increasing integer.  ** So for file format 2 and later, we can play back sqlite_master  ** and all the CREATE statements will appear in the right order.  ** But with file format 1, table entries were random and so we  ** have to make sure the CREATE TABLEs occur before their corresponding  ** CREATE INDEXs.  (We don't have to deal with CREATE VIEW or  ** CREATE TRIGGER in file format 1 because those constructs did  ** not exist then.)   */  static char init_script[] =      "SELECT type, name, rootpage, sql, 1 FROM sqlite_temp_master "     "UNION ALL "     "SELECT type, name, rootpage, sql, 0 FROM sqlite_master";  static char older_init_script[] =      "SELECT type, name, rootpage, sql, 1 FROM sqlite_temp_master "     "UNION ALL "     "SELECT type, name, rootpage, sql, 0 FROM sqlite_master "     "WHERE type='table' "     "UNION ALL "     "SELECT type, name, rootpage, sql, 0 FROM sqlite_master "     "WHERE type='index'";  assert( iDb>=0 && iDb!=1 && iDb<db->nDb );  /* Construct the schema tables: sqlite_master and sqlite_temp_master  */  sqliteSafetyOff(db);  azArg[0] = "table";  azArg[1] = MASTER_NAME;  azArg[2] = "2";  azArg[3] = master_schema;  sprintf(zDbNum, "%d", iDb);  azArg[4] = zDbNum;  azArg[5] = 0;  initData.db = db;  initData.pzErrMsg = pzErrMsg;  sqliteInitCallback(&initData, 5, azArg, 0);  pTab = sqliteFindTable(db, MASTER_NAME, "main");  if( pTab ){    pTab->readOnly = 1;  }  if( iDb==0 ){    azArg[1] = TEMP_MASTER_NAME;    azArg[3] = temp_master_schema;    azArg[4] = "1";    sqliteInitCallback(&initData, 5, azArg, 0);    pTab = sqliteFindTable(db, TEMP_MASTER_NAME, "temp");    if( pTab ){      pTab->readOnly = 1;    }  }  sqliteSafetyOn(db);  /* Create a cursor to hold the database open  */  if( db->aDb[iDb].pBt==0 ) return SQLITE_OK;  rc = sqliteBtreeCursor(db->aDb[iDb].pBt, 2, 0, &curMain);  if( rc ){    sqliteSetString(pzErrMsg, sqlite_error_string(rc), (char*)0);    return rc;  }  /* Get the database meta information  */  rc = sqliteBtreeGetMeta(db->aDb[iDb].pBt, meta);  if( rc ){    sqliteSetString(pzErrMsg, sqlite_error_string(rc), (char*)0);    sqliteBtreeCloseCursor(curMain);    return rc;  }  db->aDb[iDb].schema_cookie = meta[1];  if( iDb==0 ){    db->next_cookie = meta[1];    db->file_format = meta[2];    size = meta[3];    if( size==0 ){ size = MAX_PAGES; }    db->cache_size = size;    db->safety_level = meta[4];    if( db->safety_level==0 ) db->safety_level = 2;    /*    **  file_format==1    Version 2.1.0.    **  file_format==2    Version 2.2.0. Add support for INTEGER PRIMARY KEY.    **  file_format==3    Version 2.6.0. Fix empty-string index bug.    **  file_format==4    Version 2.7.0. Add support for separate numeric and    **                    text datatypes.    */    if( db->file_format==0 ){      /* This happens if the database was initially empty */      db->file_format = 4;    }else if( db->file_format>4 ){      sqliteBtreeCloseCursor(curMain);      sqliteSetString(pzErrMsg, "unsupported file format", (char*)0);      return SQLITE_ERROR;    }  }else if( db->file_format!=meta[2] || db->file_format<4 ){    assert( db->file_format>=4 );    if( meta[2]==0 ){      sqliteSetString(pzErrMsg, "cannot attach empty database: ",         db->aDb[iDb].zName, (char*)0);    }else{      sqliteSetString(pzErrMsg, "incompatible file format in auxiliary "         "database: ", db->aDb[iDb].zName, (char*)0);    }    sqliteBtreeClose(db->aDb[iDb].pBt);    db->aDb[iDb].pBt = 0;    return SQLITE_FORMAT;  }  sqliteBtreeSetCacheSize(db->aDb[iDb].pBt, db->cache_size);  sqliteBtreeSetSafetyLevel(db->aDb[iDb].pBt, meta[4]==0 ? 2 : meta[4]);  /* Read the schema information out of the schema tables  */  assert( db->init.busy );  sqliteSafetyOff(db);  if( iDb==0 ){    rc = sqlite_exec(db,         db->file_format>=2 ? init_script : older_init_script,        sqliteInitCallback, &initData, 0);  }else{    char *zSql = 0;    sqliteSetString(&zSql,        "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",       db->aDb[iDb].zName, "\".sqlite_master", (char*)0);    rc = sqlite_exec(db, zSql, sqliteInitCallback, &initData, 0);    sqliteFree(zSql);  }  sqliteSafetyOn(db);  sqliteBtreeCloseCursor(curMain);  if( sqlite_malloc_failed ){    sqliteSetString(pzErrMsg, "out of memory", (char*)0);    rc = SQLITE_NOMEM;    sqliteResetInternalSchema(db, 0);  }  if( rc==SQLITE_OK ){    DbSetProperty(db, iDb, DB_SchemaLoaded);    if( iDb==0 ){      DbSetProperty(db, 1, DB_SchemaLoaded);    }  }else{    sqliteResetInternalSchema(db, iDb);  }  return rc;}