@@ -48,17 +48,14 @@ def __init__(self, dao, web_svc, dir_prefix=""):
4848 # Use the substring method to save in the parent_tid column as the Txxx part of the tid (without the .xx)
4949 "WITH parent_tids(uid, name, tid, inactive, parent_tid) AS "
5050 f"(SELECT uid, name, tid, inactive, SUBSTR(tid, 0, { str_pos } (tid, '.')) "
51-
5251 # %% in LIKE because % messes up parameters in psycopg (https://github.com/psycopg/psycopg2/issues/827)
5352 # LIKE '%.%' = '%%.%%' so this does not affect other DB engines
5453 "FROM attack_uids WHERE tid LIKE '%%.%%'{inactive_AND}) "
55-
5654 # With parent_tids, select all fields from it and the name of the parent_tid from the attack_uids table
5755 # Need to use `AS parent_name` to not confuse it with parent_tids.name
5856 # Using an INNER JOIN because we only care about returning sub-techniques here
5957 "SELECT parent_tids.*, attack_uids.name AS parent_name FROM "
6058 "(attack_uids INNER JOIN parent_tids ON attack_uids.tid = parent_tids.parent_tid){inactive_WHERE} "
61-
6259 # Union the sub-tech query with one for all other techniques (where the tid does not contain a '.')
6360 # Need to pass in two NULLs so the number of columns for the UNION is the same
6461 # (and parent_name & parent_tid doesn't exist for these techniques which are not sub-techniques)
@@ -512,26 +509,19 @@ async def get_report_sentences_with_attacks(self, report_id="", group_by_attack=
512509 "EXISTS(SELECT 1 FROM false_negatives fn WHERE fn.sentence_id = report_sentences.uid "
513510 " AND fn.attack_uid = report_sentence_hits.attack_uid) as false_negative, "
514511 "report_sentence_hits.initial_model_match, "
515-
516512 # We want to add any sub-technique's parent-technique name
517513 "report_sentence_hits.active_hit, " + FULL_ATTACK_INFO + ".parent_name AS attack_parent_name, "
518-
519514 # LEFT (not INNER) JOINS with FULL_ATTACK_INFO may have 'inactive' data; return 'inactive' from attack_uids
520515 "attack_uids.inactive AS inactive_attack, " + start_date + ", " + end_date + " "
521-
522516 # The first join for the report data; LEFT OUTER JOIN because we want all report sentences
523517 "FROM (((report_sentences LEFT OUTER JOIN report_sentence_hits "
524518 "ON report_sentences.uid = report_sentence_hits.sentence_id) "
525-
526519 # A second join for the full attack table; still using a LEFT JOIN
527520 "LEFT JOIN " + FULL_ATTACK_INFO + " ON " + FULL_ATTACK_INFO + ".uid = report_sentence_hits.attack_uid) "
528-
529521 # FULL_ATTACK_INFO omits 'inactive' flag; join so we have this info
530522 "LEFT JOIN attack_uids ON report_sentence_hits.attack_uid = attack_uids.uid) "
531-
532523 # Finish with the WHERE clause stating which report this is for
533524 f"WHERE report_sentences.report_uid = { self .dao .db_qparam } "
534-
535525 # Need to order by for JOIN query (otherwise sentences can be out of order if attacks are updated)
536526 "ORDER BY report_sentences.sen_index"
537527 )
@@ -579,14 +569,11 @@ async def get_confirmed_attacks_for_sentence(self, sentence_id=""):
579569 select_join_query = (
580570 # Select all columns from the full attack info table
581571 f"{ self .SQL_WITH_PAR_ATTACK_INC_INACTIVE } SELECT { FULL_ATTACK_INFO } .*, "
582-
583572 # Include row ID for use when updating dates of attack
584573 f"report_sentence_hits.uid AS mapping_id, { start_date } , { end_date } "
585-
586574 # Use an INNER JOIN on full_attack_info and report_sentence_hits (to get the intersection of attacks)
587575 f"FROM ({ FULL_ATTACK_INFO } INNER JOIN report_sentence_hits ON "
588576 f"{ FULL_ATTACK_INFO } .uid = report_sentence_hits.attack_uid) "
589-
590577 # Finish with the WHERE clause stating which sentence we are searching for and that the attack is confirmed
591578 f"WHERE report_sentence_hits.sentence_id = { self .dao .db_qparam } "
592579 f"AND report_sentence_hits.confirmed = { self .dao .db_true_val } "
0 commit comments