|
| 1 | +--- |
| 2 | +title: Overview |
| 3 | +id: overview |
| 4 | +--- |
| 5 | + |
| 6 | +In this document we explore some of the meta parts of BlueQL. If you want to look at how you can use BlueQL, consider looking at the sections that follow. |
| 7 | + |
| 8 | +Design principles: |
| 9 | +- **Simplicity and clarity**: The language shouldn't be overwhelming to understand |
| 10 | +- **Security with mandatory parameterization**: We want to reduce the surface of injection attacks. For this reason, [parameterization is mandatory](#parameters). |
| 11 | + |
| 12 | +Just like SQL, BlueQL has three categories of commands/queries inside it: |
| 13 | + |
| 14 | +- **DDL**: Data definition language is used to define, modify and/or remove DDL objects such as `space`s and `model`s |
| 15 | +- **DCL**: Data control language is used to control the access to data, and perform other administrative tasks |
| 16 | +- **DML**: Data manipulation language is used to manipulate data |
| 17 | + |
| 18 | +Jump to [differences from SQL](#differences-from-sql). |
| 19 | + |
| 20 | +:::info |
| 21 | +This text is *not* a detailed, formal guide. It's meant for developers and users who want to work with |
| 22 | +Skytable. If you need a more formal specification, like a grammar definition, please ask us, and we'll create |
| 23 | +it. We haven't published it yet because no one has requested it. |
| 24 | +::: |
| 25 | + |
| 26 | +## Identifiers |
| 27 | +Can begin with any ASCII alphabet or an underscore (`_`) and then have any number of alphanumeric characters and/or underscores. |
| 28 | + |
| 29 | +## Keywords |
| 30 | + |
| 31 | +Keywords are identifiers with special meanings and hence can't be used as identifiers in other places. Here's a full-list of |
| 32 | +keywords: |
| 33 | + |
| 34 | +```ts |
| 35 | +[ |
| 36 | + "sysctl", "create", "alter", "drop", "use", "inspect", "describe", "insert", "select", "update", |
| 37 | + "delete", "exists", "table", "model", "space", "index", "type", "function", "rename", "add", |
| 38 | + "remove", "transform", "set", "return", "order", "sort", "group", "limit", "asc", "desc", "all", |
| 39 | + "by", "with", "on", "from", "into", "as", "to", "in", "of", "and", "or", "not", "if", "else", |
| 40 | + "where", "when", "allow", "auto", "default", "null", "transaction", "batch", "lock", "read", |
| 41 | + "write", "begin", "end", "key", "value", "primary", "truncate" |
| 42 | +] |
| 43 | +``` |
| 44 | + |
| 45 | +## Data types |
| 46 | + |
| 47 | +### Boolean |
| 48 | +A boolean value, either `true` or `false` |
| 49 | + |
| 50 | +### Unsigned integers |
| 51 | + |
| 52 | +- `uint8`: unsigned 8-bit integer |
| 53 | +- `uint16`: unsigned 16-bit integer |
| 54 | +- `uint32`: unsigned 32-bit integer |
| 55 | +- `uint64`: unsigned 64-bit integer |
| 56 | + |
| 57 | +### Signed integers |
| 58 | + |
| 59 | +- `sint8`: signed 8-bit integer |
| 60 | +- `sint16`: signed 16-bit integer |
| 61 | +- `sint32`: signed 32-bit integer |
| 62 | +- `sint64`: signed 64-bit integer |
| 63 | + |
| 64 | +### Floating point values |
| 65 | + |
| 66 | +- `float32`: a single-precision float |
| 67 | +- `float64`: a double-precision float |
| 68 | + |
| 69 | +### Simple collections |
| 70 | + |
| 71 | +- `binary`: a binary blob represented as a sequence of `uint8` values |
| 72 | +- `string`: an UTF-8 string |
| 73 | + |
| 74 | +### Complex collections |
| 75 | + |
| 76 | +- `list`: a list of any of the data types, including nested lists |
| 77 | + - A list is represented as: `[]` with values inbetween. For example, a `list { type:string }` would be represented as: |
| 78 | + ```sql |
| 79 | + ["sayan", "loves", "dogs"] |
| 80 | + ``` |
| 81 | + - **Lists cannot contain null values** |
| 82 | + - **List can be nested**: You can have heavily nested lists like: `[[[]], [["another one"]]]` |
| 83 | + - **List can only have one base type**: This means that if you have a list like `[[[string]]]` each element must either be the same nested list, or an empty list |
| 84 | + |
| 85 | +:::info Note |
| 86 | +New data types are frequently added, so treat this list as non-exhaustive. |
| 87 | +::: |
| 88 | + |
| 89 | +## Literals |
| 90 | + |
| 91 | +- Null literal: `null` |
| 92 | +- Numeric literals: |
| 93 | + - Unsigned: `1234` |
| 94 | + - Signed: `[-]1234` |
| 95 | +- Floating point literals: `[-]1234.5678` |
| 96 | +- String literals: `"hello"` |
| 97 | +- Binary literals: \`binary\` |
| 98 | +- List literals: `[..]` |
| 99 | +- Dictionaries: `{<ident>: <literal>}` |
| 100 | +
|
| 101 | +:::warning Literals are not available everywhere |
| 102 | +It is very important for you to know that literals are not allowed everywhere. The only literals allowed everywhere are: |
| 103 | +- Lists |
| 104 | +- Dictionaries |
| 105 | +
|
| 106 | +Read below to understand why. |
| 107 | +::: |
| 108 | +
|
| 109 | +## Parameters |
| 110 | +
|
| 111 | +All literals apart from dictionaries and lists must be used as parameters. **BlueQL only allows literals as parameters**. For example, using the Rust client, if you were to run this: |
| 112 | +
|
| 113 | +```sql |
| 114 | +insert into myspace.mymodel('sayan', 'pass123', ['myfirstnote']) |
| 115 | +``` |
| 116 | + |
| 117 | +You are required to parameterize the query like this: |
| 118 | + |
| 119 | +```rust |
| 120 | +use skytable::query; |
| 121 | + |
| 122 | +let query = query!("insert into myspace.mymode(?, ?, [?])", "sayan", "pass123", "myfirstnote") |
| 123 | +``` |
| 124 | + |
| 125 | +If you try to run it without any parameters (don't forget that `skysh` automatically parameterizes for convenience) the query |
| 126 | +won't even compile. |
| 127 | + |
| 128 | +:::tip |
| 129 | +Just so you know, parameterizing involves passing a separate parameter list, with each parameter encoded. You wouldn't need to worry about this because the client driver does all of that for you! |
| 130 | + |
| 131 | +**The question is why? The answer is security.** SQL-injection vulernabilties have already costed companies a lot, so we don't |
| 132 | +want to inherit that from SQL. |
| 133 | + |
| 134 | +**Also, parameterization is exclusively possible for literals**. This means that whenever you're accepting data from an untrusted |
| 135 | +source, it becomes a parameter. If you try to not use parameters, the query will not even compile. |
| 136 | + |
| 137 | +On a final note, BlueQL doesn't support comments of any form also for security reasons. |
| 138 | +::: |
| 139 | + |
| 140 | +## Expressions |
| 141 | + |
| 142 | +- `+=`: add RHS to LHS |
| 143 | + - Can be used outside arithmetic contexts |
| 144 | + - Add a char to a field `mystring`: `mystring += ",world"` |
| 145 | + - Add a list to a nested list field: `mylist += ["item in nested list"]` |
| 146 | +- `-=`: subtract RHS from LHS |
| 147 | +- `/=`: divide LHS by RHS |
| 148 | +- `*=`: multiply LHS by RHS |
| 149 | + |
| 150 | +## DDL |
| 151 | + |
| 152 | +Queries include: |
| 153 | +- Spaces: |
| 154 | + - `CREATE SPACE myspace [WITH { property: value, ... }]` |
| 155 | + - `ALTER SPACE myspace [WITH { property: updated_value, ... }]` |
| 156 | + - `DROP SPACE [allow not empty] myspace` |
| 157 | +- Models: |
| 158 | + - `CREATE MODEL myspace.mymodel([primary] [null] field: field_type, ...) [WITH { property: value, ... }]` |
| 159 | + - `ALTER MODEL myspace.mymodel (ADD ... | UPDATE ... | REMOVE ...)` |
| 160 | + - `DROP MODEL [allow not empty] myspace.mymodel` |
| 161 | +- `INSPECT GLOBAL`: inspects global state, shows a list of spaces and users |
| 162 | +- `INSPECT SPACE <space>`: inspects a single space, shows a list of models and other things |
| 163 | +- `INSPECT MODEL <model>`: inspects a single model, shows information about stored data and other things |
| 164 | + |
| 165 | +## DML |
| 166 | + |
| 167 | +- `INSERT INTO myspace.mymodel(...)` |
| 168 | +- `SELECT col1, ... FROM myspace.mymodel WHERE ...` |
| 169 | +- `UPDATE myspace.mymodel SET counter += 1 WHERE ...` |
| 170 | +- `DELETE FROM myspace.mymode WHERE ...` |
| 171 | + |
| 172 | +## DCL |
| 173 | + |
| 174 | +Queries include: |
| 175 | +- `SYSCTL REPORT STATUS`: returns the status of the system. (Not a control query per se) |
| 176 | +- `SYSCTL CREATE USER "username" WITH { password: ... }`: create a new user |
| 177 | +- `SYSCTL DROP USER "username"`: removes the user in question |
| 178 | + |
| 179 | +## Differences from SQL |
| 180 | + |
| 181 | +- No literals (see above) |
| 182 | +- Mandatory parameterization (see above) |
| 183 | +- No semicolons! |
| 184 | +- Only one statement per query. For multiple statements batches must be used |
| 185 | +- DML queries are point queries (hence must contain a `WHERE` clause) |
0 commit comments