// File: /workspace/github_c_makefile_star2_O3/barabo[P]advanced-shell-history/src/sqlite3.c
// Function: sqlite3RunVacuum
SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
  int rc = SQLITE_OK;     /* Return code from service routines */
  Btree *pMain;           /* The database being vacuumed */
  Btree *pTemp;           /* The temporary database we vacuum into */
  char *zSql = 0;         /* SQL statements */
  int saved_flags;        /* Saved value of the db->flags */
  int saved_nChange;      /* Saved value of db->nChange */
  int saved_nTotalChange; /* Saved value of db->nTotalChange */
  void (*saved_xTrace)(void*,const char*);  /* Saved db->xTrace */
  Db *pDb = 0;            /* Database to detach at end of vacuum */
  int isMemDb;            /* True if vacuuming a :memory: database */
  int nRes;               /* Bytes of reserved space at the end of each page */
  int nDb;                /* Number of attached databases */

  if( !db->autoCommit ){
    sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
    return SQLITE_ERROR;
  }
  if( db->nVdbeActive>1 ){
    sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress");
    return SQLITE_ERROR;
  }

  /* Save the current value of the database flags so that it can be 
  ** restored before returning. Then set the writable-schema flag, and
  ** disable CHECK and foreign key constraints.  */
  saved_flags = db->flags;
  saved_nChange = db->nChange;
  saved_nTotalChange = db->nTotalChange;
  saved_xTrace = db->xTrace;
  db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin;
  db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder);
  db->xTrace = 0;

  pMain = db->aDb[0].pBt;
  isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));

  /* Attach the temporary database as 'vacuum_db'. The synchronous pragma
  ** can be set to 'off' for this file, as it is not recovered if a crash
  ** occurs anyway. The integrity of the database is maintained by a
  ** (possibly synchronous) transaction opened on the main database before
  ** sqlite3BtreeCopyFile() is called.
  **
  ** An optimisation would be to use a non-journaled pager.
  ** (Later:) I tried setting "PRAGMA vacuum_db.journal_mode=OFF" but
  ** that actually made the VACUUM run slower.  Very little journalling
  ** actually occurs when doing a vacuum since the vacuum_db is initially
  ** empty.  Only the journal header is written.  Apparently it takes more
  ** time to parse and run the PRAGMA to turn journalling off than it does
  ** to write the journal header file.
  */
  nDb = db->nDb;
  if( sqlite3TempInMemory(db) ){
    zSql = "ATTACH ':memory:' AS vacuum_db;";
  }else{
    zSql = "ATTACH '' AS vacuum_db;";
  }
  rc = execSql(db, pzErrMsg, zSql);
  if( db->nDb>nDb ){
    pDb = &db->aDb[db->nDb-1];
    assert( strcmp(pDb->zName,"vacuum_db")==0 );
  }
  if( rc!=SQLITE_OK ) goto end_of_vacuum;
  pTemp = db->aDb[db->nDb-1].pBt;

  /* The call to execSql() to attach the temp database has left the file
  ** locked (as there was more than one active statement when the transaction
  ** to read the schema was concluded. Unlock it here so that this doesn't
  ** cause problems for the call to BtreeSetPageSize() below.  */
  sqlite3BtreeCommit(pTemp);

  nRes = sqlite3BtreeGetReserve(pMain);

  /* A VACUUM cannot change the pagesize of an encrypted database. */
#ifdef SQLITE_HAS_CODEC
  if( db->nextPagesize ){
    extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
    int nKey;
    char *zKey;
    sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
    if( nKey ) db->nextPagesize = 0;
  }
#endif

  rc = execSql(db, pzErrMsg, "PRAGMA vacuum_db.synchronous=OFF");
  if( rc!=SQLITE_OK ) goto end_of_vacuum;

  /* Begin a transaction and take an exclusive lock on the main database
  ** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below,
  ** to ensure that we do not try to change the page-size on a WAL database.
  */
  rc = execSql(db, pzErrMsg, "BEGIN;");
  if( rc!=SQLITE_OK ) goto end_of_vacuum;
  rc = sqlite3BtreeBeginTrans(pMain, 2);
  if( rc!=SQLITE_OK ) goto end_of_vacuum;

  /* Do not attempt to change the page size for a WAL database */
  if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain))
                                               ==PAGER_JOURNALMODE_WAL ){
    db->nextPagesize = 0;
  }

  if( sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), nRes, 0)
   || (!isMemDb && sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes, 0))
   || NEVER(db->mallocFailed)
  ){
    rc = SQLITE_NOMEM;
    goto end_of_vacuum;
  }

