Grundlegende Syntax von CodeQL-Notizen (2)


Vorwort

      Erfahren Sie, wie Sie CodeQL für die Codeprüfung verwenden. Die Grundgrammatik umfasst Konzepte und Beispiele. Dieser Artikel ist Teil von Abfragen und Klassen.


1. Anfrage

     Die Abfrage ist die Ergebnisausgabe, nachdem die gesamte QL-Sprache ausgeführt wurde. Es gibt zwei Abfragetypen:

  • Die erste besteht darin, dass die Select-Query-Klausel im Modul definiert ist
  • Abfrageprädikate, was bedeutet, dass wir sie im aktuellen Modul definieren oder aus anderen Modulen importieren können

1. Abfrageklausel auswählen

     1) Das Format der Select-Klausel ist wie folgt (normalerweise am Ende der Datei), wobei die Anweisungsteile from und where optional sind. Wir können Variablen in from definieren, Variablen Werte zuweisen und Abfrageergebnisse in where filtern und schließlich die Ergebnisse in select anzeigen.

from /* ... variable declarations ... */
where /* ... logical formula ... */
select /* ... expressions ... */

     2) Einige Schlüsselwörter können auch in der Select-Anweisung verwendet werden:

  • als Schlüsselwort, gefolgt von einem Namen. Die Funktion ähnelt der in SQL. Sie stellt eine „Beschriftung“ für die Ergebnisspalte bereit und ermöglicht deren Verwendung in nachfolgenden Auswahlausdrücken.
  • Auf die Reihenfolge nach Schlüsselwörtern folgen nacheinander die Namen der Ergebnisspalten. Die Funktion entspricht order by in SQL, das zum Sortieren der Ergebnisse verwendet wird, und das Schlüsselwort asc (aufsteigende Reihenfolge) oder desc (absteigende Reihenfolge) kann nach dem Namen der Ergebnisspalte optional stehen.

     3) Das offizielle Beispiel lautet wie folgt: Die ersten Bildergebnisse geben die Ergebnisse der Select-Klausel-Abfrage zurück, und das zweite Bild fügt eine Sortierung hinzu

from int x, int y
where x = 3 and y in [0 .. 2]
select x, y, x * y as product, "product: " + product

Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein

2. Abfrageprädikat

     1) Das Abfrageprädikat ist kein Mitgliedsprädikat und die Abfrage wird am Anfang als Anmerkung verwendet. Es gibt alle Tupel der Prädikatauswertungsergebnisse zurück. Hier ist ein offizielles Beispiel:

query int getProduct(int x, int y) {
    
    
  x = 3 and
  y in [0 .. 2] and
  result = x * y
}

Fügen Sie hier eine Bildbeschreibung ein
     2) Der Vorteil des Schreibens von Abfrageprädikaten gegenüber dem Schreiben von Auswahlklauseln besteht darin, dass Sie die Prädikate in anderen Teilen des Codes aufrufen können. Beispielsweise können wir getProduct in der Klasse aufrufen:

query int getProduct(int x, int y) {
    
    
  x = 3 and
  y in [0 .. 2] and
  result = x * y
}
class MultipleOfThree extends int {
    
    
  MultipleOfThree() {
    
     this = getProduct(_, _) }
}

from MultipleOfThree m  
select m

     3) Auf diese Weise haben unsere Abfrageergebnisse zwei, eines ist das integrierte #select und das andere ist getProduct
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
     4) Im Gegensatz zu den beiden ist die select-Klausel wie ein anonymes Prädikat und kann später nicht aufgerufen werden . Das Hinzufügen von Abfragekommentaren zu Prädikaten ist auch beim Debuggen Ihres Codes hilfreich. Auf diese Weise können Sie explizit die Menge der Tupel sehen, zu der das Prädikat ausgewertet wird.

2. Geben Sie ein

1. Übersicht

     QL ist eine statisch typisierte Sprache, daher muss jede Variable einen deklarierten Typ haben. In QL ist ein Typ eine Menge von Werten. Der Typ int ist beispielsweise eine Menge von Ganzzahlen. Werte können zu mehreren Sammlungen gehören, was bedeutet, dass ein Wert mehrere Typen haben kann. Zu den Typen in QL gehören primitive Typen, Klassen, Zeichentypen, feldartige Typen, algebraische Datentypen, Typvereinigungen und Datenbanktypen.

2. Primitiver Typ

     Diese Typen sind in QL integriert und immer im globalen Namespace verfügbar, unabhängig von der Datenbank, die wir abfragen.

  • boolean: Dieser Typ enthält die Werte true und false.
  • float: Dieser Typ enthält 64-Bit-Gleitkommazahlen, z. B. 6,28 und -0,618.
  • int: Dieser Typ enthält 32-Bit-Zweierkomplement-Ganzzahlen wie -1 und 42.
  • string: Dieser Typ enthält eine begrenzte Zeichenfolge von 16 Zeichen.
  • Datum: Dieser Typ enthält ein Datum (und optional eine Uhrzeit).

