]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the ability for the PRAGMA statement to accept multiple arguments. multi-arg-pragma
authordrh <drh@noemail.net>
Thu, 20 Oct 2016 18:20:10 +0000 (18:20 +0000)
committerdrh <drh@noemail.net>
Thu, 20 Oct 2016 18:20:10 +0000 (18:20 +0000)
Currently all arguments other than the first are ignored.

FossilOrigin-Name: fd81d8a4300c36d02f07371b722124ccf619654c

manifest
manifest.uuid
src/build.c
src/parse.y
src/pragma.c
src/sqliteInt.h

index 48536b00434bc82c373b464bd3120b3715a2c77f..335c3844f347cc47baea348ce918ab51d4245f69 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Minor\ssimplification\sof\sthe\scomparison\sopcodes.
-D 2016-10-18T16:36:15.935
+C Add\sthe\sability\sfor\sthe\sPRAGMA\sstatement\sto\saccept\smultiple\sarguments.\nCurrently\sall\sarguments\sother\sthan\sthe\sfirst\sare\signored.
+D 2016-10-20T18:20:10.293
 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f
@@ -332,7 +332,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73
 F src/btree.c 4d035fb52b0ef9658d43dfe604413185dff7a5d1
 F src/btree.h d05b2fcc290991a8a3d9ea1816ddd55a4359dcde
 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5
-F src/build.c 59dcfdc1ee55439d069af301ef7f2e84421b5102
+F src/build.c e22e66fb34e1e50bb7869a510923bfe58db3071a
 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730
 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
 F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7
@@ -375,11 +375,11 @@ F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9
 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
 F src/pager.c 49b6c163832498838c92d0c4c90721576ae707b7
 F src/pager.h 0a19b1e212d0f5d0507f186ae1cca4e523d09d1a
-F src/parse.y 0338f906b61e311c2b7e11a3f89b0092c780b664
+F src/parse.y 07f68096c97093793ed04d69db8bb75e55c3e00e
 F src/pcache.c 5ff2a08f76a9c1b22f43eb063b7068fb085465ac
 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490
 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953
-F src/pragma.c d932ba278654617cdd281f88a790a3185fca7c44
+F src/pragma.c 3ad504c61bcddacc231662f83ac41aceea639ff2
 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c
 F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a
 F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1
@@ -391,7 +391,7 @@ F src/shell.c b80396d2fadce4681397707e30078bf416e1dec2
 F src/sqlite.h.in 7ef021d74ac7d4004c784a16ad015508f171c4bf
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae
-F src/sqliteInt.h 8d241c2c0a1a7b6611d3e9398f41d69426da850d
+F src/sqliteInt.h cf6393ad581d692b886e5281f7bb03b02c2a5f26
 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
 F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9
@@ -1526,7 +1526,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 2aa7a03b8632dbfd9741018b5b19c372dcfd3647
-R 4e106c87e784e92bad6650fe8613fe88
+P 56474ebca3fdddb8f3c5156f06dc42dc0a65256c
+R 7df9a33a3d365e65a71615f92b26cc61
+T *branch * multi-arg-pragma
+T *sym-multi-arg-pragma *
+T -sym-trunk *
 U drh
