aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordrh <>2021-07-30 18:39:59 +0000
committerdrh <>2021-07-30 18:39:59 +0000
commit77441faff5f4d5cee08c747116fae97b48eeb9b0 (patch)
treef6691599a4454725ced373b181b39d32819e56a1
parent7b3c514b5324156c8ba4c9fbb0548f374ccdb629 (diff)
downloadsqlite-77441faff5f4d5cee08c747116fae97b48eeb9b0.tar.gz
sqlite-77441faff5f4d5cee08c747116fae97b48eeb9b0.zip
Avoid clownfeet in the names columns when the column names are quoted
in the original CREATE TABLE statement. FossilOrigin-Name: 980f7292afd45a8e73272e2139b55b99ab86167febec9fd0bf0356e8167b2ee9
-rw-r--r--manifest18
-rw-r--r--manifest.uuid2
-rw-r--r--src/build.c17
-rw-r--r--src/parse.y2
-rw-r--r--src/sqliteInt.h3
-rw-r--r--src/util.c29
6 files changed, 49 insertions, 22 deletions
diff --git a/manifest b/manifest
index edf0ee35b..4346c1292 100644
--- a/manifest
+++ b/manifest
@@ -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
diff --git a/manifest.uuid b/manifest.uuid
index bfefc3402..50ed690d5 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-2941ded0acbdcf914567bf7451cfd9b770269545c20d3fa7107c40492689afad \ No newline at end of file
+980f7292afd45a8e73272e2139b55b99ab86167febec9fd0bf0356e8167b2ee9 \ No newline at end of file
diff --git a/src/build.c b/src/build.c
index 4f6f50a20..5d2936f5b 100644
--- a/src/build.c
+++ b/src/build.c
@@ -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;
diff --git a/src/parse.y b/src/parse.y
index 1e0782558..24c539bdb 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -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
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 25eb9f108..7d6fda4c6 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -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*);
diff --git a/src/util.c b/src/util.c
index fc0c2042b..8bcf1d261 100644
--- a/src/util.c
+++ b/src/util.c
@@ -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;
+ }
}
/*
@@ -267,6 +270,28 @@ void sqlite3DequoteExpr(Expr *p){
}
/*
+** 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
*/
void sqlite3TokenInit(Token *p, char *z){