mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Merge branch 'main' into feature/oracle-model
This commit is contained in:
@@ -53,7 +53,7 @@ jobs:
|
||||
- name: Create database
|
||||
run: |
|
||||
"${CODEQL}" database create \
|
||||
--search-path "${{ github.workspace }}"
|
||||
--search-path "${{ github.workspace }}" \
|
||||
--threads 4 \
|
||||
--language ql --source-root "${{ github.workspace }}/repo" \
|
||||
"${{ runner.temp }}/database"
|
||||
|
||||
@@ -36,5 +36,5 @@ pub fn run(options: Options) -> std::io::Result<()> {
|
||||
},
|
||||
];
|
||||
|
||||
generate(languages, options.dbscheme, options.library, false)
|
||||
generate(languages, options.dbscheme, options.library)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
|
||||
import codeql.Locations as L
|
||||
|
||||
/** Holds if the database is an overlay. */
|
||||
overlay[local]
|
||||
private predicate isOverlay() { databaseMetadata("isOverlay", "true") }
|
||||
|
||||
module QL {
|
||||
/** The base class for all AST nodes */
|
||||
class AstNode extends @ql_ast_node {
|
||||
@@ -48,6 +52,30 @@ module QL {
|
||||
final override string getAPrimaryQlClass() { result = "ReservedWord" }
|
||||
}
|
||||
|
||||
/** Gets the file containing the given `node`. */
|
||||
overlay[local]
|
||||
private @file getNodeFile(@ql_ast_node node) {
|
||||
exists(@location_default loc | ql_ast_node_location(node, loc) |
|
||||
locations_default(loc, result, _, _, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `file` was extracted as part of the overlay database. */
|
||||
overlay[local]
|
||||
private predicate discardFile(@file file) { isOverlay() and file = getNodeFile(_) }
|
||||
|
||||
/** Holds if `node` is in the `file` and is part of the overlay base database. */
|
||||
overlay[local]
|
||||
private predicate discardableAstNode(@file file, @ql_ast_node node) {
|
||||
not isOverlay() and file = getNodeFile(node)
|
||||
}
|
||||
|
||||
/** Holds if `node` should be discarded, because it is part of the overlay base and is in a file that was also extracted as part of the overlay database. */
|
||||
overlay[discard_entity]
|
||||
private predicate discardAstNode(@ql_ast_node node) {
|
||||
exists(@file file | discardableAstNode(file, node) and discardFile(file))
|
||||
}
|
||||
|
||||
/** A class representing `add_expr` nodes. */
|
||||
class AddExpr extends @ql_add_expr, AstNode {
|
||||
/** Gets the name of the primary QL class for this element. */
|
||||
@@ -1318,6 +1346,30 @@ module Dbscheme {
|
||||
final override string getAPrimaryQlClass() { result = "ReservedWord" }
|
||||
}
|
||||
|
||||
/** Gets the file containing the given `node`. */
|
||||
overlay[local]
|
||||
private @file getNodeFile(@dbscheme_ast_node node) {
|
||||
exists(@location_default loc | dbscheme_ast_node_location(node, loc) |
|
||||
locations_default(loc, result, _, _, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `file` was extracted as part of the overlay database. */
|
||||
overlay[local]
|
||||
private predicate discardFile(@file file) { isOverlay() and file = getNodeFile(_) }
|
||||
|
||||
/** Holds if `node` is in the `file` and is part of the overlay base database. */
|
||||
overlay[local]
|
||||
private predicate discardableAstNode(@file file, @dbscheme_ast_node node) {
|
||||
not isOverlay() and file = getNodeFile(node)
|
||||
}
|
||||
|
||||
/** Holds if `node` should be discarded, because it is part of the overlay base and is in a file that was also extracted as part of the overlay database. */
|
||||
overlay[discard_entity]
|
||||
private predicate discardAstNode(@dbscheme_ast_node node) {
|
||||
exists(@file file | discardableAstNode(file, node) and discardFile(file))
|
||||
}
|
||||
|
||||
/** A class representing `annotName` tokens. */
|
||||
class AnnotName extends @dbscheme_token_annot_name, Token {
|
||||
/** Gets the name of the primary QL class for this element. */
|
||||
@@ -1654,6 +1706,30 @@ module Blame {
|
||||
final override string getAPrimaryQlClass() { result = "ReservedWord" }
|
||||
}
|
||||
|
||||
/** Gets the file containing the given `node`. */
|
||||
overlay[local]
|
||||
private @file getNodeFile(@blame_ast_node node) {
|
||||
exists(@location_default loc | blame_ast_node_location(node, loc) |
|
||||
locations_default(loc, result, _, _, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `file` was extracted as part of the overlay database. */
|
||||
overlay[local]
|
||||
private predicate discardFile(@file file) { isOverlay() and file = getNodeFile(_) }
|
||||
|
||||
/** Holds if `node` is in the `file` and is part of the overlay base database. */
|
||||
overlay[local]
|
||||
private predicate discardableAstNode(@file file, @blame_ast_node node) {
|
||||
not isOverlay() and file = getNodeFile(node)
|
||||
}
|
||||
|
||||
/** Holds if `node` should be discarded, because it is part of the overlay base and is in a file that was also extracted as part of the overlay database. */
|
||||
overlay[discard_entity]
|
||||
private predicate discardAstNode(@blame_ast_node node) {
|
||||
exists(@file file | discardableAstNode(file, node) and discardFile(file))
|
||||
}
|
||||
|
||||
/** A class representing `blame_entry` nodes. */
|
||||
class BlameEntry extends @blame_blame_entry, AstNode {
|
||||
/** Gets the name of the primary QL class for this element. */
|
||||
@@ -1767,6 +1843,30 @@ module JSON {
|
||||
final override string getAPrimaryQlClass() { result = "ReservedWord" }
|
||||
}
|
||||
|
||||
/** Gets the file containing the given `node`. */
|
||||
overlay[local]
|
||||
private @file getNodeFile(@json_ast_node node) {
|
||||
exists(@location_default loc | json_ast_node_location(node, loc) |
|
||||
locations_default(loc, result, _, _, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `file` was extracted as part of the overlay database. */
|
||||
overlay[local]
|
||||
private predicate discardFile(@file file) { isOverlay() and file = getNodeFile(_) }
|
||||
|
||||
/** Holds if `node` is in the `file` and is part of the overlay base database. */
|
||||
overlay[local]
|
||||
private predicate discardableAstNode(@file file, @json_ast_node node) {
|
||||
not isOverlay() and file = getNodeFile(node)
|
||||
}
|
||||
|
||||
/** Holds if `node` should be discarded, because it is part of the overlay base and is in a file that was also extracted as part of the overlay database. */
|
||||
overlay[discard_entity]
|
||||
private predicate discardAstNode(@json_ast_node node) {
|
||||
exists(@file file | discardableAstNode(file, node) and discardFile(file))
|
||||
}
|
||||
|
||||
class UnderscoreValue extends @json_underscore_value, AstNode { }
|
||||
|
||||
/** A class representing `array` nodes. */
|
||||
|
||||
@@ -108,6 +108,12 @@ yaml_locations(unique int locatable: @yaml_locatable ref,
|
||||
|
||||
@yaml_locatable = @yaml_node | @yaml_error;
|
||||
|
||||
/*- Database metadata -*/
|
||||
databaseMetadata(
|
||||
string metadataKey: string ref,
|
||||
string value: string ref
|
||||
);
|
||||
|
||||
/*- QL dbscheme -*/
|
||||
@ql_add_expr_left_type = @ql_add_expr | @ql_aggregate | @ql_call_or_unqual_agg_expr | @ql_comp_term | @ql_conjunction | @ql_disjunction | @ql_expr_annotation | @ql_if_term | @ql_implication | @ql_in_expr | @ql_instance_of | @ql_literal | @ql_mul_expr | @ql_negation | @ql_par_expr | @ql_prefix_cast | @ql_qualified_expr | @ql_quantified | @ql_range | @ql_set_literal | @ql_special_call | @ql_super_ref | @ql_unary_expr | @ql_variable
|
||||
|
||||
|
||||
@@ -22436,5 +22436,41 @@
|
||||
</dep>
|
||||
</dependencies>
|
||||
</relation>
|
||||
<relation>
|
||||
<name>databaseMetadata</name>
|
||||
<cardinality>1</cardinality>
|
||||
<columnsizes>
|
||||
<e>
|
||||
<k>metadataKey</k>
|
||||
<v>1</v>
|
||||
</e>
|
||||
<e>
|
||||
<k>value</k>
|
||||
<v>1</v>
|
||||
</e>
|
||||
</columnsizes>
|
||||
<dependencies>
|
||||
<dep>
|
||||
<src>metadataKey</src>
|
||||
<trg>value</trg>
|
||||
<val>
|
||||
<hist>
|
||||
<budget>12</budget>
|
||||
<bs/>
|
||||
</hist>
|
||||
</val>
|
||||
</dep>
|
||||
<dep>
|
||||
<src>value</src>
|
||||
<trg>metadataKey</trg>
|
||||
<val>
|
||||
<hist>
|
||||
<budget>12</budget>
|
||||
<bs/>
|
||||
</hist>
|
||||
</val>
|
||||
</dep>
|
||||
</dependencies>
|
||||
</relation>
|
||||
</stats>
|
||||
</dbstats>
|
||||
|
||||
@@ -28,5 +28,5 @@ pub fn run(options: Options) -> std::io::Result<()> {
|
||||
},
|
||||
];
|
||||
|
||||
generate(languages, options.dbscheme, options.library, true)
|
||||
generate(languages, options.dbscheme, options.library)
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
description: Add databaseMetadata relation
|
||||
compatibility: full
|
||||
databaseMetadata.rel: delete
|
||||
@@ -108,6 +108,12 @@ yaml_locations(unique int locatable: @yaml_locatable ref,
|
||||
|
||||
@yaml_locatable = @yaml_node | @yaml_error;
|
||||
|
||||
/*- Database metadata -*/
|
||||
databaseMetadata(
|
||||
string metadataKey: string ref,
|
||||
string value: string ref
|
||||
);
|
||||
|
||||
|
||||
// from prefix.dbscheme
|
||||
#keyset[id]
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Add databaseMetadata relation
|
||||
compatibility: full
|
||||
@@ -17,7 +17,6 @@ pub fn generate(
|
||||
languages: Vec<language::Language>,
|
||||
dbscheme_path: PathBuf,
|
||||
ql_library_path: PathBuf,
|
||||
overlay_support: bool,
|
||||
) -> std::io::Result<()> {
|
||||
let dbscheme_file = File::create(dbscheme_path).map_err(|e| {
|
||||
tracing::error!("Failed to create dbscheme file: {}", e);
|
||||
@@ -33,16 +32,6 @@ pub fn generate(
|
||||
|
||||
writeln!(dbscheme_writer, include_str!("prefix.dbscheme"))?;
|
||||
|
||||
// Eventually all languages will have the metadata relation (for overlay support), at which
|
||||
// point this could be moved to prefix.dbscheme.
|
||||
if overlay_support {
|
||||
writeln!(dbscheme_writer, "/*- Database metadata -*/",)?;
|
||||
dbscheme::write(
|
||||
&mut dbscheme_writer,
|
||||
&[dbscheme::Entry::Table(create_database_metadata())],
|
||||
)?;
|
||||
}
|
||||
|
||||
let mut ql_writer = LineWriter::new(File::create(ql_library_path)?);
|
||||
writeln!(
|
||||
ql_writer,
|
||||
@@ -60,14 +49,12 @@ pub fn generate(
|
||||
})],
|
||||
)?;
|
||||
|
||||
if overlay_support {
|
||||
ql::write(
|
||||
&mut ql_writer,
|
||||
&[ql::TopLevel::Predicate(
|
||||
ql_gen::create_is_overlay_predicate(),
|
||||
)],
|
||||
)?;
|
||||
}
|
||||
ql::write(
|
||||
&mut ql_writer,
|
||||
&[ql::TopLevel::Predicate(
|
||||
ql_gen::create_is_overlay_predicate(),
|
||||
)],
|
||||
)?;
|
||||
|
||||
for language in languages {
|
||||
let prefix = node_types::to_snake_case(&language.name);
|
||||
@@ -113,20 +100,19 @@ pub fn generate(
|
||||
ql::TopLevel::Class(ql_gen::create_reserved_word_class(&reserved_word_name)),
|
||||
];
|
||||
|
||||
if overlay_support {
|
||||
body.push(ql::TopLevel::Predicate(
|
||||
ql_gen::create_get_node_file_predicate(&ast_node_name, &node_location_table_name),
|
||||
));
|
||||
body.push(ql::TopLevel::Predicate(
|
||||
ql_gen::create_discard_file_predicate(),
|
||||
));
|
||||
body.push(ql::TopLevel::Predicate(
|
||||
ql_gen::create_discardable_ast_node_predicate(&ast_node_name),
|
||||
));
|
||||
body.push(ql::TopLevel::Predicate(
|
||||
ql_gen::create_discard_ast_node_predicate(&ast_node_name),
|
||||
));
|
||||
}
|
||||
// Overlay discard predicates
|
||||
body.push(ql::TopLevel::Predicate(
|
||||
ql_gen::create_get_node_file_predicate(&ast_node_name, &node_location_table_name),
|
||||
));
|
||||
body.push(ql::TopLevel::Predicate(
|
||||
ql_gen::create_discard_file_predicate(),
|
||||
));
|
||||
body.push(ql::TopLevel::Predicate(
|
||||
ql_gen::create_discardable_ast_node_predicate(&ast_node_name),
|
||||
));
|
||||
body.push(ql::TopLevel::Predicate(
|
||||
ql_gen::create_discard_ast_node_predicate(&ast_node_name),
|
||||
));
|
||||
|
||||
body.append(&mut ql_gen::convert_nodes(&nodes));
|
||||
ql::write(
|
||||
@@ -478,26 +464,3 @@ fn create_token_case<'a>(name: &'a str, token_kinds: Map<&'a str, usize>) -> dbs
|
||||
branches,
|
||||
}
|
||||
}
|
||||
|
||||
fn create_database_metadata() -> dbscheme::Table<'static> {
|
||||
dbscheme::Table {
|
||||
name: "databaseMetadata",
|
||||
keysets: None,
|
||||
columns: vec![
|
||||
dbscheme::Column {
|
||||
db_type: dbscheme::DbColumnType::String,
|
||||
name: "metadataKey",
|
||||
unique: false,
|
||||
ql_type: ql::Type::String,
|
||||
ql_type_is_ref: true,
|
||||
},
|
||||
dbscheme::Column {
|
||||
db_type: dbscheme::DbColumnType::String,
|
||||
name: "value",
|
||||
unique: false,
|
||||
ql_type: ql::Type::String,
|
||||
ql_type_is_ref: true,
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,3 +104,9 @@ yaml_locations(unique int locatable: @yaml_locatable ref,
|
||||
int location: @location_default ref);
|
||||
|
||||
@yaml_locatable = @yaml_node | @yaml_error;
|
||||
|
||||
/*- Database metadata -*/
|
||||
databaseMetadata(
|
||||
string metadataKey: string ref,
|
||||
string value: string ref
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user