-Z 84c64fba90e2b1da59a52306d789b152
+Z 4afce9abc23c76c5686e4f8a5162325b
index 091e1f1005cec3f9c1b4955b7776b4b2ec74523b..4f7a6dca1507743937ee2c53460905e802a68838 100644 (file)
@@ -1 +1 @@
-56474ebca3fdddb8f3c5156f06dc42dc0a65256c
\ No newline at end of file
+fd81d8a4300c36d02f07371b722124ccf619654c
\ No newline at end of file
index 508e747ea6dd93d730359cdada4e4274860b3355..432b832836851cb39b97b404fc0cf2d4e56eb4e8 100644 (file)
@@ -3572,12 +3572,21 @@ void *sqlite3ArrayAllocate(
 ** need be.
 **
 ** A new IdList is returned, or NULL if malloc() fails.
+**
+** The zName must have been obtained from sqlite3DbMalloc().  This routine
+** accepts ownership of the zName string and will ensure that it is freed
+** when no longer in use.
 */
-IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){
+IdList *sqlite3IdListAppend(
+  Parse *pParse,       /* Parsing context */
+  IdList *pList,       /* ID list to append to */
+  char *zName          /* Token to append */
+){
   int i;
+  sqlite3 *db = pParse->db;
   if( pList==0 ){
     pList = sqlite3DbMallocZero(db, sizeof(IdList) );
-    if( pList==0 ) return 0;
+    if( pList==0 ) goto id_list_append_fail;
   }
   pList->a = sqlite3ArrayAllocate(
       db,
@@ -3588,10 +3597,14 @@ IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){
   );
   if( i<0 ){
     sqlite3IdListDelete(db, pList);
-    return 0;
+    goto id_list_append_fail;
   }
-  pList->a[i].zName = sqlite3NameFromToken(db, pToken);
+  pList->a[i].zName = zName;
   return pList;
+
+id_list_append_fail:
+  sqlite3DbFree(db, zName);
+  return 0;
 }
 
 /*
index 1eff123d1864bf15269ee8ddd7867c25a1ba2e2c..57b7db0408e51ced82e56bfb5f3c498c581d54b7 100644 (file)
@@ -204,11 +204,15 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);}
 %left COLLATE.
 %right BITNOT.
 
-// An IDENTIFIER can be a generic identifier, or one of several
+// An "id" can be a generic identifier, or one of several
 // keywords.  Any non-standard keyword can also be an identifier.
 //
 %token_class id  ID|INDEXED.
 
+// A "number" can be either an integer or a floating point value
+%token_class number INTEGER|FLOAT.
+
+
 // The following directive causes tokens ABORT, AFTER, ASC, etc. to
 // fallback to ID if they will not parse as their original value.
 // This obviates the need for the "id" nonterminal.
@@ -254,8 +258,8 @@ typetoken(A) ::= typename(A) LP signed COMMA signed RP(Y). {
 %type typename {Token}
 typename(A) ::= ids(A).
 typename(A) ::= typename(A) ids(Y). {A.n=Y.n+(int)(Y.z-A.z);}
-signed ::= plus_num.
-signed ::= minus_num.
+signed ::= PLUS|MINUS number.
+signed ::= number.
 
 // "carglist" is a list of additional constraints that come after the
 // column name and column type in a CREATE TABLE statement.
@@ -807,12 +811,13 @@ insert_cmd(A) ::= REPLACE.            {A = OE_Replace;}
 %type idlist {IdList*}
 %destructor idlist {sqlite3IdListDelete(pParse->db, $$);}
 
-idlist_opt(A) ::= .                       {A = 0;}
+idlist_opt(A) ::= .                   {A = 0;}
 idlist_opt(A) ::= LP idlist(X) RP.    {A = X;}
 idlist(A) ::= idlist(A) COMMA nm(Y).
-    {A = sqlite3IdListAppend(pParse->db,A,&Y);}
+    {A = sqlite3IdListAppend(pParse,A,sqlite3NameFromToken(pParse->db,&Y));}
 idlist(A) ::= nm(Y).
-    {A = sqlite3IdListAppend(pParse->db,0,&Y); /*A-overwrites-Y*/}
+    {A = sqlite3IdListAppend(pParse,0,sqlite3NameFromToken(pParse->db,&Y));
+     /*A-overwrites-Y*/}
 
 /////////////////////////// Expression Processing /////////////////////////////
 //
@@ -1324,24 +1329,32 @@ cmd ::= VACUUM nm(X).          {sqlite3Vacuum(pParse,&X);}
 ///////////////////////////// The PRAGMA command /////////////////////////////
 //
 %ifndef SQLITE_OMIT_PRAGMA
