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;