Avoid clownfeet in the names columns when the column names are quoted

in the original CREATE TABLE statement.

FossilOrigin-Name: 980f7292afd45a8e73272e2139b55b99ab86167febec9fd0bf0356e8167b2ee9
This commit is contained in:
drh 2021-07-30 18:39:59 +00:00
parent 7b3c514b53
commit 77441faff5
6 changed files with 49 additions and 22 deletions

View File

@ -1,5 +1,5 @@
C Reduce\sclownfooting\sin\sthe\sallocation\sof\sthe\sTable.aCol\sarray.\s\sThis\sreduces\nthe\samount\sof\sheap\sspace\srequired\sto\shold\slarge\sschemas\sby\sabout\s11%.
D 2021-07-30T12:47:35.850
C Avoid\sclownfeet\sin\sthe\snames\scolumns\swhen\sthe\scolumn\snames\sare\squoted\nin\sthe\soriginal\sCREATE\sTABLE\sstatement.
D 2021-07-30T18:39:59.675
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -488,7 +488,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
F src/btree.c e204a9c8fb4fe5dbb910a863ba487f4af9b5c501254ec4ccbfcdd6b1f65b7fb4
F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22
F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0
F src/build.c 218628f5743e2329959f66269928ac9521cc5e7f69d8bcc0e90a57f2715fe0ae
F src/build.c 8b0a6aa7dbce272c66f282f7aeec6e37ee1c7ded21e8f5a6e3864b0ab6ccdb29
F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 8159d5f706551861c18ec6c8f6bdf105e15ea00367f05d9ab65d31a1077facc1
@ -533,7 +533,7 @@ F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 95c255256b13827caf038c8f963d334784073f38ab6ef9d70371d9d04f3c43e0
F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f
F src/parse.y 6d90c816edf65e99fb978c3b5486df5e661c3534347efac2842b80eb02263e68
F src/parse.y 0ba0baec5de6921ec8ba8bbcf1018969144ef29d26112e17539d8fbb1662e3eb
F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
F src/pcache1.c 388304fd2d91c39591080b5e0f3c62cfba87db20370e7e0554062bfb29740e9f
@ -549,7 +549,7 @@ F src/shell.c.in 24b99dae8818d1a234732d73f4d5b49f12b510bc62735a41c04e314fafae09e
F src/sqlite.h.in 43fcf0fe2af04081f420a906fc020bde1243851ba44b0aa567a27f94bf8c3145
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510
F src/sqliteInt.h 441f226f8e5de526fcbddc092d6fa7f99df12985bf29411399219e79196caf82
F src/sqliteInt.h 1041c70f63687392665dde29f87f8af27d27bc1e18d29c8b804360fc915c2fde
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@ -614,7 +614,7 @@ F src/trigger.c 7d16aa09e63226b6d8b3f0fc60b21cbfa596fc406288b2ebcf4266633d1ba222
F src/update.c 30465f9accc854e8a7932b413578027fbb68186132abbb36e01d2022473fc83d
F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048
F src/util.c b2cb568393144b05df06871b2c61b0f0240f1835aee2843c736391507fac2780
F src/vacuum.c 454973a59fb20bb982efc2df568a098616db6328a0491b6e84e2e07f7333db45
F src/vdbe.c b73a5ec9940185eb001ff8cff2cfd429bb438c7e89f2885e0bfdb56c3ff13386
F src/vdbe.h 25dabb25c7e157b84e59260cfb5b466c3ac103ede9f36f4db371332c47601abe
@ -1920,7 +1920,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P a6c160e08a61d105f8aab959440ac5ec4f1aaca8f0d393e08e7c2c67815b5bb2
R 05be268cc1d65b192983539c10fe9664
P 2941ded0acbdcf914567bf7451cfd9b770269545c20d3fa7107c40492689afad
R 34387fa0540aea58caf42bd33cbb64b5
U drh
Z 293e50cb88f37ee66f4747a547b7dd6f
Z a43263f36582e13af1a30f741180b3be

View File

@ -1 +1 @@
2941ded0acbdcf914567bf7451cfd9b770269545c20d3fa7107c40492689afad
980f7292afd45a8e73272e2139b55b99ab86167febec9fd0bf0356e8167b2ee9

View File