3. Klassen

     1) Wir können unsere eigenen Typen in CodeQL definieren und eine Methode definiert eine Klasse.
     2) Klassen bieten eine einfache Möglichkeit, Code wiederzuverwenden und zu strukturieren. Sie können beispielsweise verwandte Werte gruppieren, Elementprädikate für diese Werte definieren und Unterklassen definieren, um Elementprädikate zu überschreiben.
     3) Eine Klasse in QL „erstellt“ kein neues Objekt, sondern repräsentiert lediglich eine logische Eigenschaft. Ein Wert gehört zu einer bestimmten Klasse, wenn er diese logische Eigenschaft erfüllt.
     4) Definieren Sie eine Klasse, die die folgenden Parameter erfordert:

  • Klassenschlüsselwort
  • Der Name der Klasse. Dies ist eine Kennung, die mit einem Großbuchstaben beginnt
  • Der Supertyp einer Klasse, die über „extends“ und / oder „instanceof“ von Klassen abgeleitet wird
  • Der Hauptteil der Klasse, eingeschlossen in geschweifte Klammern

     5) Offizieller Fall:

class OneTwoThree extends int {
    
    
  OneTwoThree() {
    
     // characteristic predicate
    this = 1 or this = 2 or this = 3
  }

  string getAString() {
    
     // member predicate
    result = "One, two or three: " + this.toString()
  }

  predicate isEven() {
    
     // member predicate
    this = 2
  }
}

     6) In CodeQL erlauben Klassen Mehrfachvererbung, aber die folgenden Operationen sind illegal:

  • kann sich nicht selbst erben
  • Die letzte Klasse kann nicht geerbt werden
  • Inkompatible Typen können nicht vererbt werden. Weitere Informationen finden Sie unter: https://codeql.github.com/docs/ql-lingual-reference/annotations/#annotations-overview

4. Der Hauptteil der Klasse

     1) Der Hauptteil einer Klasse kann Folgendes enthalten:

  • Deklaration charakteristischer Prädikate
  • Beliebig viele Mitgliedsprädikatdeklarationen
  • Beliebig viele Felddeklarationen

     2) In einer Klasse können wir damit auf die Klasse selbst verweisen. Wenn wir eine Klasse definieren, erbt die Klasse auch alle nicht privaten Mitgliedsprädikate und -felder von ihrer übergeordneten Klasse, die wir überschreiben können.

5. Merkmalsprädikat

     Ähnlich wie der Konstruktor einer Klasse in anderen Sprachen, der nur einen definieren kann, können wir diesen im Merkmalsprädikat verwenden, um die möglichen Werte in der Klasse einzuschränken. Im obigen Beispiel ist OneTwoThree auf Ganzzahlen von 1-3 beschränkt.

6.Mitgliedsprädikat

     Diese Prädikate gelten nur für Mitglieder einer bestimmten Klasse. Wir können Elementprädikate für Werte nennen.

	(OneTwoThree).getAString()
	// 结果是 One, two or three: 1

7.Feld

     Felder sind Variablen, die im Hauptteil einer Klasse deklariert werden, und es kann eine beliebige Anzahl von Felddeklarationen im Subjekt einer Klasse geben. Wir können diese Variablen auf Prädikate in der Klasse anwenden. Die Verwendung ist ähnlich: Die Felder müssen auf das charakteristische Prädikat beschränkt sein. Offizieller Fall:

class SmallInt extends int {
    
    
  SmallInt() {
    
     this = [1 .. 10] }
}

class DivisibleInt extends SmallInt {
    
    
  SmallInt divisor;   // declaration of the field `divisor`
  DivisibleInt() {
    
     this % divisor = 0 }

  SmallInt getADivisor() {
    
     result = divisor }
}

from DivisibleInt i
select i, i.getADivisor()

     In diesem Fall wird der SmallInt-Divisor deklariert und ein Divisorfeld definiert, im charakteristischen Prädikat eingeschränkt und dann in der Deklaration des Mitgliedsprädikats getADivisor verwendet.
Fügen Sie hier eine Bildbeschreibung ein

8. Konkreter Unterricht

     Bei den obigen Beispielen handelt es sich allesamt um konkrete Klassen, die durch die Einschränkung der Werte in einem größeren Typ definiert werden. Die Werte in einer konkreten Klasse sind auch diejenigen Werte im Schnittpunkt von Supertypen, die auch die charakteristischen Prädikate der Klasse erfüllen.

9.Abstrakte Klasse

     Abstrakte Klassen werden mit dem Schlüsselwort abstract vor dem Schlüsselwort class definiert. Ich glaube, wir sind mit abstrakten Konzepten in vielen anderen Sprachen (wie Java) in Kontakt gekommen. Eine abstrakte Klasse kann auch als Metaklasse bezeichnet werden, die die Prädikate und Felder ihrer Unterklassen definiert. Das Format ist wie folgt:

abstract class SqlExpr extends Expr {
    
    
  ...
}

Ich denke du magst

Origin blog.csdn.net/qq_44029310/article/details/127598097
Empfohlen
Rangfolge