Skip to content

Commit

Permalink
Merge pull request #17556 from d10c/d10c/bigint-docs
Browse files Browse the repository at this point in the history
BigInt Documentation
  • Loading branch information
jbj authored Oct 8, 2024
2 parents 3d6965a + 328f322 commit 51d189d
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 107 deletions.
6 changes: 3 additions & 3 deletions docs/codeql/codeql-language-guides/extensible-predicates.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,16 @@ This example of an extensible predicate for a source is taken from the core Java
.. code-block:: ql
extensible predicate sourceModel(
string package, string type, boolean subtypes, string name,
string signature, string ext, string output, string kind,
string package, string type, boolean subtypes, string name,
string signature, string ext, string output, string kind,
string provenance
);
An extensible predicate is a CodeQL predicate with the following restrictions:

- It uses the ``extensible`` keyword.
- It has no body.
- All predicate parameters have primitive types.
- All predicate parameters have type ``string``, ``int``, ``float``, ``boolean``, or ``date``.
- It is not in a module.

Columns shared by all extensible predicates
Expand Down
85 changes: 56 additions & 29 deletions docs/codeql/ql-language-reference/modules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

Modules
#######

Modules provide a way of organizing QL code by grouping together related types, predicates, and other modules.

You can import modules into other files, which avoids duplication, and helps
Modules provide a way of organizing QL code by grouping together related types, predicates, and other modules.

You can import modules into other files, which avoids duplication, and helps
structure your code into more manageable pieces.

.. _defining-module:
Expand All @@ -16,7 +16,7 @@ Defining a module
*****************

There are various ways to define modules—here is an example of the simplest way, declaring an
:ref:`explicit module <explicit-modules>` named ``Example`` containing
:ref:`explicit module <explicit-modules>` named ``Example`` containing
a class ``OneTwoThree``:

.. code-block:: ql
Expand All @@ -27,17 +27,17 @@ a class ``OneTwoThree``:
this = 1 or this = 2 or this = 3
}
}
}
}
The name of a module can be any `identifier <https://codeql.github.com/docs/ql-language-reference/ql-language-specification/#identifiers>`_
that starts with an uppercase or lowercase letter.
that starts with an uppercase or lowercase letter.

``.ql`` or ``.qll`` files also implicitly define modules.
For more information, see ":ref:`kinds-of-modules`."

You can also annotate a module. For more information, see of ":ref:`annotations-overview`."

Note that you can only annotate :ref:`explicit modules <explicit-modules>`.
Note that you can only annotate :ref:`explicit modules <explicit-modules>`.
File modules cannot be annotated.

.. _kinds-of-modules:
Expand All @@ -48,7 +48,7 @@ Kinds of modules
File modules
============

Each query file (extension ``.ql``) and library file (extension ``.qll``) implicitly defines
Each query file (extension ``.ql``) and library file (extension ``.qll``) implicitly defines
a module. The module has the same name as the file, but any spaces in the file name are replaced
by underscores (``_``). The contents of the file form the :ref:`body of the module <module-bodies>`.

