mirror of
https://github.com/jackfoxy/urQL.git
synced 2024-08-16 15:20:48 +03:00
docs
This commit is contained in:
parent
423ef331c2
commit
3a17beedb1
@ -60,8 +60,9 @@ Column, table, and other aliases provide an alternative to referencing the quali
|
||||
|
||||
All objects in the database *sys* and namespace *sys* are system-owned and read-only for all user commands. The namespace *sys* may not be specified in any user-defined database.
|
||||
|
||||
## Common structures throughout the reference
|
||||
The following are some common language structures used throughout the reference:
|
||||
## Common documenataion structures
|
||||
|
||||
The following are some common language structures used throughout the reference.
|
||||
|
||||
```
|
||||
<db-qualifier> ::= { <database>.<namespace>. | <database>.. | <namespace>. }
|
||||
@ -113,6 +114,63 @@ If not cached, `<view>` must be evaluated to resolve.
|
||||
|
||||
Similarly `*` as the output of `DELETE`, `INSERT`, `MERGE` creates a pass-thru virtual-table for consumption by the next step or ultimate product of a `<transform>`.
|
||||
|
||||
## Literals
|
||||
|
||||
urQL supports most of the aura types implemented in Urbit as literals for the INSERT and SELECT commands. The *loobean* Urbit literal types is supported by *different* literals in urQL than normally in Urbit. urQL supports some literal types in multiple ways. Dates, timespans, and ships can all be represented in INSERT without the leading **~**. Unsigned decimal can be represented without the dot thousands separator. In some cases the support between INSERT and SELECT is not the same.
|
||||
|
||||
Column types (auras) not supported for INSERT can only be inserted into tables through the API.
|
||||
|
||||
| Aura | Description | INSERT | SELECT |
|
||||
| :--- |:-------------------- |:------------------:|:------------------:|
|
||||
| @c | UTF-32 | ~-~45fed. | **not supported** |
|
||||
| @da | date | ~2020.12.25 | ~2020.12.25 |
|
||||
| | | ~2020.12.25..7.15.0 | ~2020.12.25..7.15.0 |
|
||||
| | | ~2020.12.25..7.15.0..1ef5 | ~2020.12.25..7.15.0..1ef5 |
|
||||
| | | 2020.12.25 | 2020.12.25 |
|
||||
| | | 2020.12.25..7.15.0 | 2020.12.25..7.15.0 |
|
||||
| | | 2020.12.25..7.15.0..1ef5 | 2020.12.25..7.15.0..1ef5
|
||||
| @dr | timespan | ~d71.h19.m26.s24..9d55 | ~d71.h19.m26.s24..9d55 |
|
||||
| | | ~d71.h19.m26.s24 | ~d71.h19.m26.s24 |
|
||||
| | | ~d71.h19.m26 | ~d71.h19.m26 |
|
||||
| | | ~d71.h19 | ~d71.h19 |
|
||||
| | | ~d71 | ~d71 |
|
||||
| | | d71.h19.m26.s24..9d55 | |
|
||||
| | | d71.h19.m26.s24 | |
|
||||
| | | d71.h19.m26 | |
|
||||
| | | d71.h19 | |
|
||||
| | | d71 | |
|
||||
| @f | loobean | y, n, Y, N | Y, N |
|
||||
| @if | IPv4 address | .195.198.143.90 | .195.198.143.90 |
|
||||
| @is | IPv6 address | .0.0.0.0.0.1c.c3c6.8f5a | .0.0.0.0.0.1c.c3c6.8f5a |
|
||||
| @p | ship name | ~sampel-palnet | ~sampel-palnet |
|
||||
| | | sampel-palnet | |
|
||||
| @q | phonemic base | **not supported** | **not supported** |
|
||||
| @rh | half float (16b) | **not supported** | **not supported** |
|
||||
| @rs | single float (32b) | .3.14, .-3.14 | .3.14, .-3.14 |
|
||||
| @rd | double float (64b) | .~3.14, .~-3.14 | .~3.14, .~-3.14 |
|
||||
| @rq | quad float (128b) | **not supported** | **not supported** |
|
||||
| @sb | signed binary | --0b10.0000 | --0b10.0000 |
|
||||
| | | -0b10.0000 | -0b10.0000 |
|
||||
| @sd | signed decimal | --20, -20 | --20, -20 |
|
||||
| @sv | signed base32 | --0v201.4gvml.245kc | --0v201.4gvml.245kc |
|
||||
| | | -0v201.4gvml.245kc | -0v201.4gvml.245kc |
|
||||
| @sw | signed base64 | --0w2.04AfS.G8xqc | --0w2.04AfS.G8xqc |
|
||||
| | | -0w2.04AfS.G8xqc | -0w2.04AfS.G8xqc |
|
||||
| @sx | signed hexadecimal | --0x2004.90fd | --0x2004.90fd |
|
||||
| | | -0x2004.90fd | -0x2004.90fd |
|
||||
| @t | UTF-8 text (cord) | 'cord', 'cord\\\\'s' <sup>1</sup> | 'cord', 'cord\\\\'s' <sup>1</sup> |
|
||||
| @ta | ASCII text (knot) | *support pending* | *support pending* |
|
||||
| @tas | ASCII text (term) | *support pending* | *support pending* |
|
||||
| @ub | unsigned binary | 10.1011 | 10.1011 |
|
||||
| @ud | unsigned decimal | 2.222 | 2.222 |
|
||||
| | | 2222 | 2222 |
|
||||
| @uv | unsigned base32 | **not supported** | **not supported** |
|
||||
| @uw | unsigned base64 | e2O.l4Xpm | **not supported** |
|
||||
| @ux | unsigned hexadecimal | 0x12.6401 | 0x12.6401 |
|
||||
|
||||
<sup>1</sup> Example of embedding single quote in @t literal.
|
||||
|
||||
|
||||
## Issues
|
||||
(very incomplete list)
|
||||
1. Stored procedures - To Be Designed (TBD)
|
||||
|
87
docs/02-ddl-database.md
Normal file
87
docs/02-ddl-database.md
Normal file
@ -0,0 +1,87 @@
|
||||
# CREATE DATABASE
|
||||
|
||||
Creates a new user-space database accessible to any agent running on the ship. There is no sandboxing implemented.
|
||||
|
||||
_To Do NOTE_: Additional features like owner-desk property and GRANT desk permissions are under development.
|
||||
```
|
||||
<create-database> ::=
|
||||
CREATE DATABASE <database>
|
||||
[ AS OF { NOW
|
||||
| <timestamp>
|
||||
| n { SECONDS | MINUTES | HOURS | DAYS | WEEKS | MONTHS | YEARS } AGO
|
||||
| <inline-scalar>
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Example
|
||||
```
|
||||
CREATE DATABASE my-database
|
||||
```
|
||||
|
||||
## API
|
||||
```
|
||||
+$ create-database $:([%create-database name=@tas as-of=(unit @da)])
|
||||
```
|
||||
|
||||
## Arguments
|
||||
|
||||
**`<database>`**
|
||||
The user-defined name for the new database. It must comply with the Hoon term naming standard.
|
||||
|
||||
**`AS OF`**
|
||||
Timestamp of database creation. Defaults to current time. Subsequent DDL and data actions must have timestamps equal to or greater than this timestamp.
|
||||
|
||||
## Remarks
|
||||
|
||||
This command mutates the state of the Obelisk agent.
|
||||
|
||||
`CREATE DATABASE` must be executed independently within a script. The script will fail if there are prior commands. Subsequent commands will be ignored.
|
||||
|
||||
## Produced Metadata
|
||||
|
||||
INSERT row into `sys.sys.databases`.
|
||||
|
||||
## Example
|
||||
|
||||
create-database %db1
|
||||
|
||||
## Exceptions
|
||||
|
||||
"duplicate key: {<key>}" database already exists
|
||||
|
||||
# DROP DATABASE
|
||||
Deletes an existing `<database>` and all associated objects.
|
||||
```
|
||||
<drop-database> ::= DROP DATABASE [ FORCE ] <database>
|
||||
```
|
||||
|
||||
## API
|
||||
```
|
||||
+$ drop-database
|
||||
$:
|
||||
%drop-database
|
||||
name=@tas
|
||||
force=?
|
||||
==
|
||||
```
|
||||
|
||||
## Arguments
|
||||
|
||||
**`FORCE`**
|
||||
Optionally, force deletion of a database.
|
||||
|
||||
**`<database>`**
|
||||
The name of the database to delete.
|
||||
|
||||
## Remarks
|
||||
This command mutates the state of the Obelisk agent.
|
||||
|
||||
The command only succeeds when no populated tables exist in the database, unless `FORCE` is specified.
|
||||
|
||||
## Produced Metadata
|
||||
DELETE row from `sys.sys.databases`.
|
||||
|
||||
## Exceptions
|
||||
`<database>` does not exist.
|
||||
`<database>` has populated tables and FORCE was not specified.
|
155
docs/03-ddl-namespace.md
Normal file
155
docs/03-ddl-namespace.md
Normal file
@ -0,0 +1,155 @@
|
||||
# CREATE NAMESPACE
|
||||
Namespaces group various database components, including tables and views. When not explicitly specified, namespace designations default to `dbo`.
|
||||
|
||||
```
|
||||
<create-namespace> ::=
|
||||
CREATE NAMESPACE [<database>.]<namespace>
|
||||
[ AS OF { NOW
|
||||
| <timestamp>
|
||||
| n { SECONDS | MINUTES | HOURS | DAYS | WEEKS | MONTHS | YEARS } AGO
|
||||
| <inline-scalar>
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Example
|
||||
`CREATE NAMESPACE my-namespace`
|
||||
|
||||
## API
|
||||
```
|
||||
+$ create-namespace
|
||||
database-name=@tas
|
||||
name=@tas
|
||||
as-of=(unit @da)
|
||||
==
|
||||
```
|
||||
|
||||
## Arguments
|
||||
|
||||
**`<namespace>`**
|
||||
This is a user-defined name for the new namespace. It must adhere to the hoon term naming standard.
|
||||
|
||||
Note: The "sys" namespace is reserved for system use.
|
||||
|
||||
**`AS OF`**
|
||||
Timestamp of namespace creation. Defaults to current time. When specified timestamp must be equal to or greater than latest system timestamp for the database.
|
||||
|
||||
## Remarks
|
||||
This command mutates the state of the Obelisk agent.
|
||||
|
||||
## Produced Metadata
|
||||
|
||||
system timestamp
|
||||
|
||||
## Exceptions
|
||||
|
||||
"duplicate key: {<key>}" namespace already exists
|
||||
AS OF less than latests system timestamp
|
||||
|
||||
# ALTER NAMESPACE
|
||||
Transfer an existing user `<table>` or `<view>` to another `<namespace>`.
|
||||
|
||||
```
|
||||
<alter-namespace> ::=
|
||||
ALTER NAMESPACE [ <database>. ]<namespace>
|
||||
TRANSFER { TABLE | VIEW } [ <db-qualifer> ]{ <table> | <view> }
|
||||
[ AS OF { NOW
|
||||
| <timestamp>
|
||||
| n { SECONDS | MINUTES | HOURS | DAYS | WEEKS | MONTHS | YEARS } AGO
|
||||
| <inline-scalar>
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## API
|
||||
```
|
||||
+$ alter-namespace
|
||||
$: %alter-namespace
|
||||
database-name=@tas
|
||||
source-namespace=@tas
|
||||
object-type=object-type
|
||||
target-namespace=@tas
|
||||
target-name=@tas
|
||||
as-of=(unit @da)
|
||||
==
|
||||
```
|
||||
|
||||
## Arguments
|
||||
|
||||
**`<namespace>`**
|
||||
Name of the target namespace into which the object is to be transferred.
|
||||
|
||||
**`TABLE | VIEW`**
|
||||
Indicates the type of the target object.
|
||||
|
||||
**`<table> | <view>`**
|
||||
Name of the object to be transferred to the target namespace.
|
||||
|
||||
**`AS OF`**
|
||||
Timestamp of namespace update. Defaults to current time. When specified timestamp must be equal to or greater than latest system timestamp for the database.
|
||||
|
||||
## Remarks
|
||||
This command mutates the state of the Obelisk agent.
|
||||
|
||||
Objects cannot be transferred in or out of namespace *sys*.
|
||||
|
||||
## Produced Metadata
|
||||
update `<database>.sys.tables`
|
||||
update `<database>.sys.views`
|
||||
|
||||
## Exceptions
|
||||
namespace does not exist
|
||||
`<table>` or `<view>` does not exist
|
||||
AS OF less than latests system timestamp
|
||||
|
||||
# DROP NAMESPACE
|
||||
Deletes a `<namespace>` and all its associated objects.
|
||||
|
||||
```
|
||||
<drop-namespace> ::=
|
||||
DROP NAMESPACE [ FORCE ] [ <database>. ]<namespace>
|
||||
[ AS OF { NOW
|
||||
| <timestamp>
|
||||
| n { SECONDS | MINUTES | HOURS | DAYS | WEEKS | MONTHS | YEARS } AGO
|
||||
| <inline-scalar>
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## API
|
||||
```
|
||||
+$ drop-namespace
|
||||
$:
|
||||
%drop-namespace
|
||||
database-name=@tas
|
||||
name=@tas
|
||||
force=?
|
||||
as-of=(unit @da)
|
||||
==
|
||||
```
|
||||
|
||||
## Arguments
|
||||
|
||||
**`FORCE`**
|
||||
Optionally, force deletion of `<namespace>`.
|
||||
|
||||
**`<namespace>`**
|
||||
The name of `<namespace>` to delete.
|
||||
|
||||
**`AS OF`**
|
||||
Timestamp of namespace deletion. Defaults to current time. When specified timestamp must be equal to or greater than latest system timestamp for the database.
|
||||
|
||||
## Remarks
|
||||
This command mutates the state of the Obelisk agent.
|
||||
|
||||
Only succeeds when no *populated* `<table>`s are in the namespace, unless `FORCE` is specified, possibly resulting in cascading object drops described in `DROP TABLE`.
|
||||
|
||||
The namespaces *dbo* and *sys* cannot be dropped.
|
||||
|
||||
## Produced Metadata
|
||||
DELETE row from `<database>.sys.namespaces`.
|
||||
|
||||
## Exceptions
|
||||
`<namespace>` does not exist.
|
||||
`<namespace>` has populated tables and FORCE was not specified.
|
||||
`AS OF` specified and not less than latest system timestamp for database.
|
@ -1,247 +1,3 @@
|
||||
# CREATE DATABASE
|
||||
|
||||
Creates a new user-space database accessible to any agent running on the ship. There is no sandboxing implemented.
|
||||
|
||||
_To Do NOTE_: Additional features like owner-desk property and GRANT desk permissions are under development.
|
||||
```
|
||||
<create-database> ::=
|
||||
CREATE DATABASE <database>
|
||||
[ AS OF { NOW
|
||||
| <timestamp>
|
||||
| n { SECONDS | MINUTES | HOURS | DAYS | WEEKS | MONTHS | YEARS } AGO
|
||||
| <inline-scalar>
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Example
|
||||
```
|
||||
CREATE DATABASE my-database
|
||||
```
|
||||
|
||||
## API
|
||||
```
|
||||
+$ create-database $:([%create-database name=@tas as-of=(unit @da)])
|
||||
```
|
||||
|
||||
## Arguments
|
||||
|
||||
**`<database>`**
|
||||
The user-defined name for the new database. It must comply with the Hoon term naming standard.
|
||||
|
||||
**`AS OF`**
|
||||
Timestamp of database creation. Defaults to current time. Subsequent DDL and data actions must have timestamps equal to or greater than this timestamp.
|
||||
|
||||
## Remarks
|
||||
|
||||
This command mutates the state of the Obelisk agent.
|
||||
|
||||
`CREATE DATABASE` must be executed independently within a script. The script will fail if there are prior commands. Subsequent commands will be ignored.
|
||||
|
||||
## Produced Metadata
|
||||
|
||||
INSERT row into `sys.sys.databases`.
|
||||
|
||||
## Example
|
||||
|
||||
create-database %db1
|
||||
|
||||
## Exceptions
|
||||
|
||||
"duplicate key: {<key>}" database already exists
|
||||
|
||||
# DROP DATABASE
|
||||
Deletes an existing `<database>` and all associated objects.
|
||||
```
|
||||
<drop-database> ::= DROP DATABASE [ FORCE ] <database>
|
||||
```
|
||||
|
||||
## API
|
||||
```
|
||||
+$ drop-database
|
||||
$:
|
||||
%drop-database
|
||||
name=@tas
|
||||
force=?
|
||||
==
|
||||
```
|
||||
|
||||
## Arguments
|
||||
|
||||
**`FORCE`**
|
||||
Optionally, force deletion of a database.
|
||||
|
||||
**`<database>`**
|
||||
The name of the database to delete.
|
||||
|
||||
## Remarks
|
||||
This command mutates the state of the Obelisk agent.
|
||||
|
||||
The command only succeeds when no populated tables exist in the database, unless `FORCE` is specified.
|
||||
|
||||
## Produced Metadata
|
||||
DELETE row from `sys.sys.databases`.
|
||||
|
||||
## Exceptions
|
||||
`<database>` does not exist.
|
||||
`<database>` has populated tables and FORCE was not specified.
|
||||
|
||||
# CREATE NAMESPACE
|
||||
Namespaces group various database components, including tables and views. When not explicitly specified, namespace designations default to `dbo`.
|
||||
|
||||
```
|
||||
<create-namespace> ::=
|
||||
CREATE NAMESPACE [<database>.]<namespace>
|
||||
[ AS OF { NOW
|
||||
| <timestamp>
|
||||
| n { SECONDS | MINUTES | HOURS | DAYS | WEEKS | MONTHS | YEARS } AGO
|
||||
| <inline-scalar>
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Example
|
||||
`CREATE NAMESPACE my-namespace`
|
||||
|
||||
## API
|
||||
```
|
||||
+$ create-namespace
|
||||
database-name=@tas
|
||||
name=@tas
|
||||
as-of=(unit @da)
|
||||
==
|
||||
```
|
||||
|
||||
## Arguments
|
||||
|
||||
**`<namespace>`**
|
||||
This is a user-defined name for the new namespace. It must adhere to the hoon term naming standard.
|
||||
|
||||
Note: The "sys" namespace is reserved for system use.
|
||||
|
||||
**`AS OF`**
|
||||
Timestamp of namespace creation. Defaults to current time. When specified timestamp must be equal to or greater than latest system timestamp for the database.
|
||||
|
||||
## Remarks
|
||||
This command mutates the state of the Obelisk agent.
|
||||
|
||||
## Produced Metadata
|
||||
|
||||
system timestamp
|
||||
|
||||
## Exceptions
|
||||
|
||||
"duplicate key: {<key>}" namespace already exists
|
||||
AS OF less than latests system timestamp
|
||||
|
||||
# ALTER NAMESPACE
|
||||
Transfer an existing user `<table>` or `<view>` to another `<namespace>`.
|
||||
|
||||
```
|
||||
<alter-namespace> ::=
|
||||
ALTER NAMESPACE [ <database>. ]<namespace>
|
||||
TRANSFER { TABLE | VIEW } [ <db-qualifer> ]{ <table> | <view> }
|
||||
[ AS OF { NOW
|
||||
| <timestamp>
|
||||
| n { SECONDS | MINUTES | HOURS | DAYS | WEEKS | MONTHS | YEARS } AGO
|
||||
| <inline-scalar>
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## API
|
||||
```
|
||||
+$ alter-namespace
|
||||
$: %alter-namespace
|
||||
database-name=@tas
|
||||
source-namespace=@tas
|
||||
object-type=object-type
|
||||
target-namespace=@tas
|
||||
target-name=@tas
|
||||
as-of=(unit @da)
|
||||
==
|
||||
```
|
||||
|
||||
## Arguments
|
||||
|
||||
**`<namespace>`**
|
||||
Name of the target namespace into which the object is to be transferred.
|
||||
|
||||
**`TABLE | VIEW`**
|
||||
Indicates the type of the target object.
|
||||
|
||||
**`<table> | <view>`**
|
||||
Name of the object to be transferred to the target namespace.
|
||||
|
||||
**`AS OF`**
|
||||
Timestamp of namespace update. Defaults to current time. When specified timestamp must be equal to or greater than latest system timestamp for the database.
|
||||
|
||||
## Remarks
|
||||
This command mutates the state of the Obelisk agent.
|
||||
|
||||
Objects cannot be transferred in or out of namespace *sys*.
|
||||
|
||||
## Produced Metadata
|
||||
update `<database>.sys.tables`
|
||||
update `<database>.sys.views`
|
||||
|
||||
## Exceptions
|
||||
namespace does not exist
|
||||
`<table>` or `<view>` does not exist
|
||||
AS OF less than latests system timestamp
|
||||
|
||||
# DROP NAMESPACE
|
||||
Deletes a `<namespace>` and all its associated objects.
|
||||
|
||||
```
|
||||
<drop-namespace> ::=
|
||||
DROP NAMESPACE [ FORCE ] [ <database>. ]<namespace>
|
||||
[ AS OF { NOW
|
||||
| <timestamp>
|
||||
| n { SECONDS | MINUTES | HOURS | DAYS | WEEKS | MONTHS | YEARS } AGO
|
||||
| <inline-scalar>
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## API
|
||||
```
|
||||
+$ drop-namespace
|
||||
$:
|
||||
%drop-namespace
|
||||
database-name=@tas
|
||||
name=@tas
|
||||
force=?
|
||||
as-of=(unit @da)
|
||||
==
|
||||
```
|
||||
|
||||
## Arguments
|
||||
|
||||
**`FORCE`**
|
||||
Optionally, force deletion of `<namespace>`.
|
||||
|
||||
**`<namespace>`**
|
||||
The name of `<namespace>` to delete.
|
||||
|
||||
**`AS OF`**
|
||||
Timestamp of namespace deletion. Defaults to current time. When specified timestamp must be equal to or greater than latest system timestamp for the database.
|
||||
|
||||
## Remarks
|
||||
This command mutates the state of the Obelisk agent.
|
||||
|
||||
Only succeeds when no *populated* `<table>`s are in the namespace, unless `FORCE` is specified, possibly resulting in cascading object drops described in `DROP TABLE`.
|
||||
|
||||
The namespaces *dbo* and *sys* cannot be dropped.
|
||||
|
||||
## Produced Metadata
|
||||
DELETE row from `<database>.sys.namespaces`.
|
||||
|
||||
## Exceptions
|
||||
`<namespace>` does not exist.
|
||||
`<namespace>` has populated tables and FORCE was not specified.
|
||||
`AS OF` specified and not less than latest system timestamp for database.
|
||||
|
||||
# CREATE TABLE
|
||||
`<table>`s are the only means of indexed persistent `<table-sets>`s in Obelisk.
|
||||
Any update to `<table>` contents results in a state change of the Obelisk agent.
|
||||
@ -494,6 +250,7 @@ table column referenced by FOREIGN KEY does not exist
|
||||
aura mis-match in FOREIGN KEY
|
||||
AS OF timestamp prior to latest system timestamp for table
|
||||
|
||||
|
||||
# DROP TABLE
|
||||
Deletes a `<table>` and all associated objects
|
||||
|
||||
@ -548,3 +305,4 @@ DELETE from `<database>.sys.indices`.
|
||||
`<table>` used in `<view>` and FORCE was not specified.
|
||||
`<table>` used in `<foreign-key>` and FORCE was not specified.
|
||||
AS OF `<timestamp>` prior to latest system timestamp `<timestamp>`.
|
||||
|
@ -1,130 +0,0 @@
|
||||
# Introduction
|
||||
|
||||
## Manifesto
|
||||
|
||||
A _first principles_ approach should guide the design and implementation of an Urbit RDBMS. The _urQL_ language, influenced by _The Third Manifesto_ (Date and Darwen), emphasizes composability and type safety. The areas where SQL design was hurried or neglected in terms of theoretical considerations (like nullable columns) have been excluded or corrected, making urQL closer to the _Query Language_ that Codd and Date would have endorsed.
|
||||
|
||||
An Urbit-native RDBMS implementation presents new opportunities for composability. Any desk's data is readily available for _mash up_ apps and _ad hoc_ queries, and every desk persisting data to an RDBMS already has search functionality built-in.
|
||||
|
||||
## Functionality
|
||||
|
||||
The Urbit RDBMS, Obelisk, consists of:
|
||||
|
||||
1. A scripting language and parser (as documented here).
|
||||
2. A plan builder.
|
||||
3. A front-end agent app using the parser and APIs.
|
||||
|
||||
The scripting language, _urQL_, is a derivation of SQL with significant variations.
|
||||
|
||||
Queries are constructed in FROM..WHERE..SELECT.. order, mirroring the order of events in plan execution. (Users should be aware of the event ordering.)
|
||||
|
||||
Columns are typed atoms. Table definitions do not permit nullable columns.
|
||||
|
||||
All user-defined names (excepting aliases) follow the hoon term naming standard.
|
||||
|
||||
Functions, apart from the simplest ones, are grouped in their own clause and inlined into SELECT clause and predicates by alias.
|
||||
|
||||
Inlined sub-queries are prohibited to enhance readability. JOINs and/or CTEs accommodate all related use cases and promote composability. CTEs can be referenced for certain use cases in predicates.
|
||||
|
||||
Relational division is supported with a DIVIDED BY operator.
|
||||
|
||||
Set operations support nesting of queries on the right side of the operator.
|
||||
|
||||
All data manipulation commands (DELETE, INSERT, MERGE, UPDATE), along with the SELECT statement, can accept a dataset output by the previous TRANSFORM step and send its output dataset to the next step.
|
||||
|
||||
Reading and/or updating data on foreign ships is permissible if the ship's pilot has granted permission. Cross database joins are allowed, but cross ship joins are not. Views cannot be defined on foreign databases.
|
||||
|
||||
Queries can operate on previous versions and data of the databases through the the AS OF clause.
|
||||
|
||||
This document has placeholders for Stored Procedures and Triggers, which have yet to be defined. These will be points for integration with hoon and other agents.
|
||||
|
||||
## urQL language diagrams and general syntax
|
||||
|
||||
[ ] indicate optional entries.
|
||||
{ } nest options | delimited. If there is a default, it is the first entry.
|
||||
In some cases { } groups a portion of the diagram to indicate optional repeating [ ,...n ].
|
||||
\<...> Represents a user-supplied argument that either expands to a diagram defined elsewhere or hints at user input, e.g. `<alias>`, `<new-table>`.
|
||||
|
||||
Text outside of brackets represents required keywords.
|
||||
Keywords are uppercase. This is not a requirement, but is strongly suggested for readability.
|
||||
|
||||
All whitespace is treated the same; a single space or line feed suffices.
|
||||
Whitespace around delimiting `;` and `,` is optional.
|
||||
Whitespace is required on the outside of parentheses and optional on the inside.
|
||||
|
||||
Multiple statements must be delimited by `;`.
|
||||
|
||||
All object names follow the hoon rules for terms, i.e. character set restricted to lower-case alpha-numeric and hypen characters and first character must be alphabetic.
|
||||
|
||||
Column, table, and other aliases provide an alternative to referencing the qualified object name and follow the hoon term naming standard, except that upper-case alphabetic characters are permitted and alias evaluation is case agnositc, e.g. `t1` and `T1` represent the same alias.
|
||||
|
||||
All objects in the database *sys* and namespace *sys* are system-owned and read-only for all user commands. The namespace *sys* may not be specified in any user-defined database.
|
||||
|
||||
## Common structures throughout the reference
|
||||
The following are some common language structures used throughout the reference:
|
||||
|
||||
```
|
||||
<db-qualifier> ::= { <database>.<namespace>. | <database>.. | <namespace>. }
|
||||
```
|
||||
|
||||
Provides the fully qualified path to a `<table>` or `<view>` object on the host ship.
|
||||
|
||||
`<database>` defaults to the current-databse property of the Obelisk agent.
|
||||
|
||||
`<namespace>` defaults to 'dbo' (database owner).
|
||||
|
||||
```
|
||||
<ship-qualifier> ::=
|
||||
{ @p.<database>.<namespace>.
|
||||
| @p.<database>..
|
||||
| <db-qualifier> }
|
||||
```
|
||||
|
||||
Adds ship qualification.
|
||||
|
||||
```
|
||||
<common-table-expression> ::= <transform> [ AS ] <alias>
|
||||
```
|
||||
`<transform> ::=` from transform diagram.
|
||||
|
||||
`<alias> ::= @t` case-agnostic, see alias naming discussion above.
|
||||
|
||||
Each CTE is always referenced by alias, never inlined.
|
||||
|
||||
```
|
||||
<table-set> ::=
|
||||
[ <ship-qualifier> ]{ <table> | <view> }
|
||||
| <common-table-expression>
|
||||
| ( column-1 [,...column-n] )
|
||||
| *
|
||||
```
|
||||
|
||||
When `<view>, <table>` have the same name within a namespace, `<view>` is said to "shadow" `<table>` wherever syntax accepts `<table>` or `<view>`.
|
||||
|
||||
A base-table, `<table>`, is the only manifestation of `<table-set>` that is not a computation.
|
||||
|
||||
Every `<table-set>` is a virtual-table and the row type may be a union type.
|
||||
|
||||
If not cached, `<view>` must be evaluated to resolve.
|
||||
|
||||
`( column-1 [,...column-n] )` assigns column names to the widest row type of an incoming pass-thru table.
|
||||
|
||||
`*` accepts an incoming pass-thru virtual-table assuming column names established by the previous set-command (`DELETE`, `INSERT`, `MERGE`, `QUERY`, or `UPDATE`) that created the pass-thru.
|
||||
|
||||
Similarly `*` as the output of `DELETE`, `INSERT`, `MERGE` creates a pass-thru virtual-table for consumption by the next step or ultimate product of a `<transform>`.
|
||||
|
||||
## Issues
|
||||
(very incomplete list)
|
||||
1. Stored procedures - To Be Designed (TBD)
|
||||
2. Triggers - TBD
|
||||
3. Localization of date/time - TBD (See: https://github.com/sigilante/l10n)
|
||||
4. `SELECT` single column named `top` or `bottom` may cause problems
|
||||
5. Add `DISTINCT` and other advanced aggregate features like Grouping Sets, Rollup, Cube, GROUPING function. Feature T301 'Functional dependencies' from SQL 1999 specification needs to be added.
|
||||
6. Change column:ast and value-literal:ast to vase in parser and AST.
|
||||
7. Set operators, multiple commands per `<transform>` not complete in the parser.
|
||||
8. Scalar and aggregate functions incompletely implemented in parser and not fully desinged.
|
||||
9. Add aura @uc Bitcoin address 0c1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa
|
||||
10. Custom types and support for arbitrary noun columns - TBD
|
||||
11. Pivoting and windowing will be implemented in a future release.
|
||||
12. `<view>` not implemented in parser and caching is TBD
|
||||
13. Option in `<merge>` to replicate `<target-table>`'s `<foreign-key>`s and/or unique indices when new `<table>` created.
|
@ -1,55 +0,0 @@
|
||||
# LITERALS
|
||||
|
||||
urQL supports most of the aura types implemented in Urbit as literals for the INSERT and SELECT commands. The *loobean* Urbit literal types is supported by *different* literals in urQL than normally in Urbit. urQL supports some literal types in multiple ways. Dates, timespans, and ships can all be represented in INSERT without the leading **~**. Unsigned decimal can be represented without the dot thousands separator. In some cases the support between INSERT and SELECT is not the same.
|
||||
|
||||
Column types (auras) not supported for INSERT can only be inserted into tables through the API.
|
||||
|
||||
| Aura | Description | INSERT | SELECT |
|
||||
| :--- |:-------------------- |:------------------:|:------------------:|
|
||||
| @c | UTF-32 | ~-~45fed. | **not supported** |
|
||||
| @da | date | ~2020.12.25 | ~2020.12.25 |
|
||||
| | | ~2020.12.25..7.15.0 | ~2020.12.25..7.15.0 |
|
||||
| | | ~2020.12.25..7.15.0..1ef5 | ~2020.12.25..7.15.0..1ef5 |
|
||||
| | | 2020.12.25 | 2020.12.25 |
|
||||
| | | 2020.12.25..7.15.0 | 2020.12.25..7.15.0 |
|
||||
| | | 2020.12.25..7.15.0..1ef5 | 2020.12.25..7.15.0..1ef5
|
||||
| @dr | timespan | ~d71.h19.m26.s24..9d55 | ~d71.h19.m26.s24..9d55 |
|
||||
| | | ~d71.h19.m26.s24 | ~d71.h19.m26.s24 |
|
||||
| | | ~d71.h19.m26 | ~d71.h19.m26 |
|
||||
| | | ~d71.h19 | ~d71.h19 |
|
||||
| | | ~d71 | ~d71 |
|
||||
| | | d71.h19.m26.s24..9d55 | |
|
||||
| | | d71.h19.m26.s24 | |
|
||||
| | | d71.h19.m26 | |
|
||||
| | | d71.h19 | |
|
||||
| | | d71 | |
|
||||
| @f | loobean | y, n, Y, N | Y, N |
|
||||
| @if | IPv4 address | .195.198.143.90 | .195.198.143.90 |
|
||||
| @is | IPv6 address | .0.0.0.0.0.1c.c3c6.8f5a | .0.0.0.0.0.1c.c3c6.8f5a |
|
||||
| @p | ship name | ~sampel-palnet | ~sampel-palnet |
|
||||
| | | sampel-palnet | |
|
||||
| @q | phonemic base | **not supported** | **not supported** |
|
||||
| @rh | half float (16b) | **not supported** | **not supported** |
|
||||
| @rs | single float (32b) | .3.14, .-3.14 | .3.14, .-3.14 |
|
||||
| @rd | double float (64b) | .~3.14, .~-3.14 | .~3.14, .~-3.14 |
|
||||
| @rq | quad float (128b) | **not supported** | **not supported** |
|
||||
| @sb | signed binary | --0b10.0000 | --0b10.0000 |
|
||||
| | | -0b10.0000 | -0b10.0000 |
|
||||
| @sd | signed decimal | --20, -20 | --20, -20 |
|
||||
| @sv | signed base32 | --0v201.4gvml.245kc | --0v201.4gvml.245kc |
|
||||
| | | -0v201.4gvml.245kc | -0v201.4gvml.245kc |
|
||||
| @sw | signed base64 | --0w2.04AfS.G8xqc | --0w2.04AfS.G8xqc |
|
||||
| | | -0w2.04AfS.G8xqc | -0w2.04AfS.G8xqc |
|
||||
| @sx | signed hexadecimal | --0x2004.90fd | --0x2004.90fd |
|
||||
| | | -0x2004.90fd | -0x2004.90fd |
|
||||
| @t | UTF-8 text (cord) | 'cord', 'cord\\\\'s' <sup>1</sup> | 'cord', 'cord\\\\'s' <sup>1</sup> |
|
||||
| @ta | ASCII text (knot) | *support pending* | *support pending* |
|
||||
| @tas | ASCII text (term) | *support pending* | *support pending* |
|
||||
| @ub | unsigned binary | 10.1011 | 10.1011 |
|
||||
| @ud | unsigned decimal | 2.222 | 2.222 |
|
||||
| | | 2222 | 2222 |
|
||||
| @uv | unsigned base32 | **not supported** | **not supported** |
|
||||
| @uw | unsigned base64 | e2O.l4Xpm | **not supported** |
|
||||
| @ux | unsigned hexadecimal | 0x12.6401 | 0x12.6401 |
|
||||
|
||||
<sup>1</sup> Example of embedding single quote in @t literal.
|
@ -2,112 +2,6 @@
|
||||
/+ parse, *test
|
||||
|%
|
||||
|
||||
++ m-cmnt-1
|
||||
"/* line1\0a line2 \0a line3\0a*/"
|
||||
++ m-cmnt-2
|
||||
"\0a/* linea\0a lineb \0a linec \0a*/"
|
||||
++ m-cmnt-3
|
||||
"\0a/* linea1 \0a lineb2 \0a linec3 \0a*/"
|
||||
|
||||
++ vfas-tar [%selected-value value=[p=~.t q=10.799] alias=~]
|
||||
++ vcol-col [%selected-value value=[p=~.t q=14.906] alias=~]
|
||||
++ vtar-fas [%selected-value value=[p=~.t q=12.074] alias=~]
|
||||
++ va-fas-tar-a [%selected-value value=[p=~.t q=539.635.488] alias=~]
|
||||
++ va-col-col-a [%selected-value value=[p=~.t q=540.686.880] alias=~]
|
||||
++ va-tar-fas-a [%selected-value value=[p=~.t q=539.961.888] alias=~]
|
||||
|
||||
++ s1 ~[vfas-tar vtar-fas vcol-col va-fas-tar-a va-tar-fas-a va-col-col-a]
|
||||
++ s2 ~[va-col-col-a vfas-tar vtar-fas vcol-col va-fas-tar-a va-tar-fas-a]
|
||||
++ s3 ~[va-tar-fas-a va-col-col-a vfas-tar vtar-fas vcol-col va-fas-tar-a]
|
||||
|
||||
++ s1a ~[vfas-tar vtar-fas]
|
||||
++ s2a ~[va-col-col-a vfas-tar vtar-fas]
|
||||
++ s3a ~[va-tar-fas-a va-col-col-a vfas-tar vtar-fas]
|
||||
++ s3b ~[va-tar-fas-a]
|
||||
|
||||
++ q1 [%query from=~ scalars=~ predicate=~ group-by=~ having=~ selection=[%select top=~ bottom=~ columns=s1] order-by=~]
|
||||
++ q2 [%query from=~ scalars=~ predicate=~ group-by=~ having=~ selection=[%select top=~ bottom=~ columns=s2] order-by=~]
|
||||
++ q3 [%query from=~ scalars=~ predicate=~ group-by=~ having=~ selection=[%select top=~ bottom=~ columns=s3] order-by=~]
|
||||
++ q3a [%query from=~ scalars=~ predicate=~ group-by=~ having=~ selection=[%select top=~ bottom=~ columns=s3a] order-by=~]
|
||||
++ q3b [%query from=~ scalars=~ predicate=~ group-by=~ having=~ selection=[%select top=~ bottom=~ columns=s3b] order-by=~]
|
||||
|
||||
++ q1a [%query from=~ scalars=~ predicate=~ group-by=~ having=~ selection=[%select top=~ bottom=~ columns=s1a] order-by=~]
|
||||
++ q2a [%query from=~ scalars=~ predicate=~ group-by=~ having=~ selection=[%select top=~ bottom=~ columns=s2a] order-by=~]
|
||||
|
||||
++ t1 [%transform ctes=~ set-functions=[q1 ~ ~]]
|
||||
++ t2 [%transform ctes=~ set-functions=[q2 ~ ~]]
|
||||
++ t3 [%transform ctes=~ set-functions=[q3 ~ ~]]
|
||||
|
||||
++ t1a [%transform ctes=~ set-functions=[q1a ~ ~]]
|
||||
++ t2a [%transform ctes=~ set-functions=[q2a ~ ~]]
|
||||
++ t3a [%transform ctes=~ set-functions=[q3a ~ ~]]
|
||||
++ t3b [%transform ctes=~ set-functions=[q3b ~ ~]]
|
||||
|
||||
++ test-line-cmnt-00
|
||||
%+ expect-eq
|
||||
!> ~
|
||||
!> %- parse:parse(default-database 'other-db') ~
|
||||
++ test-line-cmnt-01
|
||||
%+ expect-eq
|
||||
!> ~
|
||||
!> %- parse:parse(default-database 'other-db') %- zing ~["::line cmnt"]
|
||||
++ test-line-cmnt-02
|
||||
%+ expect-eq
|
||||
!> ~[[%create-namespace database-name='db1' name='ns1' as-of=~]]
|
||||
!> (parse:parse(default-database 'db1') "create namespace ns1 \0a::line cmnt")
|
||||
++ test-line-cmnt-03
|
||||
%+ expect-eq
|
||||
!> ~[[%create-namespace database-name='db1' name='ns1' as-of=~]]
|
||||
!> (parse:parse(default-database 'db1') "create namespace ns1 ::line cmnt")
|
||||
++ test-line-cmnt-04
|
||||
%+ expect-eq
|
||||
!> ~[t1a t2 t3]
|
||||
!> %- parse:parse(default-database 'other-db')
|
||||
%- zing
|
||||
%- limo
|
||||
:~ "select '\2f\2a', '*\2f' ::, ' \2f\2a ', ' *\2f ', ' :: '\0a"
|
||||
m-cmnt-1
|
||||
"select ' :: ', '\2f\2a', '*\2f', '::', ' \2f\2a ', ' *\2f '"
|
||||
m-cmnt-2
|
||||
"select ' *\2f ', ' :: ', '\2f\2a', '*\2f', '::', ' \2f\2a '"
|
||||
m-cmnt-3
|
||||
==
|
||||
++ test-line-cmnt-05
|
||||
%+ expect-eq
|
||||
!> ~[t1 t2a t3]
|
||||
!> %- parse:parse(default-database 'other-db')
|
||||
%- zing
|
||||
%- limo
|
||||
:~ "select '\2f\2a', '*\2f', '::', ' \2f\2a ', ' *\2f ', ' :: '\0a"
|
||||
m-cmnt-1
|
||||
"select ' :: ', '\2f\2a', '*\2f'::, ' \2f\2a ', ' *\2f '"
|
||||
m-cmnt-2
|
||||
"select ' *\2f ', ' :: ', '\2f\2a', '*\2f', '::', ' \2f\2a '"
|
||||
m-cmnt-3
|
||||
==
|
||||
++ test-line-cmnt-06
|
||||
%+ expect-eq
|
||||
!> ~[t1 t2 t3a]
|
||||
!> %- parse:parse(default-database 'other-db')
|
||||
%- zing
|
||||
%- limo
|
||||
:~ "select '\2f\2a', '*\2f', '::', ' \2f\2a ', ' *\2f ', ' :: '\0a"
|
||||
m-cmnt-1
|
||||
"select ' :: ', '\2f\2a', '*\2f', '::', ' \2f\2a ', ' *\2f '"
|
||||
m-cmnt-2
|
||||
"select ' *\2f ', ' :: ', '\2f\2a', '*\2f' ::, ' \2f\2a '"
|
||||
m-cmnt-3
|
||||
==
|
||||
++ test-line-cmnt-07
|
||||
%+ expect-eq
|
||||
!> ~[t1 t2a t3b]
|
||||
!> %- parse:parse(default-database 'other-db')
|
||||
%- zing
|
||||
%- limo
|
||||
:~ "select '\2f\2a', '*\2f', '::', ' \2f\2a ', ' *\2f ', ' :: '\0a"
|
||||
"select ' :: ', '\2f\2a', '*\2f'::, ' \2f\2a ', ' *\2f '\0a"
|
||||
"select ' *\2f ' :: ', '\2f\2a', '*\2f', '::', ' \2f\2a '"
|
||||
==
|
||||
|
||||
|
||||
::@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
|
Loading…
Reference in New Issue
Block a user