26368b16a37d3845623054270770df7e905c32f1
kent
  Fri Apr 19 10:06:02 2013 -0700
Adding index and auto keywords to autoSql columns.
diff --git src/lib/asParse.c src/lib/asParse.c
index 17d5982..6c867cb 100644
--- src/lib/asParse.c
+++ src/lib/asParse.c
@@ -1,22 +1,23 @@
 /* asParse - parse out an autoSql .as file. */
 
 #include "common.h"
 #include "linefile.h"
 #include "tokenizer.h"
 #include "dystring.h"
 #include "asParse.h"
+#include "sqlNum.h"
 
 
 /* n.b. switched double/float from %f to %g to partially address losing
  * precision.  Values like 2e-12 were being rounded to 0.0 with %f.  While %g
  * doesn't match the precision of the database fields, specifying a larger
  * precision with %g resulted in numbers like 1.9999999999999999597733e-12,
  *  which might impact load time.  This issue needs more investigation.*/
 struct asTypeInfo asTypes[] = {
     {t_double,  "double",  FALSE, FALSE, "double",            "double",        "Double",   "Double",   "%g",   "FloatField"},
     {t_float,   "float",   FALSE, FALSE, "float",             "float",         "Float",    "Float",    "%g",   "FloatField"},
     {t_char,    "char",    FALSE, FALSE, "char",              "char",          "Char",     "Char",     "%c",   "CharField"},
     {t_int,     "int",     FALSE, FALSE, "int",               "int",           "Signed",   "Signed",   "%d",   "IntegerField"},
     {t_uint,    "uint",    TRUE,  FALSE, "int unsigned",      "unsigned",      "Unsigned", "Unsigned", "%u",   "PositiveIntegerField"},
     {t_short,   "short",   FALSE, FALSE, "smallint",          "short",         "Short",    "Signed",   "%d",   "SmallIntegerField"},
     {t_ushort,  "ushort",  TRUE,  FALSE, "smallint unsigned", "unsigned short","Ushort",   "Unsigned", "%u",   "SmallPositiveIntegerField"},
@@ -173,52 +174,93 @@
 tokenizerMustHaveNext(tkz);
 while (tkz->string[0] != ')')
     {
     slSafeAddHead(&col->values, slNameNew(tkz->string));
     /* look for `,' or `)', but allow `,' after last token */
     tokenizerMustHaveNext(tkz);
     if (!((tkz->string[0] == ',') || (tkz->string[0] == ')')))
         tokenizerErrAbort(tkz, "expected `,' or `)' got `%s'", tkz->string);
     if (tkz->string[0] != ')')
         tokenizerMustHaveNext(tkz);
     }
 tokenizerMustMatch(tkz, ")");
 slReverse(&col->values);
 }
 
+int tokenizerUnsignedVal(struct tokenizer *tkz)
+/* Ensure current token is an unsigned integer and return value */
+{
+if (!isdigit(tkz->string[0]))
+    {
+    struct lineFile *lf = tkz->lf;
+    errAbort("expecting number got %s line %d of %s", tkz->string, lf->lineIx, lf->fileName);
+    }
+return sqlUnsigned(tkz->string);
+}
+
+struct asIndex *asParseIndex(struct tokenizer *tkz, struct asColumn *col)
+/* See if there's an index key word and if so parse it and return an asIndex
+ * based on it.  If not an index key word then just return NULL. */
+{
+struct asIndex *index = NULL;
+if (sameString(tkz->string, "primary") || sameString(tkz->string, "unique")
+	|| sameString(tkz->string, "index") )
+    {
+    AllocVar(index);
+    index->type = cloneString(tkz->string);
+    tokenizerMustHaveNext(tkz);
+    if (tkz->string[0] == '[')
+	{
+	tokenizerMustHaveNext(tkz);
+	index->size = tokenizerUnsignedVal(tkz);
+	tokenizerMustHaveNext(tkz);
+	tokenizerMustMatch(tkz, "]");
+	}
+    }
+return index;
+}
+
 static void asParseColDef(struct tokenizer *tkz, struct asObject *obj)
-/* Parse a column definintion */
+/* Parse a column definition */
 {
 struct asColumn *col;
 AllocVar(col);
 
 col->lowType = findLowType(tkz);
 tokenizerMustHaveNext(tkz);
 
 if (col->lowType->type == t_object || col->lowType->type == t_simple)
     {
     col->obName = cloneString(tkz->string);
     tokenizerMustHaveNext(tkz);
     }
 
 if (tkz->string[0] == '[')
     asParseColArraySpec(tkz, obj, col);
 else if (tkz->string[0] == '(')
     asParseColSymSpec(tkz, obj, col);
 
 col->name = cloneString(tkz->string);
 tokenizerMustHaveNext(tkz);
+col->index = asParseIndex(tkz, col);
+if (sameString(tkz->string, "auto"))
+    {
+    col->autoIncrement = TRUE;
+    if (!asTypesIsInt(col->lowType->type))
+        errAbort("error - auto with non-integer type for field %s", col->name);
+    tokenizerMustHaveNext(tkz);
+    }
 tokenizerMustMatch(tkz, ";");
 col->comment = cloneString(tkz->string);
 tokenizerMustHaveNext(tkz);
 if (col->lowType->type == t_char && col->fixedSize != 0)
     col->isList = FALSE;	/* It's not really a list... */
 slAddHead(&obj->columnList, col);
 }
 
 static struct asObject *asParseTableDef(struct tokenizer *tkz)
 /* Parse a table or object definintion */
 {
 struct asObject *obj;
 AllocVar(obj);
 if (sameWord(tkz->string, "table"))
     obj->isTable = TRUE;