1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-11 01:42:22 +03:00

Enforce column affinity on the materialization of a subquery or view.

FossilOrigin-Name: b6692de374d7f489d8cf8877bdfef19501bc5ecb0781d42750807eeb58f2e7cd
This commit is contained in:
drh
2022-11-01 00:52:22 +00:00
parent c7dd9b60eb
commit 5fdb9a352c
7 changed files with 68 additions and 26 deletions

View File

@@ -110,6 +110,28 @@ const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){
return pIdx->zColAff;
}
/*
** Compute an affinity string for a table. Space is obtained
** from sqlite3DbMalloc(). The caller is responsible for freeing
** the space when done.
*/
char *sqlite3TableAffinityStr(sqlite3 *db, const Table *pTab){
char *zColAff;
zColAff = (char *)sqlite3DbMallocRaw(db, pTab->nCol+1);
if( zColAff ){
int i, j;
for(i=j=0; i<pTab->nCol; i++){
if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){
zColAff[j++] = pTab->aCol[i].affinity;
}
}
do{
zColAff[j--] = 0;
}while( j>=0 && zColAff[j]<=SQLITE_AFF_BLOB );
}
return zColAff;
}
/*
** Make changes to the evolving bytecode to do affinity transformations
** of values that are about to be gathered into a row for table pTab.
@@ -151,7 +173,7 @@ const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){
** Apply the type checking to that array of registers.
*/
void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){
int i, j;
int i;
char *zColAff;
if( pTab->tabFlags & TF_Strict ){
if( iReg==0 ){
@@ -174,22 +196,11 @@ void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){
}
zColAff = pTab->zColAff;
if( zColAff==0 ){
sqlite3 *db = sqlite3VdbeDb(v);
zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1);
zColAff = sqlite3TableAffinityStr(0, pTab);
if( !zColAff ){
sqlite3OomFault(db);
sqlite3OomFault(sqlite3VdbeDb(v));
return;
}
for(i=j=0; i<pTab->nCol; i++){
assert( pTab->aCol[i].affinity!=0 || sqlite3VdbeParser(v)->nErr>0 );
if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){
zColAff[j++] = pTab->aCol[i].affinity;
}
}
do{
zColAff[j--] = 0;
}while( j>=0 && zColAff[j]<=SQLITE_AFF_BLOB );
pTab->zColAff = zColAff;
}
assert( zColAff!=0 );