Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix ALTER TABLE RENAME COLUMN in cases where the column being renamed is an IPK declared with a separate PRIMARY KEY clause - "CREATE TABLE x(y INTEGER, PRIMARY KEY(y))". |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | alter-table-rename-column |
Files: | files | file ages | folders |
SHA3-256: |
32ca8418df8735a6c53e53153f733579 |
User & Date: | dan 2018-08-14 16:18:19.678 |
Context
2018-08-14
| ||
18:12 | Merge fixes and enhancements from trunk. (check-in: dff0314b7e user: drh tags: alter-table-rename-column) | |
16:18 | Fix ALTER TABLE RENAME COLUMN in cases where the column being renamed is an IPK declared with a separate PRIMARY KEY clause - "CREATE TABLE x(y INTEGER, PRIMARY KEY(y))". (check-in: 32ca8418df user: dan tags: alter-table-rename-column) | |
2018-08-13
| ||
17:02 | Make the sqlite_rename_column() SQL function resistant to problems caused by OOMs and/or malformed parameters submitted by hostile application code. Also add additional comments to the RENAME COLUMN logic. (check-in: 87743ddef1 user: drh tags: alter-table-rename-column) | |
Changes
Changes to src/alter.c.
︙ | ︙ | |||
937 938 939 940 941 942 943 | for(p=pToken; p; p=pNext){ pNext = p->pNext; sqlite3DbFree(db, p); } } /* | > | < | < < | | | | > > < > | < < < < < | 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 | for(p=pToken; p; p=pNext){ pNext = p->pNext; sqlite3DbFree(db, p); } } /* ** Search the Parse object passed as the first argument for a RenameToken ** object associated with parse tree element pPtr. If found, remove it ** from the Parse object and add it to the list maintained by the ** RenameCtx object passed as the second argument. */ static void renameTokenFind(Parse *pParse, struct RenameCtx *pCtx, void *pPtr){ RenameToken **pp; for(pp=&pParse->pRename; (*pp); pp=&(*pp)->pNext){ if( (*pp)->p==pPtr ){ RenameToken *pToken = *pp; *pp = pToken->pNext; pToken->pNext = pCtx->pList; pCtx->pList = pToken; pCtx->nList++; break; } } } /* ** This is a Walker expression callback. ** ** For every TK_COLUMN node in the expression tree, search to see ** if the column being references is the column being renamed by an ** ALTER TABLE statement. If it is, then attach its associated ** RenameToken object to the list of RenameToken objects being ** constructed in RenameCtx object at pWalker->u.pRename. */ static int renameColumnExprCb(Walker *pWalker, Expr *pExpr){ struct RenameCtx *p = pWalker->u.pRename; if( pExpr->op==TK_COLUMN && pExpr->iColumn==p->iCol ){ renameTokenFind(pWalker->pParse, p, (void*)pExpr); } return WRC_Continue; } /* ** The RenameCtx contains a list of tokens that reference a column that ** is being renamed by an ALTER TABLE statement. Return the "first" |
︙ | ︙ | |||
1111 1112 1113 1114 1115 1116 1117 | sWalker.xExprCallback = renameColumnExprCb; sWalker.u.pRename = &sCtx; if( sParse.pNewTable ){ int bFKOnly = sqlite3_stricmp(zTable, sParse.pNewTable->zName); FKey *pFKey; if( bFKOnly==0 ){ | | | < > | < < < < < | < < < | 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 | sWalker.xExprCallback = renameColumnExprCb; sWalker.u.pRename = &sCtx; if( sParse.pNewTable ){ int bFKOnly = sqlite3_stricmp(zTable, sParse.pNewTable->zName); FKey *pFKey; if( bFKOnly==0 ){ renameTokenFind( &sParse, &sCtx, (void*)sParse.pNewTable->aCol[sCtx.iCol].zName ); assert( sCtx.iCol>=0 ); if( sParse.pNewTable->iPKey==sCtx.iCol ){ renameTokenFind(&sParse, &sCtx, (void*)&sParse.pNewTable->iPKey); sCtx.iCol = -1; } sqlite3WalkExprList(&sWalker, sParse.pNewTable->pCheck); for(pIdx=sParse.pNewTable->pIndex; pIdx; pIdx=pIdx->pNext){ sqlite3WalkExprList(&sWalker, pIdx->aColExpr); } } for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){ for(i=0; i<pFKey->nCol; i++){ RenameToken *pTok = 0; if( bFKOnly==0 && pFKey->aCol[i].iFrom==sCtx.iCol ){ renameTokenFind(&sParse, &sCtx, (void*)&pFKey->aCol[i]); } if( 0==sqlite3_stricmp(pFKey->zTo, zTable) && 0==sqlite3_stricmp(pFKey->aCol[i].zCol, zOld) ){ renameTokenFind(&sParse, &sCtx, (void*)pFKey->aCol[i].zCol); } } } }else{ sqlite3WalkExprList(&sWalker, sParse.pNewIndex->aColExpr); sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere); } |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 | } } if( nTerm==1 && pCol && sqlite3StrICmp(sqlite3ColumnType(pCol,""), "INTEGER")==0 && sortOrder!=SQLITE_SO_DESC ){ pTab->iPKey = iCol; pTab->keyConf = (u8)onError; assert( autoInc==0 || autoInc==1 ); pTab->tabFlags |= autoInc*TF_Autoincrement; if( pList ) pParse->iPkSortOrder = pList->a[0].sortOrder; }else if( autoInc ){ #ifndef SQLITE_OMIT_AUTOINCREMENT | > > > | 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 | } } if( nTerm==1 && pCol && sqlite3StrICmp(sqlite3ColumnType(pCol,""), "INTEGER")==0 && sortOrder!=SQLITE_SO_DESC ){ if( IN_RENAME_COLUMN && pList ){ sqlite3MoveRenameToken(pParse, &pTab->iPKey, pList->a[0].pExpr); } pTab->iPKey = iCol; pTab->keyConf = (u8)onError; assert( autoInc==0 || autoInc==1 ); pTab->tabFlags |= autoInc*TF_Autoincrement; if( pList ) pParse->iPkSortOrder = pList->a[0].sortOrder; }else if( autoInc ){ #ifndef SQLITE_OMIT_AUTOINCREMENT |
︙ | ︙ |
Changes to test/altercol.test.
︙ | ︙ | |||
61 62 63 64 65 66 67 68 69 70 71 72 73 74 | {{CREATE TABLE t1(a, d, c)} {CREATE INDEX t1i ON t1(d, c)}} 12 {CREATE TABLE t1(a, b, c); CREATE INDEX t1i ON t1(b+b+b+b, c) WHERE b>0} {{CREATE TABLE t1(a, d, c)} {CREATE INDEX t1i ON t1(d+d+d+d, c) WHERE d>0}} 13 {CREATE TABLE t1(a, b, c, FOREIGN KEY (b) REFERENCES t2)} {CREATE TABLE t1(a, d, c, FOREIGN KEY (d) REFERENCES t2)} } { reset_db do_execsql_test 1.$tn.0 $before do_execsql_test 1.$tn.1 { INSERT INTO t1 VALUES(1, 2, 3); | > > > > > > | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | {{CREATE TABLE t1(a, d, c)} {CREATE INDEX t1i ON t1(d, c)}} 12 {CREATE TABLE t1(a, b, c); CREATE INDEX t1i ON t1(b+b+b+b, c) WHERE b>0} {{CREATE TABLE t1(a, d, c)} {CREATE INDEX t1i ON t1(d+d+d+d, c) WHERE d>0}} 13 {CREATE TABLE t1(a, b, c, FOREIGN KEY (b) REFERENCES t2)} {CREATE TABLE t1(a, d, c, FOREIGN KEY (d) REFERENCES t2)} 15 {CREATE TABLE t1(a INTEGER, b INTEGER, c BLOB, PRIMARY KEY(b))} {CREATE TABLE t1(a INTEGER, d INTEGER, c BLOB, PRIMARY KEY(d))} 16 {CREATE TABLE t1(a INTEGER, b INTEGER PRIMARY KEY, c BLOB)} {CREATE TABLE t1(a INTEGER, d INTEGER PRIMARY KEY, c BLOB)} } { reset_db do_execsql_test 1.$tn.0 $before do_execsql_test 1.$tn.1 { INSERT INTO t1 VALUES(1, 2, 3); |
︙ | ︙ |