Expand All @@ -57,7 +57,7 @@ by underscores (``_``). The contents of the file form the :ref:`body of the modu
Library modules
---------------

A library module is defined by a ``.qll`` file. It can contain any of the
A library module is defined by a ``.qll`` file. It can contain any of the
elements listed in :ref:`module-bodies` below, apart from select clauses.

For example, consider the following QL library:
Expand All @@ -75,19 +75,19 @@ For example, consider the following QL library:
This file defines a library module named ``OneTwoThreeLib``. The body of this module
defines the class ``OneTwoThree``.

.. _query-modules:
.. _query-modules:

Query modules
-------------

A query module is defined by a ``.ql`` file. It can contain any of the elements listed
in :ref:`module-bodies` below.
A query module is defined by a ``.ql`` file. It can contain any of the elements listed
in :ref:`module-bodies` below.

Query modules are slightly different from other modules:

- A query module can't be imported.
- A query module must have at least one query in its
:ref:`namespace <namespaces>`. This is usually a :ref:`select clause <select-clauses>`,
- A query module must have at least one query in its
:ref:`namespace <namespaces>`. This is usually a :ref:`select clause <select-clauses>`,
but can also be a :ref:`query predicate <query-predicates>`.

For example:
Expand All @@ -97,7 +97,7 @@ For example:
.. code-block:: ql
import OneTwoThreeLib
from OneTwoThree ott
where ott = 1 or ott = 2
select ott
Expand All @@ -110,13 +110,13 @@ This file defines a query module named ``OneTwoQuery``. The body of this module
Explicit modules
================

You can also define a module within another module. This is an explicit module definition.
You can also define a module within another module. This is an explicit module definition.

An explicit module is defined with the keyword ``module`` followed by
the module name, and then the module body enclosed in braces. It can contain any
of the elements listed in ":ref:`module-bodies`" below, apart from select clauses.
An explicit module is defined with the keyword ``module`` followed by
the module name, and then the module body enclosed in braces. It can contain any
of the elements listed in ":ref:`module-bodies`" below, apart from select clauses.

For example, you could add the following QL snippet to the library file **OneTwoThreeLib.qll**
For example, you could add the following QL snippet to the library file **OneTwoThreeLib.qll**
defined :ref:`above <library-modules>`:

.. code-block:: ql
Expand All @@ -129,7 +129,7 @@ defined :ref:`above <library-modules>`:
}
}
}
This defines an explicit module named ``M``. The body of this module defines
the class ``OneTwo``.

Expand Down Expand Up @@ -226,7 +226,7 @@ Module bodies
*************

The body of a module is the code inside the module definition, for example
the class ``OneTwo`` in the :ref:`explicit module <explicit-modules>` ``M``.
the class ``OneTwo`` in the :ref:`explicit module <explicit-modules>` ``M``.

In general, the body of a module can contain the following constructs:

Expand All @@ -243,11 +243,11 @@ In general, the body of a module can contain the following constructs:
Importing modules
*****************

The main benefit of storing code in a module is that you can reuse it in other modules.
To access the contents of an external module, you can import the module using an
The main benefit of storing code in a module is that you can reuse it in other modules.
To access the contents of an external module, you can import the module using an
:ref:`import statement <import-statements>`.

When you import a module this brings all the names in its namespace, apart from :ref:`private` names,
When you import a module this brings all the names in its namespace, apart from :ref:`private` names,
into the :ref:`namespace <namespaces>` of the current module.

.. _import-statements:
Expand All @@ -263,7 +263,7 @@ Import statements are used for importing modules. They are of the form:
import <module_expression2>
Import statements are usually listed at the beginning of the module. Each
import statement imports one module. You can import multiple modules by
import statement imports one module. You can import multiple modules by
including multiple import statements (one for each module you want to import).

An import statement can also be :ref:`annotated <annotations-overview>` with
Expand All @@ -272,14 +272,14 @@ An import statement can also be :ref:`annotated <annotations-overview>` with
only reachable through deprecated imports in a given context then usage of the
name in that context will generate deprecation warnings.

You can import a module under a different name using the ``as`` keyword,
You can import a module under a different name using the ``as`` keyword,
for example ``import javascript as js``.

The ``<module_expression>`` itself can be a module name, a selection, or a qualified
reference. For more information, see ":ref:`name-resolution`."

For information about how import statements are looked up, see "`Module resolution <https://codeql.github.com/docs/ql-language-reference/ql-language-specification/#module-resolution>`__"
in the QL language specification.
in the QL language specification.

Built-in modules
****************
Expand Down Expand Up @@ -353,7 +353,7 @@ Sets

The built-in ``InternSets`` module is parameterized by ``Key`` and ``Value`` types
and a ``Value getAValue(Key key)`` relation. The module groups the ``Value``
column by ``Key`` and creates a set for each group of values related by a key.
column by ``Key`` and creates a set for each group of values related by a key.

