Sqlite: Update carray extension

Change-Id: I6fd69c3c8d34bf86a0529c63dede80791a204c88
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Marco Bubke
2023-02-21 14:44:23 +01:00
parent 157b5039c1
commit 3a1aea1298

View File

@@ -28,7 +28,7 @@
** **
** There is an optional third parameter to determine the datatype of ** There is an optional third parameter to determine the datatype of
** the C-language array. Allowed values of the third parameter are ** the C-language array. Allowed values of the third parameter are
** 'int32', 'int64', 'double', 'char*'. Example: ** 'int32', 'int64', 'double', 'char*', 'struct iovec'. Example:
** **
** SELECT * FROM carray($ptr,10,'char*'); ** SELECT * FROM carray($ptr,10,'char*');
** **
@@ -56,6 +56,14 @@
SQLITE_EXTENSION_INIT1 SQLITE_EXTENSION_INIT1
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#ifdef _WIN32
struct iovec {
void *iov_base;
size_t iov_len;
};
#else
# include <sys/uio.h>
#endif
/* Allowed values for the mFlags parameter to sqlite3_carray_bind(). /* Allowed values for the mFlags parameter to sqlite3_carray_bind().
** Must exactly match the definitions in carray.h. ** Must exactly match the definitions in carray.h.
@@ -65,6 +73,7 @@ SQLITE_EXTENSION_INIT1
# define CARRAY_INT64 1 /* Data is 64-bit signed integers */ # define CARRAY_INT64 1 /* Data is 64-bit signed integers */
# define CARRAY_DOUBLE 2 /* Data is doubles */ # define CARRAY_DOUBLE 2 /* Data is doubles */
# define CARRAY_TEXT 3 /* Data is char* */ # define CARRAY_TEXT 3 /* Data is char* */
# define CARRAY_BLOB 4 /* Data is struct iovec* */
#endif #endif
#ifndef SQLITE_API #ifndef SQLITE_API
@@ -80,7 +89,8 @@ SQLITE_EXTENSION_INIT1
/* /*
** Names of allowed datatypes ** Names of allowed datatypes
*/ */
static const char *azType[] = { "int32", "int64", "double", "char*" }; static const char *azType[] = { "int32", "int64", "double", "char*",
"struct iovec" };
/* /*
** Structure used to hold the sqlite3_carray_bind() information ** Structure used to hold the sqlite3_carray_bind() information
@@ -224,6 +234,12 @@ static int carrayColumn(
sqlite3_result_text(ctx, p[pCur->iRowid-1], -1, SQLITE_TRANSIENT); sqlite3_result_text(ctx, p[pCur->iRowid-1], -1, SQLITE_TRANSIENT);
return SQLITE_OK; return SQLITE_OK;
} }
case CARRAY_BLOB: {
const struct iovec *p = (struct iovec*)pCur->pPtr;
sqlite3_result_blob(ctx, p[pCur->iRowid-1].iov_base,
(int)p[pCur->iRowid-1].iov_len, SQLITE_TRANSIENT);
return SQLITE_OK;
}
} }
} }
} }
@@ -268,7 +284,7 @@ static int carrayFilter(
if( pBind==0 ) break; if( pBind==0 ) break;
pCur->pPtr = pBind->aData; pCur->pPtr = pBind->aData;
pCur->iCnt = pBind->nData; pCur->iCnt = pBind->nData;
pCur->eType = pBind->mFlags & 0x03; pCur->eType = pBind->mFlags & 0x07;
break; break;
} }
case 2: case 2:
@@ -431,24 +447,29 @@ SQLITE_API int sqlite3_carray_bind(
pNew->mFlags = mFlags; pNew->mFlags = mFlags;
if( xDestroy==SQLITE_TRANSIENT ){ if( xDestroy==SQLITE_TRANSIENT ){
sqlite3_int64 sz = nData; sqlite3_int64 sz = nData;
switch( mFlags & 0x03 ){ switch( mFlags & 0x07 ){
case CARRAY_INT32: sz *= 4; break; case CARRAY_INT32: sz *= 4; break;
case CARRAY_INT64: sz *= 8; break; case CARRAY_INT64: sz *= 8; break;
case CARRAY_DOUBLE: sz *= 8; break; case CARRAY_DOUBLE: sz *= 8; break;
case CARRAY_TEXT: sz *= sizeof(char*); break; case CARRAY_TEXT: sz *= sizeof(char*); break;
case CARRAY_BLOB: sz *= sizeof(struct iovec); break;
} }
if( (mFlags & 0x03)==CARRAY_TEXT ){ if( (mFlags & 0x07)==CARRAY_TEXT ){
for(i=0; i<nData; i++){ for(i=0; i<nData; i++){
const char *z = ((char**)aData)[i]; const char *z = ((char**)aData)[i];
if( z ) sz += strlen(z) + 1; if( z ) sz += strlen(z) + 1;
} }
}else if( (mFlags & 0x07)==CARRAY_BLOB ){
for(i=0; i<nData; i++){
sz += ((struct iovec*)aData)[i].iov_len;
}
} }
pNew->aData = sqlite3_malloc64( sz ); pNew->aData = sqlite3_malloc64( sz );
if( pNew->aData==0 ){ if( pNew->aData==0 ){
sqlite3_free(pNew); sqlite3_free(pNew);
return SQLITE_NOMEM; return SQLITE_NOMEM;
} }
if( (mFlags & 0x03)==CARRAY_TEXT ){ if( (mFlags & 0x07)==CARRAY_TEXT ){
char **az = (char**)pNew->aData; char **az = (char**)pNew->aData;
char *z = (char*)&az[nData]; char *z = (char*)&az[nData];
for(i=0; i<nData; i++){ for(i=0; i<nData; i++){
@@ -463,6 +484,16 @@ SQLITE_API int sqlite3_carray_bind(
memcpy(z, zData, n+1); memcpy(z, zData, n+1);
z += n+1; z += n+1;
} }
}else if( (mFlags & 0x07)==CARRAY_BLOB ){
struct iovec *p = (struct iovec*)pNew->aData;
unsigned char *z = (unsigned char*)&p[nData];
for(i=0; i<nData; i++){
size_t n = ((struct iovec*)aData)[i].iov_len;
p[i].iov_len = n;
p[i].iov_base = z;
z += n;
memcpy(p[i].iov_base, ((struct iovec*)aData)[i].iov_base, n);
}
}else{ }else{
memcpy(pNew->aData, aData, sz); memcpy(pNew->aData, aData, sz);
} }