440fe3df0fd71f302ac763de3a604dacb45b600e
galt
  Fri Jan 23 19:23:29 2015 -0800
Added a check for duplicate column names in .as autoSql table definition used by big* and other utilities. This will also catch accidentally duplicated lines in an editor. Check for unique column names is case-insensitive which is also what myqsl does.
diff --git src/lib/asParse.c src/lib/asParse.c
index 2e4ae82..2b8a5a1 100644
--- src/lib/asParse.c
+++ src/lib/asParse.c
@@ -129,40 +129,57 @@
 for (i = 0;  i < ArraySize(asTypes);  i++)
     if (sameString(buf, asTypes[i].sqlName))
 	{
 	if (isArray)
 	    {
 	    int typeLen = strlen(buf);
 	    safef(buf+typeLen, sizeof(buf)-typeLen, "[%d]", arraySize);
 	    return buf;
 	    }
 	else
 	    return asTypes[i].name;
 	}
 return NULL;
 }
 
-static struct asColumn *mustFindColumn(struct asObject *table, char *colName)
-/* Return column or die. */
+static struct asColumn *findColumn(struct asObject *table, char *colName)
+/* Return column or null. */
 {
 struct asColumn *col;
 
 for (col = table->columnList; col != NULL; col = col->next)
     {
     if (sameWord(col->name, colName))
 	return col;
     }
+return NULL;
+}
+
+static void mustNotFindColumn(struct asObject *table, char *colName)
+/* Die if column found. */
+{
+struct asColumn *col = findColumn(table, colName);
+if (col)
+    errAbort("duplicate column names found: %s, %s", col->name, colName);
+}
+
+
+static struct asColumn *mustFindColumn(struct asObject *table, char *colName)
+/* Return column or die. */
+{
+struct asColumn *col = findColumn(table, colName);
+if (!col)
     errAbort("Couldn't find column %s", colName);
 return NULL;
 }
 
 static struct asObject *findObType(struct asObject *objList, char *obName)
 /* Find object with given name. */
 {
 struct asObject *obj;
 for (obj = objList; obj != NULL; obj = obj->next)
     {
     if (sameWord(obj->name, obName))
 	return obj;
     }
 return NULL;
 }
@@ -258,30 +275,31 @@
 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);
+mustNotFindColumn(obj, col->name);  // check for duplicate column name
 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);