Add the capability to track the maximum depth of the LALR(1) parser stack
so that critical applications can check to see if they are getting close
to limits. (CVS 5481)

FossilOrigin-Name: ef0250f3dc769a4acd534f31fa06d90922d4145b
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 246ba6e..5639cbf 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -30,7 +30,7 @@
 ** the version number) and changes its name to "sqlite3.h" as
 ** part of the build process.
 **
-** @(#) $Id: sqlite.h.in,v 1.379 2008/07/25 08:49:00 danielk1977 Exp $
+** @(#) $Id: sqlite.h.in,v 1.380 2008/07/25 15:39:04 drh Exp $
 */
 #ifndef _SQLITE3_H_
 #define _SQLITE3_H_
@@ -6119,6 +6119,10 @@
 ** internal equivalents).  The value of interest is return in the
 ** *pHighwater parameter to [sqlite3_status()].  The value written
 ** into the *pCurrent parameter is undefined.</dd>
+**
+** <dt>SQLITE_STATUS_PARSER_STACK</dt>
+** <dd>This parameter records the deepest parser stack.  It is only
+** meaningful if SQLite is compiled with YYTRACKMAXSTACKDEPTH.</dd>
 ** </dl>
 **
 ** New status parameters may be added from time to time.
@@ -6129,6 +6133,7 @@
 #define SQLITE_STATUS_SCRATCH_USED         3
 #define SQLITE_STATUS_SCRATCH_OVERFLOW     4
 #define SQLITE_STATUS_MALLOC_SIZE          5
+#define SQLITE_STATUS_PARSER_STACK         6
 
 
 /*
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 45cbdfd..5672394 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.745 2008/07/25 08:49:00 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.746 2008/07/25 15:39:04 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -1790,6 +1790,7 @@
   int isMallocInit;                 /* True after malloc is initialized */
   sqlite3_mutex *pInitMutex;        /* Mutex used by sqlite3_initialize() */
   int nSmall;                       /* alloc size threshold used by mem6.c */
+  int mxParserStack;                /* maximum depth of the parser stack */
 };
 
 /*
@@ -2195,6 +2196,9 @@
 void *sqlite3ParserAlloc(void*(*)(size_t));
 void sqlite3ParserFree(void*, void(*)(void*));
 void sqlite3Parser(void*, int, Token, Parse*);
+#ifdef YYTRACKMAXSTACKDEPTH
+  int sqlite3ParserStackPeak(void*);
+#endif
 
 int sqlite3AutoLoadExtensions(sqlite3*);
 #ifndef SQLITE_OMIT_LOAD_EXTENSION
diff --git a/src/status.c b/src/status.c
index 5d7d6fa..504f44e 100644
--- a/src/status.c
+++ b/src/status.c
@@ -13,7 +13,7 @@
 ** This module implements the sqlite3_status() interface and related
 ** functionality.
 **
-** $Id: status.c,v 1.3 2008/07/11 16:15:18 drh Exp $
+** $Id: status.c,v 1.4 2008/07/25 15:39:04 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -21,8 +21,8 @@
 ** Variables in which to record status information.
 */
 static struct {
-  int nowValue[6];         /* Current value */
-  int mxValue[6];          /* Maximum value */
+  int nowValue[7];         /* Current value */
+  int mxValue[7];          /* Maximum value */
 } sqlite3Stat;
 
 
diff --git a/src/test_config.c b/src/test_config.c
index b62f8c0..b3007aa 100644
--- a/src/test_config.c
+++ b/src/test_config.c
@@ -16,7 +16,7 @@
 ** The focus of this file is providing the TCL testing layer
 ** access to compile-time constants.
 **
-** $Id: test_config.c,v 1.31 2008/07/08 23:40:20 drh Exp $
+** $Id: test_config.c,v 1.32 2008/07/25 15:39:04 drh Exp $
 */
 
 #include "sqliteLimit.h"
@@ -437,6 +437,12 @@
   Tcl_SetVar2(interp, "sqlite_options", "secure_delete", "0", TCL_GLOBAL_ONLY);
 #endif
 
+#ifdef YYTRACKMAXSTACKDEPTH
+  Tcl_SetVar2(interp, "sqlite_options", "yytrackmaxstackdepth", "1", TCL_GLOBAL_ONLY);
+#else
+  Tcl_SetVar2(interp, "sqlite_options", "yytrackmaxstackdepth", "0", TCL_GLOBAL_ONLY);
+#endif
+
 #define LINKVAR(x) { \
     static const int cv_ ## x = SQLITE_ ## x; \
     Tcl_LinkVar(interp, "SQLITE_" #x, (char *)&(cv_ ## x), \
diff --git a/src/test_malloc.c b/src/test_malloc.c
index ea5c2d6..0c963ad 100644
--- a/src/test_malloc.c
+++ b/src/test_malloc.c
@@ -13,7 +13,7 @@
 ** This file contains code used to implement test interfaces to the
 ** memory allocation subsystem.
 **
-** $Id: test_malloc.c,v 1.40 2008/07/25 08:49:00 danielk1977 Exp $
+** $Id: test_malloc.c,v 1.41 2008/07/25 15:39:04 drh Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -1083,6 +1083,7 @@
     { "SQLITE_STATUS_SCRATCH_USED",        SQLITE_STATUS_SCRATCH_USED        },
     { "SQLITE_STATUS_SCRATCH_OVERFLOW",    SQLITE_STATUS_SCRATCH_OVERFLOW    },
     { "SQLITE_STATUS_MALLOC_SIZE",         SQLITE_STATUS_MALLOC_SIZE         },
+    { "SQLITE_STATUS_PARSER_STACK",        SQLITE_STATUS_PARSER_STACK        },
   };
   Tcl_Obj *pResult;
   if( objc!=3 ){
diff --git a/src/tokenize.c b/src/tokenize.c
index c7769f9..70b2d3a 100644
--- a/src/tokenize.c
+++ b/src/tokenize.c
@@ -15,7 +15,7 @@
 ** individual tokens and sends those tokens one-by-one over to the
 ** parser for analysis.
 **
-** $Id: tokenize.c,v 1.146 2008/07/08 19:34:07 drh Exp $
+** $Id: tokenize.c,v 1.147 2008/07/25 15:39:04 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -455,6 +455,11 @@
     }
     sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
   }
+#ifdef YYTRACKMAXSTACKDEPTH
+  sqlite3StatusSet(SQLITE_STATUS_PARSER_STACK,
+      sqlite3ParserStackPeak(pEngine)
+  );
+#endif /* YYDEBUG */
   sqlite3ParserFree(pEngine, sqlite3_free);
   if( db->mallocFailed ){
     pParse->rc = SQLITE_NOMEM;