@ -1373,7 +1373,7 @@ void sqlite3AddReturning(Parse *pParse, ExprList *pList){
** first to get things going. Then this routine is called for each
** column.
*/
void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){
Table *p;
int i;
char *z;
@ -1388,11 +1388,12 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName);
return;
}
z = sqlite3DbMallocRaw(db, pName->n + pType->n + 2);
if( !IN_RENAME_OBJECT ) sqlite3DequoteToken(&sName);
z = sqlite3DbMallocRaw(db, sName.n + sType.n + 2);
if( z==0 ) return;
if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, pName);
memcpy(z, pName->z, pName->n);
z[pName->n] = 0;
if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, &sName);
memcpy(z, sName.z, sName.n);
z[sName.n] = 0;
sqlite3Dequote(z);
hName = sqlite3StrIHash(z);
for(i=0; i<p->nCol; i++){
@ -1414,7 +1415,7 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
pCol->hName = hName;
sqlite3ColumnPropertiesFromName(p, pCol);
if( pType->n==0 ){
if( sType.n==0 ){
/* If there is no type specified, columns have the default affinity
** 'BLOB' with a default size of 4 bytes. */
pCol->affinity = SQLITE_AFF_BLOB;
@ -1426,8 +1427,8 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
#endif
}else{
zType = z + sqlite3Strlen30(z) + 1;
memcpy(zType, pType->z, pType->n);
zType[pType->n] = 0;
memcpy(zType, sType.z, sType.n);
zType[sType.n] = 0;
sqlite3Dequote(zType);
pCol->affinity = sqlite3AffinityType(zType, pCol);
pCol->colFlags |= COLFLAG_HASTYPE;

View File

@ -215,7 +215,7 @@ table_options(A) ::= WITHOUT nm(X). {
}
columnlist ::= columnlist COMMA columnname carglist.
columnlist ::= columnname carglist.
columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);}
columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,A,Y);}
// Declare some tokens early in order to influence their values, to
// improve performance and reduce the executable size. The goal here is

View File

@ -4317,6 +4317,7 @@ void sqlite3ErrorMsg(Parse*, const char*, ...);
int sqlite3ErrorToParser(sqlite3*,int);
void sqlite3Dequote(char*);
void sqlite3DequoteExpr(Expr*);
void sqlite3DequoteToken(Token*);
void sqlite3TokenInit(Token*,char*);
int sqlite3KeywordCode(const unsigned char*, int);
int sqlite3RunParser(Parse*, const char*, char **);
@ -4383,7 +4384,7 @@ void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int);
#else
# define sqlite3ColumnPropertiesFromName(T,C) /* no-op */
#endif
void sqlite3AddColumn(Parse*,Token*,Token*);
void sqlite3AddColumn(Parse*,Token,Token);
void sqlite3AddNotNull(Parse*, int);
void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
void sqlite3AddCheckConstraint(Parse*, Expr*, const char*, const char*);

View File

@ -89,8 +89,11 @@ int sqlite3Strlen30(const char *z){
** the column name if and only if the COLFLAG_HASTYPE flag is set.
*/
char *sqlite3ColumnType(Column *pCol, char *zDflt){
if( (pCol->colFlags & COLFLAG_HASTYPE)==0 ) return zDflt;
return pCol->zName + strlen(pCol->zName) + 1;
if( pCol->colFlags & COLFLAG_HASTYPE ){
return pCol->zName + strlen(pCol->zName) + 1;
}else{
return zDflt;
}
}
/*
@ -266,6 +269,28 @@ void sqlite3DequoteExpr(Expr *p){
sqlite3Dequote(p->u.zToken);
}
/*
** If the input token p is quoted, try to adjust the token to remove
** the quotes. This is not always possible:
**
** "abc" -> abc
** "ab""cd" -> (not possible because of the interior "")
**
** Remove the quotes if possible. This is a optimization. The overall
** system should still return the correct answer even if this routine
** is always a no-op.
*/
void sqlite3DequoteToken(Token *p){
int i;
if( p->n<2 ) return;
if( !sqlite3Isquote(p->z[0]) ) return;
for(i=1; i<p->n-1; i++){
if( sqlite3Isquote(p->z[i]) ) return;
}
p->n -= 2;
p->z++;
}
/*
** Generate a Token object from a string
*/