#ifndef SQLITE_OMIT_AUTOVACUUM
  sqlite3BtreeSetAutoVacuum(pTemp, db->nextAutovac>=0 ? db->nextAutovac :
                                           sqlite3BtreeGetAutoVacuum(pMain));
#endif

  /* Query the schema of the main database. Create a mirror schema
  ** in the temporary database.
  */
  rc = execExecSql(db, pzErrMsg,
      "SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14) "
      "  FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'"
      "   AND rootpage>0"
  );
  if( rc!=SQLITE_OK ) goto end_of_vacuum;
  rc = execExecSql(db, pzErrMsg,
      "SELECT 'CREATE INDEX vacuum_db.' || substr(sql,14)"
      "  FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %' ");
  if( rc!=SQLITE_OK ) goto end_of_vacuum;
  rc = execExecSql(db, pzErrMsg,
      "SELECT 'CREATE UNIQUE INDEX vacuum_db.' || substr(sql,21) "
      "  FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %'");
  if( rc!=SQLITE_OK ) goto end_of_vacuum;

  /* Loop through the tables in the main database. For each, do
  ** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
  ** the contents to the temporary database.
  */
  rc = execExecSql(db, pzErrMsg,
      "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
      "|| ' SELECT * FROM main.' || quote(name) || ';'"
      "FROM main.sqlite_master "
      "WHERE type = 'table' AND name!='sqlite_sequence' "
      "  AND rootpage>0"
  );
  if( rc!=SQLITE_OK ) goto end_of_vacuum;

  /* Copy over the sequence table
  */
  rc = execExecSql(db, pzErrMsg,
      "SELECT 'DELETE FROM vacuum_db.' || quote(name) || ';' "
      "FROM vacuum_db.sqlite_master WHERE name='sqlite_sequence' "
  );
  if( rc!=SQLITE_OK ) goto end_of_vacuum;
  rc = execExecSql(db, pzErrMsg,
      "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
      "|| ' SELECT * FROM main.' || quote(name) || ';' "
      "FROM vacuum_db.sqlite_master WHERE name=='sqlite_sequence';"
  );
  if( rc!=SQLITE_OK ) goto end_of_vacuum;


  /* Copy the triggers, views, and virtual tables from the main database
  ** over to the temporary database.  None of these objects has any
  ** associated storage, so all we have to do is copy their entries
  ** from the SQLITE_MASTER table.
  */
  rc = execSql(db, pzErrMsg,
      "INSERT INTO vacuum_db.sqlite_master "
      "  SELECT type, name, tbl_name, rootpage, sql"
      "    FROM main.sqlite_master"
      "   WHERE type='view' OR type='trigger'"
      "      OR (type='table' AND rootpage=0)"
  );
  if( rc ) goto end_of_vacuum;

  /* At this point, there is a write transaction open on both the 
  ** vacuum database and the main database. Assuming no error occurs,
  ** both transactions are closed by this block - the main database
  ** transaction by sqlite3BtreeCopyFile() and the other by an explicit
  ** call to sqlite3BtreeCommit().
  */
  {
    u32 meta;
    int i;

    /* This array determines which meta meta values are preserved in the
    ** vacuum.  Even entries are the meta value number and odd entries
    ** are an increment to apply to the meta value after the vacuum.
    ** The increment is used to increase the schema cookie so that other
    ** connections to the same database will know to reread the schema.
    */
    static const unsigned char aCopy[] = {
       BTREE_SCHEMA_VERSION,     1,  /* Add one to the old schema cookie */
       BTREE_DEFAULT_CACHE_SIZE, 0,  /* Preserve the default page cache size */
       BTREE_TEXT_ENCODING,      0,  /* Preserve the text encoding */
       BTREE_USER_VERSION,       0,  /* Preserve the user version */
       BTREE_APPLICATION_ID,     0,  /* Preserve the application id */
    };

    assert( 1==sqlite3BtreeIsInTrans(pTemp) );
    assert( 1==sqlite3BtreeIsInTrans(pMain) );

    /* Copy Btree meta values */
    for(i=0; i<ArraySize(aCopy); i+=2){
      /* GetMeta() and UpdateMeta() cannot fail in this context because
      ** we already have page 1 loaded into cache and marked dirty. */
      sqlite3BtreeGetMeta(pMain, aCopy[i], &meta);
      rc = sqlite3BtreeUpdateMeta(pTemp, aCopy[i], meta+aCopy[i+1]);
      if( NEVER(rc!=SQLITE_OK) ) goto end_of_vacuum;
    }

    rc = sqlite3BtreeCopyFile(pMain, pTemp);
    if( rc!=SQLITE_OK ) goto end_of_vacuum;
    rc = sqlite3BtreeCommit(pTemp);
    if( rc!=SQLITE_OK ) goto end_of_vacuum;
#ifndef SQLITE_OMIT_AUTOVACUUM
    sqlite3BtreeSetAutoVacuum(pMain, sqlite3BtreeGetAutoVacuum(pTemp));
#endif
  }

  assert( rc==SQLITE_OK );
  rc = sqlite3BtreeSetPageSize(pMain, sqlite3BtreeGetPageSize(pTemp), nRes,1);

