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

📄 vdbemem.c

📁 sqlite最新源码
💻 C
📖 第 1 页 / 共 3 页
字号:
** negative, zero or positive if pMem1 is less than, equal to, or greater** than pMem2. Sorting order is NULL's first, followed by numbers (integers** and reals) sorted numerically, followed by text ordered by the collating** sequence pColl and finally blob's ordered by memcmp().**** Two NULL values are considered equal by this function.*/int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){  int rc;  int f1, f2;  int combined_flags;  /* Interchange pMem1 and pMem2 if the collating sequence specifies  ** DESC order.  */  f1 = pMem1->flags;  f2 = pMem2->flags;  combined_flags = f1|f2;  assert( (combined_flags & MEM_RowSet)==0 );   /* If one value is NULL, it is less than the other. If both values  ** are NULL, return 0.  */  if( combined_flags&MEM_Null ){    return (f2&MEM_Null) - (f1&MEM_Null);  }  /* If one value is a number and the other is not, the number is less.  ** If both are numbers, compare as reals if one is a real, or as integers  ** if both values are integers.  */  if( combined_flags&(MEM_Int|MEM_Real) ){    if( !(f1&(MEM_Int|MEM_Real)) ){      return 1;    }    if( !(f2&(MEM_Int|MEM_Real)) ){      return -1;    }    if( (f1 & f2 & MEM_Int)==0 ){      double r1, r2;      if( (f1&MEM_Real)==0 ){        r1 = (double)pMem1->u.i;      }else{        r1 = pMem1->r;      }      if( (f2&MEM_Real)==0 ){        r2 = (double)pMem2->u.i;      }else{        r2 = pMem2->r;      }      if( r1<r2 ) return -1;      if( r1>r2 ) return 1;      return 0;    }else{      assert( f1&MEM_Int );      assert( f2&MEM_Int );      if( pMem1->u.i < pMem2->u.i ) return -1;      if( pMem1->u.i > pMem2->u.i ) return 1;      return 0;    }  }  /* If one value is a string and the other is a blob, the string is less.  ** If both are strings, compare using the collating functions.  */  if( combined_flags&MEM_Str ){    if( (f1 & MEM_Str)==0 ){      return 1;    }    if( (f2 & MEM_Str)==0 ){      return -1;    }    assert( pMem1->enc==pMem2->enc );    assert( pMem1->enc==SQLITE_UTF8 ||             pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE );    /* The collation sequence must be defined at this point, even if    ** the user deletes the collation sequence after the vdbe program is    ** compiled (this was not always the case).    */    assert( !pColl || pColl->xCmp );    if( pColl ){      if( pMem1->enc==pColl->enc ){        /* The strings are already in the correct encoding.  Call the        ** comparison function directly */        return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z);      }else{        const void *v1, *v2;        int n1, n2;        Mem c1;        Mem c2;        memset(&c1, 0, sizeof(c1));        memset(&c2, 0, sizeof(c2));        sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem);        sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem);        v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc);        n1 = v1==0 ? 0 : c1.n;        v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc);        n2 = v2==0 ? 0 : c2.n;        rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);        sqlite3VdbeMemRelease(&c1);        sqlite3VdbeMemRelease(&c2);        return rc;      }    }    /* If a NULL pointer was passed as the collate function, fall through    ** to the blob case and use memcmp().  */  }   /* Both values must be blobs.  Compare using memcmp().  */  rc = memcmp(pMem1->z, pMem2->z, (pMem1->n>pMem2->n)?pMem2->n:pMem1->n);  if( rc==0 ){    rc = pMem1->n - pMem2->n;  }  return rc;}/*** Move data out of a btree key or data field and into a Mem structure.** The data or key is taken from the entry that pCur is currently pointing** to.  offset and amt determine what portion of the data or key to retrieve.** key is true to get the key or false to get data.  The result is written** into the pMem element.**** The pMem structure is assumed to be uninitialized.  Any prior content** is overwritten without being freed.**** If this routine fails for any reason (malloc returns NULL or unable** to read from the disk) then the pMem is left in an inconsistent state.*/int sqlite3VdbeMemFromBtree(  BtCursor *pCur,   /* Cursor pointing at record to retrieve. */  int offset,       /* Offset from the start of data to return bytes from. */  int amt,          /* Number of bytes to return. */  int key,          /* If true, retrieve from the btree key, not data. */  Mem *pMem         /* OUT: Return data in this Mem structure. */){  char *zData;       /* Data from the btree layer */  int available = 0; /* Number of bytes available on the local btree page */  sqlite3 *db;       /* Database connection */  int rc = SQLITE_OK;  db = sqlite3BtreeCursorDb(pCur);  assert( sqlite3_mutex_held(db->mutex) );  assert( (pMem->flags & MEM_RowSet)==0 );  if( key ){    zData = (char *)sqlite3BtreeKeyFetch(pCur, &available);  }else{    zData = (char *)sqlite3BtreeDataFetch(pCur, &available);  }  assert( zData!=0 );  if( offset+amt<=available && ((pMem->flags&MEM_Dyn)==0 || pMem->xDel) ){    sqlite3VdbeMemRelease(pMem);    pMem->z = &zData[offset];    pMem->flags = MEM_Blob|MEM_Ephem;  }else if( SQLITE_OK==(rc = sqlite3VdbeMemGrow(pMem, amt+2, 0)) ){    pMem->flags = MEM_Blob|MEM_Dyn|MEM_Term;    pMem->enc = 0;    pMem->type = SQLITE_BLOB;    if( key ){      rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z);    }else{      rc = sqlite3BtreeData(pCur, offset, amt, pMem->z);    }    pMem->z[amt] = 0;    pMem->z[amt+1] = 0;    if( rc!=SQLITE_OK ){      sqlite3VdbeMemRelease(pMem);    }  }  pMem->n = amt;  return rc;}/* This function is only available internally, it is not part of the** external API. It works in a similar way to sqlite3_value_text(),** except the data returned is in the encoding specified by the second** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or** SQLITE_UTF8.**** (2006-02-16:)  The enc value can be or-ed with SQLITE_UTF16_ALIGNED.** If that is the case, then the result must be aligned on an even byte** boundary.*/const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){  if( !pVal ) return 0;  assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );  assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );  assert( (pVal->flags & MEM_RowSet)==0 );  if( pVal->flags&MEM_Null ){    return 0;  }  assert( (MEM_Blob>>3) == MEM_Str );  pVal->flags |= (pVal->flags & MEM_Blob)>>3;  expandBlob(pVal);  if( pVal->flags&MEM_Str ){    sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED);    if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&SQLITE_PTR_TO_INT(pVal->z)) ){      assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 );      if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){        return 0;      }    }    sqlite3VdbeMemNulTerminate(pVal);  }else{    assert( (pVal->flags&MEM_Blob)==0 );    sqlite3VdbeMemStringify(pVal, enc);    assert( 0==(1&SQLITE_PTR_TO_INT(pVal->z)) );  }  assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0              || pVal->db->mallocFailed );  if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){    return pVal->z;  }else{    return 0;  }}/*** Create a new sqlite3_value object.*/sqlite3_value *sqlite3ValueNew(sqlite3 *db){  Mem *p = sqlite3DbMallocZero(db, sizeof(*p));  if( p ){    p->flags = MEM_Null;    p->type = SQLITE_NULL;    p->db = db;  }  return p;}/*** Create a new sqlite3_value object, containing the value of pExpr.**** This only works for very simple expressions that consist of one constant** token (i.e. "5", "5.1", "'a string'"). If the expression can** be converted directly into a value, then the value is allocated and** a pointer written to *ppVal. The caller is responsible for deallocating** the value by passing it to sqlite3ValueFree() later on. If the expression** cannot be converted to a value, then *ppVal is set to NULL.*/int sqlite3ValueFromExpr(  sqlite3 *db,              /* The database connection */  Expr *pExpr,              /* The expression to evaluate */  u8 enc,                   /* Encoding to use */  u8 affinity,              /* Affinity to use */  sqlite3_value **ppVal     /* Write the new value here */){  int op;  char *zVal = 0;  sqlite3_value *pVal = 0;  if( !pExpr ){    *ppVal = 0;    return SQLITE_OK;  }  op = pExpr->op;  if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){    zVal = sqlite3DbStrNDup(db, (char*)pExpr->token.z, pExpr->token.n);    pVal = sqlite3ValueNew(db);    if( !zVal || !pVal ) goto no_mem;    sqlite3Dequote(zVal);    sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);    if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){      sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, enc);    }else{      sqlite3ValueApplyAffinity(pVal, affinity, enc);    }  }else if( op==TK_UMINUS ) {    if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) ){      pVal->u.i = -1 * pVal->u.i;      /* (double)-1 In case of SQLITE_OMIT_FLOATING_POINT... */      pVal->r = (double)-1 * pVal->r;    }  }#ifndef SQLITE_OMIT_BLOB_LITERAL  else if( op==TK_BLOB ){    int nVal;    assert( pExpr->token.n>=3 );    assert( pExpr->token.z[0]=='x' || pExpr->token.z[0]=='X' );    assert( pExpr->token.z[1]=='\'' );    assert( pExpr->token.z[pExpr->token.n-1]=='\'' );    pVal = sqlite3ValueNew(db);    if( !pVal ) goto no_mem;    nVal = pExpr->token.n - 3;    zVal = (char*)pExpr->token.z + 2;    sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2,                         0, SQLITE_DYNAMIC);  }#endif  *ppVal = pVal;  return SQLITE_OK;no_mem:  db->mallocFailed = 1;  sqlite3DbFree(db, zVal);  sqlite3ValueFree(pVal);  *ppVal = 0;  return SQLITE_NOMEM;}/*** Change the string value of an sqlite3_value object*/void sqlite3ValueSetStr(  sqlite3_value *v,     /* Value to be set */  int n,                /* Length of string z */  const void *z,        /* Text of the new string */  u8 enc,               /* Encoding to use */  void (*xDel)(void*)   /* Destructor for the string */){  if( v ) sqlite3VdbeMemSetStr((Mem *)v, z, n, enc, xDel);}/*** Free an sqlite3_value object*/void sqlite3ValueFree(sqlite3_value *v){  if( !v ) return;  sqlite3VdbeMemRelease((Mem *)v);  sqlite3DbFree(((Mem*)v)->db, v);}/*** Return the number of bytes in the sqlite3_value object assuming** that it uses the encoding "enc"*/int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){  Mem *p = (Mem*)pVal;  if( (p->flags & MEM_Blob)!=0 || sqlite3ValueText(pVal, enc) ){    if( p->flags & MEM_Zero ){      return p->n + p->u.nZero;    }else{      return p->n;    }  }  return 0;}

⌨️ 快捷键说明

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