# Query Grammar

## <mark style="color:blue;">Data Types</mark>

The following are the supported basic data types by the DVR Query language:

* <mark style="color:orange;">**Integer**</mark>\
  A signed 64-bit integer data type. Example: 10, -12
* <mark style="color:orange;">**String**</mark>\
  A sequence of characters. Example: "Hello, world!"
* <mark style="color:orange;">**Boolean**</mark>\
  A binary value that can be either true or false

## <mark style="color:blue;">Operators</mark>

The list of supported operators:

* Boolean Operators:
  * <mark style="color:orange;">**or**</mark>
  * <mark style="color:orange;">**and**</mark>
* Relational Operators: <mark style="color:orange;">**>, >=, <, <=**</mark>
  * Applies to integer
* Equality Operators
  * Equality operator: <mark style="color:orange;">**==**</mark>\
    Applies to boolean, integer, and string.\
    In the case of a string, this is a case-sensitive comparison.
  * Inequality operator: <mark style="color:orange;">**!=**</mark>\
    Applies to boolean, integer, string
  * String-specific Relational Operations
    * <mark style="color:orange;">**\~!=**</mark>\
      Case-insensitive inequality operation on a string
    * <mark style="color:orange;">**\~==**</mark>\
      Case-insensitive equality operation on string

## <mark style="color:blue;">Variable and Literals</mark>

The zkPass Query language also defines the following concepts:

* <mark style="color:orange;">**Variable**</mark>\
  The variable corresponds to the key name of the key/value json element in the query data. To reference nested elements in the json data, delimiter “.” is used as the path separator.\
  The variable must appear on the left-hand side of a relational expression.
* <mark style="color:orange;">**Literal (Constant)**</mark>\
  The constant value is compared to the variable's value.\
  The literal must appear on the right-hand side of a relational expression. The data type of the literal must match that of the variable.

## <mark style="color:blue;">Grammar BNF</mark>

```bnf
<query> ::= <boolean-expression>

<boolean-expression> ::= "{" <logical-operator> ": [" <expression-list> "] "}"

<logical-operator> ::= "and" | "or"

<expression-list> ::= <expression> | <expression> "," <expression-list>
<expression> ::= <relational-expression> | <boolean-expression>

<relational-expression> ::= "{" <relational-operator> ": [" <variable> "," <literal> "] "}"

<relational-operator> ::= "==" | "!=" | ">" | ">=" | "<" | "<=" | "~==" | "~!="

<variable> ::= <string>

<literal> ::= <integer> | <string> | <boolean>

<integer> ::= ["-"] <digit>+

<string> ::= """ <characters> """

<boolean> ::= "true" | "false"

<characters> ::= <character>*
<character> ::= <letter> | <digit> | <special-character> | " "

<special-character> ::= "!" | "@" | "#" | "$" | "%" | "^" | "&" | "*" | "(" | ")" | "-" | "+" | "=" | "[" | "]" | "{" | "}" | "|" | ":" | ";" | "'" | "<" | ">" | "," | "." | "/" | "?" | "~"

<letter> ::= "a" ... "z" | "A" ... "Z"
<digit> ::= "0" ... "9"

```

## <mark style="color:blue;">Query Example</mark>

```json
[
  {
    assign: {
      account_holder: {
        and: [
          { "==": [{ dvar: "bcaDocID" }, "DOC897923CP"] },
          { "~==": [{ dvar: "personalInfo.firstName" }, "Ramana"] },
          { "~==": [{ dvar: "personalInfo.lastName" }, "Maharshi"] },
          {
            "~==": [{ dvar: "personalInfo.driverLicenseNumber" }, "DL77108108"],
          },
          {
            ">=": [{ dvar: "financialInfo.creditRatings.pefindo" }, 650],
          },
          {
            ">=": [
              { dvar: "financialInfo.accounts.savings.balance" },
              55000000,
            ],
          },
        ],
      },
    },
  },
  { output: { result: { lvar: "account_holder" } } },
]
```
