I am not suggesting not to use them internally, just not user facing. What about this?

    protected def columnInternal( name, columnOptions )

    // First user api
    protected def mkRelationalColumnOptions( primaryKey, autoIncrement, default )
      = Set() ++ (if(primaryKey) Some(O.PrimaryKey) else None) ++ ...
    def column( name, primaryKey=false, autoIncrement=false, default=None ){
      columnInternal( name, mkRelationalColumnOptions(primaryKey,autoIncrement,default) )
    }
    def column( name, primaryKey=false, autoIncrement=false, default=None, dbType = "" ){
      columnInternal(
        name, Set() ++ (if(type != "") Some(O.DBType(dbType)) else None) ++ 
        mkRelationalColumnOptions(primaryKey,autoIncrement,default)
    }

This seems to make the user facing API simpler. WDYT?

Regarding the meta model. Yes I agree, we need something extensible (ColumnOptions) to support special needs of driver subclasses. As a side-node, given a ColumnOption, it is not completely trivial to just generate the code that creates it again. They could even contain non-recreatable objects or resources in theory. If we want the code-generator to automatically incorporate custom column options in the generated code we have to think about how to achieve that. Should tpe become a ColumnOption, too? E.g. JdbcType ?