end_of_vacuum:
  /* Restore the original value of db->flags */
  db->flags = saved_flags;
  db->nChange = saved_nChange;
  db->nTotalChange = saved_nTotalChange;
  db->xTrace = saved_xTrace;
  sqlite3BtreeSetPageSize(pMain, -1, -1, 1);

  /* Currently there is an SQL level transaction open on the vacuum
  ** database. No locks are held on any other files (since the main file
  ** was committed at the btree level). So it safe to end the transaction
  ** by manually setting the autoCommit flag to true and detaching the
  ** vacuum database. The vacuum_db journal file is deleted when the pager
  ** is closed by the DETACH.
  */
  db->autoCommit = 1;

  if( pDb ){
    sqlite3BtreeClose(pDb->pBt);
    pDb->pBt = 0;
    pDb->pSchema = 0;
  }

  /* This both clears the schemas and reduces the size of the db->aDb[]
  ** array. */ 
  sqlite3ResetAllSchemasOfConnection(db);

  return rc;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rsi, %rbx
movq %rdi, %r12
cmpb $0x0, 0x4e(%rsi)
je 0x2fb91
cmpl $0x2, 0x9c(%rbx)
jl 0x2fbb0
leaq 0x4a909(%rip), %rdx     # 0x7a498
jmp 0x2fb98
leaq 0x4a8d8(%rip), %rdx     # 0x7a470
movq %r12, %rdi
movq %rbx, %rsi
xorl %eax, %eax
callq 0x24129
movl $0x1, %r13d
jmp 0x2fd17
movl 0x2c(%rbx), %eax
movl 0x60(%rbx), %ecx
movl %ecx, -0x54(%rbp)
movl 0x64(%rbx), %ecx
movl %ecx, -0x50(%rbp)
movq 0xb8(%rbx), %rcx
movq %rcx, -0x60(%rbp)
movl %eax, -0x58(%rbp)
andl $0xffd5d7ff, %eax       # imm = 0xFFD5D7FF
orl $0x202800, %eax         # imm = 0x202800
movl %eax, 0x2c(%rbx)
movq $0x0, 0xb8(%rbx)
movq 0x20(%rbx), %rax
movq 0x8(%rax), %r14
movq 0x8(%r14), %rax
movq (%rax), %rax
movb 0x12(%rax), %al
movb %al, -0x29(%rbp)
movl 0x28(%rbx), %r15d
cmpb $0x2, 0x4f(%rbx)
leaq 0x4a8ba(%rip), %rax     # 0x7a4c3
leaq 0x4a8d3(%rip), %rdx     # 0x7a4e3
cmoveq %rax, %rdx
movq %rbx, %rdi
movq %r12, %rsi
callq 0x35851
movl %eax, %r13d
movslq 0x28(%rbx), %rax
cmpl %r15d, %eax
jle 0x2fc40
movq 0x20(%rbx), %rcx
movq %rax, %rdx
shlq $0x5, %rdx
leaq (%rcx,%rdx), %r15
addq $-0x20, %r15
jmp 0x2fc43
xorl %r15d, %r15d
testl %r13d, %r13d
jne 0x2fcba
movq %r15, -0x40(%rbp)
movq 0x20(%rbx), %rcx
shlq $0x5, %rax
movq %r14, %r15
movq -0x18(%rcx,%rax), %r14
movq %r14, %rdi
callq 0x358e9
movq (%r15), %rax
movq %r15, -0x38(%rbp)
movq 0x8(%r15), %rcx
movq %rax, 0x8(%rcx)
movl 0x30(%rcx), %r15d
subl 0x34(%rcx), %r15d
leaq 0x4a879(%rip), %rdx     # 0x7a4fb
movq %rbx, %rdi
movq %r12, %rsi
callq 0x35851
testl %eax, %eax
jne 0x2fcaf
movq %r14, -0x48(%rbp)
movl %r15d, -0x4c(%rbp)
leaq 0x4a87c(%rip), %rdx     # 0x7a51c
movq %rbx, %rdi
movq %r12, %rsi
callq 0x35851
testl %eax, %eax
je 0x2fd29
movl %eax, %r13d
movq -0x40(%rbp), %r15
movq -0x38(%rbp), %r14
movl -0x58(%rbp), %eax
movl %eax, 0x2c(%rbx)
movl -0x54(%rbp), %eax
movl %eax, 0x60(%rbx)
movl -0x50(%rbp), %eax
movl %eax, 0x64(%rbx)
movq -0x60(%rbp), %rax
movq %rax, 0xb8(%rbx)
movq (%r14), %rdi
movq 0x8(%r14), %rsi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
movl $0x1, %r8d
callq 0x16c9b
movb $0x1, 0x4e(%rbx)
testq %r15, %r15
je 0x2fd0f
movq 0x8(%r15), %rdi
callq 0x23ec5
xorl %eax, %eax
movq %rax, 0x8(%r15)
movq %rax, 0x18(%r15)
movq %rbx, %rdi
callq 0xdea0
movl %r13d, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq -0x38(%rbp), %r14
movq %r14, %rdi
movl $0x2, %esi
callq 0xd1b2
testl %eax, %eax
movq -0x40(%rbp), %r15
je 0x2fd4a
movl %eax, %r13d
jmp 0x2fcba
movq 0x8(%r14), %rax
movq (%rax), %rcx
cmpb $0x5, 0x9(%rcx)
jne 0x2fd5e
movl $0x0, 0x58(%rbx)
movl 0x30(%rax), %edx
movq -0x48(%rbp), %rax
movq (%rax), %rdi
movq 0x8(%rax), %rsi
movl -0x4c(%rbp), %ecx
xorl %r8d, %r8d
callq 0x16c9b
movl $0x7, %r13d
testl %eax, %eax
jne 0x2fcba
cmpb $0x0, -0x29(%rbp)
je 0x2fdc0
cmpb $0x0, 0x50(%rbx)
jne 0x2fcba
movsbl 0x52(%rbx), %eax
testl %eax, %eax
movq -0x48(%rbp), %rsi
jns 0x2fde5
movq (%r14), %rcx
movq 0x8(%r14), %rax
movq %rcx, 0x8(%rax)
cmpb $0x0, 0x21(%rax)
je 0x2fde3
cmpb $0x1, 0x22(%rax)
movl $0x2, %eax
sbbl $0x0, %eax
jmp 0x2fde5
movl 0x58(%rbx), %edx
movq -0x48(%rbp), %rax
movq (%rax), %rdi
movq 0x8(%rax), %rsi
movl -0x4c(%rbp), %ecx
xorl %r8d, %r8d
callq 0x16c9b
testl %eax, %eax
jne 0x2fcba
jmp 0x2fd8b
xorl %eax, %eax
movq (%rsi), %rdx
movq 0x8(%rsi), %rcx
movq %rdx, 0x8(%rcx)
testb $0x2, 0x26(%rcx)
je 0x2fe00
testl %eax, %eax
setne %dl
cmpb %dl, 0x21(%rcx)
jne 0x2fe0d
testl %eax, %eax
setne 0x21(%rcx)
cmpl $0x2, %eax
sete 0x22(%rcx)
leaq 0x4a70f(%rip), %rdx     # 0x7a523
movq %rbx, %rdi
movq %r12, %rsi
callq 0x3591f
testl %eax, %eax
jne 0x2fd42
leaq 0x4a77d(%rip), %rdx     # 0x7a5ab
movq %rbx, %rdi
movq %r12, %rsi
callq 0x3591f
testl %eax, %eax
jne 0x2fd42
leaq 0x4a7cb(%rip), %rdx     # 0x7a613
movq %rbx, %rdi
movq %r12, %rsi
callq 0x3591f
testl %eax, %eax
jne 0x2fd42
leaq 0x4a827(%rip), %rdx     # 0x7a689
movq %rbx, %rdi
movq %r12, %rsi
callq 0x3591f
testl %eax, %eax
jne 0x2fcaf
leaq 0x4a8c5(%rip), %rdx     # 0x7a741
movq %rbx, %rdi
movq %r12, %rsi
callq 0x3591f
testl %eax, %eax
jne 0x2fcaf
leaq 0x4a91c(%rip), %rdx     # 0x7a7b2
movq %rbx, %rdi
movq %r12, %rsi
callq 0x3591f
testl %eax, %eax
jne 0x2fcaf
leaq 0x4a99d(%rip), %rdx     # 0x7a84d
movq %rbx, %rdi
movq %r12, %rsi
callq 0x35851
testl %eax, %eax
jne 0x2fcaf
movq $-0x2, %r12
leaq 0x4656d(%rip), %r14     # 0x7643e
movzbl 0x2(%r12,%r14), %edx
movq -0x38(%rbp), %rcx
movq (%rcx), %rax
movq 0x8(%rcx), %rcx
movq %rax, 0x8(%rcx)
movq 0x18(%rcx), %rax
movq 0x50(%rax), %rax
movl 0x24(%rax,%rdx,4), %eax
bswapl %eax
movzbl 0x3(%r12,%r14), %ecx
addl %eax, %ecx
movq -0x48(%rbp), %rax
movq (%rax), %rdi
movq 0x8(%rax), %rsi
callq 0xde56
testl %eax, %eax
jne 0x2fcaf
addq $0x2, %r12
cmpq $0x7, %r12
jbe 0x2fed1
movq -0x38(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq 0x359c2
testl %eax, %eax
jne 0x2fcaf
movq -0x48(%rbp), %rdi
callq 0x358e9
testl %eax, %eax
jne 0x2fcaf
movq -0x48(%rbp), %rax
movq (%rax), %rcx
movq 0x8(%rax), %rax
movq %rcx, 0x8(%rax)
cmpb $0x0, 0x21(%rax)
je 0x2ff67
cmpb $0x1, 0x22(%rax)
movl $0x2, %ecx
sbbl $0x0, %ecx
jmp 0x2ff69
xorl %ecx, %ecx
movq -0x38(%rbp), %rdx
movq (%rdx), %rdi
movq 0x8(%rdx), %rsi
movq %rdi, 0x8(%rsi)
testb $0x2, 0x26(%rsi)
je 0x2ff88
testl %ecx, %ecx
setne %dl
cmpb %dl, 0x21(%rsi)
jne 0x2ff95
testl %ecx, %ecx
setne 0x21(%rsi)
cmpl $0x2, %ecx
sete 0x22(%rsi)
movl 0x30(%rax), %edx
movl -0x4c(%rbp), %ecx
movl $0x1, %r8d
callq 0x16c9b
jmp 0x2fcaf