# for Emacs: -*- mode: org; mode: flyspell; fill-column: 79 -*- # The database schema version is stored in sqlite's "PRAGMA user_version", # which is faster to access than a specific table. | TABLE | files | file | | Stores the list of source and LI files | |----------+---------------+-----------------+---+------------------------------------------------------------------------------------------| | id | AUTOINCREMENT | PK | | | | path | TEXT | NOT NULL, INDEX, NOCASE | | Full normalized absolute path for the file. Casing is not normalized | | stamp | timestamp | NULL | | The timestamp the last time the file was read (only set for LI files for efficiency) | | language | TEXT | NOT NULL | | The language for this file (so that we can limit queries to specific languages), or "li" | | project | FK files() | NULL | | V2.0: The project to which a source file belongs. With aggregate projects, a source file might occur several times in this table, each time with a different project. | | TABLE | f2f_kind | | | All kinds of file relationships | |-------+---------------+----------+---+---------------------------------| | id | AUTOINCREMENT | PK | | | | name | TEXT | NOT NULL | | | # No unique constraint error for (fromFile, toFile, kind), since a given source # file might for instance have multiple ALI files if it contains multiple Ada # units. # 'is_array' is mostly used by the debugger to know whether the user should be # able to dereference the variable. | TABLE | f2f | | | Stores relationships between files | |----------+-----------------------+-------------------+---+------------------------------------| | fromFile | FK files(links) | NOT NULL, NOINDEX, PK | | | | toFile | FK files(linked_from) | NOT NULL, NOINDEX, PK | | | | kind | FK f2f_kind() | NOT NULL, NOINDEX, PK | | Kind of dependency | | TABLE | entity_kinds | entity_kinds | | General kinds for entities (their metaclasses) | |--------------------------+--------------+-------------------+-------+------------------------------------------------| | id | CHARACTER(1) | PK | | | | display | TEXT | NOT NULL, NOINDEX | | How to display this entity kind | | is_subprogram | BOOLEAN | NOINDEX | false | | | is_container | BOOLEAN | NOINDEX | false | | | body_is_full_declaration | BOOLEAN | NOINDEX | false | | | is_abstract | BOOLEAN | NOINDEX | false | | | is_generic | BOOLEAN | NOINDEX | false | | | is_access | BOOLEAN | NOINDEX | false | | | is_type | BOOLEAN | NOINDEX | false | | | is_printable_in_gdb | BOOLEAN | NOINDEX | false | | | is_array | BOOLEAN | NOINDEX | false | | | has_methods | BOOLEAN | NOINDEX | false | | # An entity is known by its name and the location of its declaration. An entry # in this table cannot exist without a corresponding declaration. To make # queries faster (when loading ALI files), we thus store the declaration # directly in this table, rather than as a reference. This speeds up the check # whether an entity already exists in the table, and removes one INSERT when # we need to create the entity. # # ALI files do not provide the closure of the needed entities: for instance, # an entity A might be an instantiation of a generic entity B. But all the # ALI file provides is the file and line where B is declared, not its column. # In addition, B does not necessarily appear in a.ali. So we need a forward # declaration for B (since we don't know its name, we insert a new unnamed entity # at the given line and column -1). We'll try to complete it when b.ali is # parsed eventually. # # Indexes: we tried two indexes: idx1 on name,decl_file,decl_line,decl_column, # and idx2 on decl_file,decl_line,decl_column. # Testing with two queries Find_Predefined_Entity (ie using name) and # Find_Entity_From_Decl (ie only loc): # | predefined | form_decl # ----------------+------------------------+---------------------- # idx1 + idx2 | covering idx1 (~1row) | idx2 (~2rows) # idx1 | covering idx1 (~1row) | scan (~238rows) # idx2 | idx2 (~2rows) | idx2 (~2rows) # no index | scan (~23rows) | scan (~238rows) # So having only idx2 seems a good compromise (single index is faster at creation) | TABLE | entities | entity | | | |-----------------+---------------------------------+---------------------------+-------+------------------------------------------------------------------| | id | AUTOINCREMENT | PK | | | | name | TEXT | NOT NULL, NOINDEX, NOCASE | | Can be empty for forward decls (see above). Must be UTF-8 | | kind | FK entity_kinds() | NOT NULL, NOINDEX | | The E_Kind for this entity | | decl_file | FK files(references) | NOT NULL, NOINDEX | | Set to -1 for a predefined entity | | decl_line | INTEGER | NOT NULL, NOINDEX | | Set to -1 for a predefined entity | | decl_column | INTEGER | NOT NULL, NOINDEX | | Set to -1 for a predefined entity | | decl_caller | FK entities | NULL, NOINDEX | | Parent entity | | mangled_name | TEXT | NULL | | Mangled name of the entity, if applicable | | exported | BOOLEAN | NOT NULL, NOINDEX | false | Whether the mangled name is an export or an import of the entity | | is_global | BOOLEAN | NOT NULL, NOINDEX | false | Whether this is a global entity (library-level in Ada) | | is_static_local | BOOLEAN | NOT NULL, NOINDEX | false | Whether this is a 'static' variable in C/C++ | |-----------------+---------------------------------+---------------------------+-------+------------------------------------------------------------------| | INDEX: | decl_file,decl_line,decl_column | entity_loc | | Needed during parse | | INDEX: | decl_caller | entity_decl_caller | | | # Store links between entities. # For instance, pointer to the parent types, pointed type, returned type, # renames, primitive operations, instantiation_Of, parameters # - Called_Entities: not stored here, it is enough to search the # References table using the caller information | TABLE | e2e_kind | | | Links between entities | |-------+---------------+-------------------+---+------------------------| | id | AUTOINCREMENT | PK | | | | name | TEXT | NOT NULL, NOINDEX | | | # entity-to-entity relationships. # We cannot have a (fromEntity, toEntity, kind) primary key, because in some # cases the relationships will be duplicated (for instance, the .gli format for # C files sometimes improperly record columns for entities. Thus a C subprogram # might appear to have the same parameter multiple times, although in reality # each parameter is different but just appears to be on the same column): # 37V31*gnu_dev_makedev{long long unsigned int} 55>1 55>1 55b1 60t1 # 55m1 __major{unsigned int} # 55m1 __minor{unsigned int} 57r12 | TABLE | e2e | | | | |------------+--------------------------+-------------------+---+------------------------------------------------------------------------------| | fromEntity | FK entities(links) | NOT NULL, NOINDEX, PK | | | | toEntity | FK entities(linked_from) | NOT NULL, NOINDEX, PK | | | | kind | FK e2e_kind() | NOT NULL, NOINDEX, PK | | The type of link. | | order_by | INTEGER | NOT NULL, NOINDEX | 1 | Ordering among the references. Used for instance for subprogram parameters | |------------+--------------------------+-------------------+---+------------------------------------------------------------------------------| | INDEX: | "fromEntity" | e2e_from | | Not needed during parsing | | INDEX: | "toEntity" | e2e_to | | Not needed during parsing | | TABLE | reference_kinds | reference_kind | | Kind of references | |-------------------+-----------------+------------------+-------+---------------------------------------------------------| | id | CHARACTER(1) | PK | | The character found in the ALI file | | display | TEXT | NOT NULL,NOINDEX | | Label to display the reference | | is_real | BOOLEAN | NOINDEX | true | Whether the name of the entity appears at that location | | is_read | BOOLEAN | NOINDEX | false | | | is_write | BOOLEAN | NOINDEX | false | | | is_end | BOOLEAN | NOINDEX | false | Whether this marks the end of a scope (spec or body) | | show_in_callgraph | BOOLEAN | NOINDEX | true | Whether this ref. should be shown in the call graph | | is_dispatching | BOOLEAN | NOINDEX | false | Whether this is a dispatching call | | is_implicit | BOOLEAN | NOINDEX | false | | # We store instantiations as a string for now: currently, they are only used to # display tooltips in GPS as to where an entity comes from. This can easily be # parsed from the string. But the string also makes it easy to find all # references from the same instance as the one the user clicked on, which would # be harder (and slower) to do if we stored the instances in a separate table, # where each instance potentially points to its parent. # The format is "file1|line1 file2|line2 ..." where file1|line1 is itself # instantiated at file2|line2. # # This table might contain duplicates (for instance from .gli files). It is # also possible that a given location is duplicated with different kinds, for # instance the argument for an "in out" parameter has both a "read" and # "modified" entries. # # Indexes: we have an index on "file". We used to have one on # "file,line,column" instead. In practice, "explain query plan" shows that both # have roughly the same performance on the DELETE query used to cleanup # references when updating an ALI file, and on the SELECT query to find which # entity occurs at a given location. However, the database is slightly smaller, # and the generation of the index slightly faster, when only storing the file # in the index. | TABLE | entity_refs | entity_ref | | | |--------------------+-------------------------+--------------------+---+-----------------------------------------------------| | entity | FK entities(references) | NOT NULL, NOINDEX | | The entity to which we have a reference | | file | FK files(references) | NOT NULL, NOINDEX | | | | line | INTEGER | NOT NULL, NOINDEX | | | | column | INTEGER | NOT NULL, NOINDEX | | | | kind | FK reference_kinds() | NOT NULL, NOINDEX | | Type of reference (same letter as in ALI files) | | caller | FK entities(calling) | NULL, NOINDEX | | Enclosing entity at that location | | from_instantiation | TEXT | NOINDEX | | Instances in which the ref occurs | |--------------------+-------------------------+--------------------+---+-----------------------------------------------------| | INDEX: | "file" | entity_refs_file | | Needed during parsing to cleanup outdated ALI files | | INDEX: | "entity" | entity_refs_entity | | Not needed during parsing | | INDEX: | line,"column" | entity_refs_loc | | Not needed during parsing | | INDEX: | caller | refs_caller | | |