The ``InternSets`` module exports a functional ``Set getSet(Key key)`` relation
that relates keys with the set of value related to the given key by
Expand Down Expand Up @@ -424,3 +424,30 @@ The above query therefore evalutes to:
+----+----+
| 4 | 4 |
+----+----+

.. index:: BigInt
.. _bigint:

BigInt
======

The built-in ``QlBuiltins`` module provides an **experimental** type ``BigInt`` of arbitrary-precision integers.

This type is not available in the CodeQL CLI by default, but you can enable it by passing the ``--allow-experimental=bigint``
option to the CodeQL CLI. Consequently, BigInts are currently disallowed in query results and dbscheme columns.

Unlike ``int`` and ``float``, there is no automatic conversion between ``BigInt`` and other numeric types.
Instead, big integers can be constructed using the ``.toBigInt()`` methods of ``int`` and ``string``.

The other built-in operations are:

* comparisons between ``BigInt``\s: ``=``, ``!=``, ``<``, ``<=``, ``>``, ``>=``,
* conversions from ``BigInt``\s to strings or integers (if within range): ``.toString()``, ``.toInt()``,
* ``BigInt`` arithmetic: binary ``+``, ``-``, ``*``, ``/``, ``%``, unary ``-``,
* bitwise operations: ``.bitAnd(BigInt)``, ``.bitOr(BigInt)``,
``.bitXor(BigInt)``, ``.bitShiftLeft(int)``, ``.bitShiftRightSigned(int)``,
``.bitNot()``,
* aggregates: ``min``, ``max``, (``strict``)\ ``sum``, (``strict``)\ ``count``, ``avg``,
``rank``, ``unique``, ``any``.
* other: ``.pow(int)``, ``.abs()``, ``.gcd(BigInt)``, ``.minimum(BigInt)``,
``.maximum(BigInt)``.
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ Kinds of types

Types in QL are either *primitive* types, *database* types, *class* types, *character* types, *class domain* types, type *parameters*, or *instantiation-nested* types.

The primitive types are ``boolean``, ``date``, ``float``, ``int``, and ``string``.
The primitive types are ``boolean``, ``date``, ``float``, ``int``, ``string``, and ``QlBuiltins::BigInt``.

Database types are supplied as part of the database. Each database type has a *name*, which is an identifier starting with an at sign (``@``, U+0040) followed by lower-case letter. Database types have some number of *base types*, which are other database types. In a valid database, the base types relation is non-cyclic.

Expand Down Expand Up @@ -433,7 +433,7 @@ Values are the fundamental data that QL programs compute over. This section spec
Kinds of values
~~~~~~~~~~~~~~~

There are six kinds of values in QL: one kind for each of the five primitive types, and *entities*. Each value has a type.
There are seven kinds of values in QL: one kind for each of the six primitive types, and *entities*. Each value has a type.

A boolean value is of type ``boolean``, and may have one of two distinct values: ``true`` or ``false``.

Expand All @@ -445,6 +445,8 @@ An integer value is of type ``int``. Each value is a 32-bit two's complement int

A string is a finite sequence of 16-bit characters. The characters are interpreted as Unicode code points.

A :ref:`big integer <bigint>` value is of type ``QlBuiltins::BigInt``. Each value is a signed arbitrary-precision integer.

The database includes a number of opaque entity values. Each such value has a type that is one of the database types, and an identifying integer. An entity value is written as the name of its database type followed by its identifying integer in parentheses. For example, ``@tree(12)``, ``@person(16)``, and ``@location(38132)`` are entity values. The identifying integers are left opaque to programmers in this specification, so an implementation of QL is free to use some other set of countable labels to identify its entities.

Ordering
Expand All @@ -458,7 +460,7 @@ For dates, the ordering is chronological.

For floats, the ordering is as specified in IEEE 754 when one exists, except that NaN is considered equal to itself and is ordered after all other floats, and negative zero is considered to be strictly less than positive zero.

For integers, the ordering is as for two's complement integers.
For integers (and :ref:`big integers <bigint>`), the ordering is numerical.

For strings, the ordering is lexicographic.

Expand Down
Loading

0 comments on commit 51d189d

Please sign in to comment.