-cmd ::= PRAGMA nm(X) dbnm(Z).                {sqlite3Pragma(pParse,&X,&Z,0,0);}
-cmd ::= PRAGMA nm(X) dbnm(Z) EQ nmnum(Y).    {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
-cmd ::= PRAGMA nm(X) dbnm(Z) LP nmnum(Y) RP. {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
-cmd ::= PRAGMA nm(X) dbnm(Z) EQ minus_num(Y). 
-                                             {sqlite3Pragma(pParse,&X,&Z,&Y,1);}
-cmd ::= PRAGMA nm(X) dbnm(Z) LP minus_num(Y) RP.
-                                             {sqlite3Pragma(pParse,&X,&Z,&Y,1);}
-
-nmnum(A) ::= plus_num(A).
-nmnum(A) ::= nm(A).
-nmnum(A) ::= ON(A).
-nmnum(A) ::= DELETE(A).
-nmnum(A) ::= DEFAULT(A).
+cmd ::= PRAGMA nm(X) dbnm(Z).                {sqlite3Pragma(pParse,&X,&Z,0);}
+cmd ::= PRAGMA nm(X) dbnm(Z) EQ pragma_arglist(Y).
+     {sqlite3Pragma(pParse,&X,&Z,Y);}
+cmd ::= PRAGMA nm(X) dbnm(Z) LP pragma_arglist(Y) RP.
+     {sqlite3Pragma(pParse,&X,&Z,Y);}
+
+%type pragma_arglist {IdList*}
+%destructor pragma_arglist {sqlite3IdListDelete(pParse->db,$$);}
+  
+pragma_arglist(A) ::= pragma_arg(X).
+   { A = sqlite3IdListAppend(pParse,0,X)/*A-overwrites-X*/; }
+pragma_arglist(A) ::= pragma_arglist(A) COMMA pragma_arg(Y).
+   { A = sqlite3IdListAppend(pParse,A,Y); }
+
+%type pragma_arg {char*}
+%destructor pragma_arg {sqlite3DbFree(pParse->db,$$);}
+pragma_arg(A) ::= number(X).
+    {A = sqlite3NameFromToken(pParse->db,&X);/*A-overwrites-X*/}
+pragma_arg(A) ::= nm(X).
+    {A = sqlite3NameFromToken(pParse->db,&X);/*A-overwrites-X*/}
+pragma_arg(A) ::= ON|DELETE|DEFAULT(X).
+    {A = sqlite3NameFromToken(pParse->db,&X);/*A-overwrites-X*/}
+pragma_arg(A) ::= PLUS number(X).   {A = sqlite3NameFromToken(pParse->db,&X);}
+pragma_arg(A) ::= MINUS number(X).  {A = sqlite3MPrintf(pParse->db,"-%T",&X);}
+
 %endif SQLITE_OMIT_PRAGMA
-%token_class number INTEGER|FLOAT.
-plus_num(A) ::= PLUS number(X).       {A = X;}
-plus_num(A) ::= number(A).
-minus_num(A) ::= MINUS number(X).     {A = X;}
 //////////////////////////// The CREATE TRIGGER command /////////////////////
 
 %ifndef SQLITE_OMIT_TRIGGER
index e774de34219d61b053c613865e18bce3cc7715c0..fef044d7d6063fddfeb4dc72949de76f2090dbf7 100644 (file)
@@ -282,11 +282,7 @@ const char *sqlite3JournalModename(int eMode){
 **
 ** Pragmas are of this form:
 **
-**      PRAGMA [schema.]id [= value]
-**
-** The identifier might also be a string.  The value is a string, and
-** identifier, or a number.  If minusFlag is true, then the value is
-** a number that was preceded by a minus sign.
+**      PRAGMA [schema.]id [= value-list]
 **
 ** If the left side is "database.id" then pId1 is the database name
 ** and pId2 is the id.  If the left side is just "id" then pId1 is the
@@ -296,8 +292,7 @@ void sqlite3Pragma(
   Parse *pParse, 
   Token *pId1,        /* First part of [schema.]id field */
   Token *pId2,        /* Second part of [schema.]id field, or NULL */
-  Token *pValue,      /* Token for <value>, or NULL */
-  int minusFlag       /* True if a '-' sign preceded <value> */
+  IdList *pValues     /* The value-list arguments.  NULL if omitted */
 ){
   char *zLeft = 0;       /* Nul-terminated UTF-8 string <id> */
   char *zRight = 0;      /* Nul-terminated UTF-8 string <value>, or NULL */
@@ -312,14 +307,14 @@ void sqlite3Pragma(
   Vdbe *v = sqlite3GetVdbe(pParse);  /* Prepared statement */
   const struct sPragmaNames *pPragma;
 
-  if( v==0 ) return;
+  if( v==0 ) goto pragma_out;
   sqlite3VdbeRunOnlyOnce(v);
   pParse->nMem = 2;
 
   /* Interpret the [schema.] part of the pragma statement. iDb is the
   ** index of the database this pragma is being applied to in db.aDb[]. */
   iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId);
-  if( iDb<0 ) return;
+  if( iDb<0 ) goto pragma_out;
   pDb = &db->aDb[iDb];
 
   /* If the temp database has been explicitly named as part of the 
@@ -330,12 +325,8 @@ void sqlite3Pragma(
   }
 
   zLeft = sqlite3NameFromToken(db, pId);
-  if( !zLeft ) return;
-  if( minusFlag ){
-    zRight = sqlite3MPrintf(db, "-%T", pValue);
-  }else{
-    zRight = sqlite3NameFromToken(db, pValue);
-  }
+  if( !zLeft ) goto pragma_out;
+  if( pValues ) zRight = pValues->a[0].zName;
 
   assert( pId2 );
   zDb = pId2->n>0 ? pDb->zDbSName : 0;
@@ -1984,7 +1975,7 @@ void sqlite3Pragma(
 
 pragma_out:
   sqlite3DbFree(db, zLeft);
-  sqlite3DbFree(db, zRight);
+  sqlite3IdListDelete(db, pValues);
 }
 
 #endif /* SQLITE_OMIT_PRAGMA */
index 2d13f2635dc183139f050d6f76ddee13079fed86..7b620b93e989f1ce1ed051749a78fc00280d7761 100644 (file)
@@ -3566,7 +3566,7 @@ void sqlite3ExprListDelete(sqlite3*, ExprList*);
 u32 sqlite3ExprListFlags(const ExprList*);
 int sqlite3Init(sqlite3*, char**);
 int sqlite3InitCallback(void*, int, char**, char**);
-void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
+void sqlite3Pragma(Parse*,Token*,Token*,IdList*);
 void sqlite3ResetAllSchemasOfConnection(sqlite3*);
 void sqlite3ResetOneSchema(sqlite3*,int);
 void sqlite3CollapseDatabaseArray(sqlite3*);
@@ -3641,7 +3641,7 @@ void sqlite3DeleteTable(sqlite3*, Table*);
 #endif
 void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int);
 void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*);
-IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*);
+IdList *sqlite3IdListAppend(Parse*, IdList*, char*);
 int sqlite3IdListIndex(IdList*,const char*);
 SrcList *sqlite3SrcListEnlarge(sqlite3*, SrcList*, int, int);
 SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*);