update docs

This commit is contained in:
jackfoxy 2024-01-21 13:50:35 -08:00
parent 3a5887e3da
commit 1ade8b18d8
13 changed files with 535 additions and 370 deletions

View File

@ -1,4 +1,4 @@
# Introduction
# Preliminaries
## Introduction
@ -11,7 +11,7 @@ An Urbit-native RDBMS implementation presents new opportunities for composabilit
The Urbit RDBMS, Obelisk, consists of:
1. A scripting language, urQL, and parser.
2. A a database engine, Obelisk.
2. A database engine, Obelisk.
3. A front-end agent app using the parser and Obelisk APIs. (currently does not exist)
The scripting language, _urQL_, is a derivation of SQL with significant variations.
@ -20,7 +20,7 @@ Queries are constructed in FROM..WHERE..SELECT.. order, mirroring the order of e
Columns are typed atoms. Table definitions do not permit nullable columns.
All user-defined names (excepting aliases) follow the hoon term naming standard.
All user-defined names, except 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.
@ -52,13 +52,13 @@ 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.
All object names follow the hoon rules for terms, i.e. character set restricted to lower-case alpha-numeric and hyphen 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.
Column, table, and other aliases offer an alternative to referencing the qualified object name. They follow the hoon term naming standard, except that upper-case alphabetic characters are allowed. Alias evaluation is case agnostic, 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 documenataion structures
## Common documentation structures
The following are some common language structures used throughout the reference.
@ -66,9 +66,9 @@ 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. (NOTE: `<view>` is not yet implemented and is intended to be similar similar to SQL view.)
Provides the fully qualified path to a `<table>` or `<view>` object on the host ship. (NOTE: `<view>` is not yet implemented and is intended to be similar to SQL view.)
`<database>` defaults to the current-databse property of the Obelisk agent.
`<database>` defaults to the current-database property of the Obelisk agent.
`<namespace>` defaults to 'dbo' (database owner).
@ -103,7 +103,7 @@ Base-tables, `<table>`, are the sole source of content in an Obelisk database an
The `<transform>` command returns a `<table-set>`, hence every `<table-set>` is typed by one or more equivalent urQL `<transform>` commands. This is true because every `<transform>` command is idempotent. (More on this in the section on __Time__.)
The row type is defined by the component columns and may be a union type. Hence rows of `<table-set>`s that are not also `<table>`s may be of varying length (jagged). The order of rows may be determined in the `<transform>` command, and so `<table-set>`s are not strictly __sets___ in the mathematical sense.
The row type is defined by the component columns and may be a union type. Hence rows of `<table-set>`s that are not also `<table>`s may be of varying length (jagged). The order of rows may be determined in the `<transform>` command, and so `<table-set>`s are not strictly *sets* in the mathematical sense.
```
<as-of-time> ::=
@ -114,7 +114,7 @@ The row type is defined by the component columns and may be a union type. Hence
}
```
Specifying `<as-of-time>` overrides setting the schema and/or content timestamp in state changes. See the section on __Time__.
Specifying `<as-of-time>` overrides setting the schema and/or content timestamp in state changes.
`NOW` default, current computer time
@ -126,7 +126,7 @@ Specifying `<as-of-time>` overrides setting the schema and/or content timestamp
## 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.
urQL supports most 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.
@ -183,10 +183,10 @@ Column types (auras) not supported for INSERT can only be inserted into tables t
## Types
All data representations (nouns) of the Obelisk system are strongly typed.
## Column Types
### Column Types
The fundamental data element in Obelisk is an atom that is typed by an aura. Data cells, which are intersections of a `<table-set>` row and column, are typed atoms.
Obelisk supports the following auras (see ch12-literals for representing the atomic types):
Obelisk supports the following auras (see the __Literals__ section for representing the atomic types):
| Aura | Description |
| :--- |:---------------------------- |
@ -222,7 +222,7 @@ Columns are typed by an aura and indexed by name.
<aura/name>
```
## Table Row and Table Types
### Table Row and Table Types
All datasets in Obelisk are sets, meaning each typed element, `<row-type>`, only exists once.
Datasets are also commonly regarded as tables, which is accurate when the index of each cell (row/column intersection) can be calculated. This calculation is possible when the `SELECT` statement includes an `ORDER BY` clause.
@ -252,10 +252,10 @@ In general, `<table-set>`s have the type:
| (set (<all-column-row-type> | <row-sub-type-1> | ... | <row-sub-type-n> ))
```
## Additional Types
All the static types in Obelisk API are defined in `sur/ast/hoon`.
### Additional Types
All static types in Obelisk API are defined in `sur/ast/hoon`.
## Remarks
### Remarks
Even `<table>`s can be typed as sets, because a `SELECT` statement without an `ORDER BY` clause has an undefined row order.
@ -265,4 +265,10 @@ Ultimately, "set" is the most important concept because every `<table-set>` will
## Time
In **urQL** time is both primary and fundamental. Every change of state, whether to a database's schema or content, is indexed by time. Thus every query is idempotent.
In *urQL* time is both primary and fundamental. Every change of state, whether to a database's schema or content, is indexed by time. Thus every query is idempotent.
The rules enforcing time primacy in the Obelisk database engine are simple. Each database has a most recent schema time and a most recent content time. Every subsequent state change, whether to schema or content must be subsequent to the latest of the two times. Normally the user never needs to concern himself with this requirement. The database engine just takes care of it because the default `<as-of-time>` for every command is `NOW`, the host system time carried in the Obelisk agent's `now.bowl`. *urQL* scripts default every command in a script (sequence of commands) to `NOW`, so the time result of script execution is as if everything happened "all at once" even though the commands executed sequentially. This applies as well to lists of *urQL* command ASTs, for those using a purely programmatic interface (API). We will use `script` to mean both in all cases. Users only need to be aware of this rule when applying `<as-of-time>` to override `NOW`. Violation causes the entire script to fail. (Scripts are always atomic.) The `CREATE DATABASE` command sets the first schema and content times to the database creation time, one of the reasons `CREATE DATABASE` must be the only command in a script.
The second, and last, rule is once you introduce a query into a script, all subsequent commands must also be queries. Among the metadata returned by queries is the schema and content times (labelled `system time` and `data time`) used by the engine to create the query results. The query has a de facto `<as-of-time>` of the latest of the two. That is what makes it idempotent. You need to specify this `<as-of-time>` to recreate the same query. By specifying `<as-of-time>` in a query the engine uses the schema and content in effect at that time to create the results.
Permission commands `GRANT` and `REVOKE` are outside the scope of time indexing and apply in real time.

View File

@ -1,56 +1,63 @@
# CREATE DATABASE
# DDL: Database
Creates a new user-space database accessible to any agent running on the ship. There is no sandboxing implemented.
## CREATE DATABASE
Creates a new user-space database on the ship.
_To Do NOTE_: Additional features like owner-desk property and GRANT desk permissions are under development.
```
<create-database> ::=
CREATE DATABASE <database> [ <as-of-time> ]
```
## Example
### API
```
CREATE DATABASE my-database
+$ create-database
$:
%create-database
name=@tas
as-of=(unit <as-of>)
==
```
## API
```
+$ create-database $:([%create-database name=@tas as-of=(unit @da)])
```
## Arguments
### Arguments
**`<database>`**
The user-defined name for the new database. It must comply with the Hoon term naming standard.
**`<as-of-time>`**
Timestamp of database creation. Defaults to NOW (current time). Subsequent DDL and data actions must have timestamps greater than this timestamp.
Timestamp of database creation. Defaults to `NOW` (current time). Subsequent DDL and data actions must have timestamps greater than this timestamp.
## Remarks
### Remarks
This command mutates the state of the Obelisk agent.
This command mutates the state of the Obelisk agent. It inserts a row into the view `sys.sys.databases`.
`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
### Produced Metadata
INSERT row into `sys.sys.databases`.
Schema timestamp (labelled 'system time')
Content timestamp (labelled 'data time')
## Example
### Exceptions
create-database %db1
database name cannot be 'sys'
duplicate key: `<database>`
## Exceptions
### Example
```
CREATE DATABASE my-database
```
"duplicate key: {<key>}" database already exists
## DROP DATABASE
*supported in urQL parser, not yet supported in Obelisk*
# DROP DATABASE
Deletes an existing `<database>` and all associated objects.
```
<drop-database> ::= DROP DATABASE [ FORCE ] <database>
```
## API
### API
```
+$ drop-database
$:
@ -60,7 +67,7 @@ Deletes an existing `<database>` and all associated objects.
==
```
## Arguments
### Arguments
**`FORCE`**
Optionally, force deletion of a database.
@ -71,11 +78,12 @@ 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.
The command only succeeds when no populated tables exist in the database, unless `FORCE` is specified. It removes the row from the view `sys.sys.databases`.
## Produced Metadata
DELETE row from `sys.sys.databases`.
Schema timestamp (labelled 'system time')
Content timestamp (labelled 'data time')
## Exceptions
`<database>` does not exist.
`<database>` has populated tables and FORCE was not specified.
`<database>` does not exist
`<database>` has populated tables and `FORCE` was not specified

View File

@ -1,24 +1,31 @@
# CREATE NAMESPACE
# DDL: Namespace
## CREATE NAMESPACE
Creates a new namespace within the specified or default database.
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-time> ]
CREATE NAMESPACE [<database>.] <namespace> [ <as-of-time> ]
```
## Example
`CREATE NAMESPACE my-namespace`
## API
### API
```
+$ create-namespace
database-name=@tas
name=@tas
as-of=(unit @da)
as-of=(unit as-of)
==
```
## Arguments
### Arguments
** `<database>`**
The database within which to create the namespace. When specified overrides the default database.
If not explicitly qualified, it defaults to the Obelisk agent's current database.
**`<namespace>`**
This is a user-defined name for the new namespace. It must adhere to the hoon term naming standard.
@ -26,31 +33,42 @@ This is a user-defined name for the new namespace. It must adhere to the hoon te
Note: The "sys" namespace is reserved for system use.
**`<as-of-time>`**
Timestamp of namespace creation. Defaults to NOW (current time). When specified timestamp must be greater than latest system timestamp for the database.
Timestamp of namespace creation. Defaults to NOW (current time). When specified timestamp must be greater than both the latest database schema and content timestamps.
### Remarks
## Remarks
This command mutates the state of the Obelisk agent.
## Produced Metadata
### Produced Metadata
system timestamp
Schema timestamp (labelled 'system time')
## Exceptions
### Exceptions
"duplicate key: {<key>}" namespace already exists
`<as-of-time>` less than latests system timestamp
schema changes must be by local agent
database `<database>` does not exist
namespace `<namespace>` as-of schema time out of order
namespace `<namespace>` as-of content time out of order
namespace `<namespace>` already exists
create namespace state change after query in script
### Example
`CREATE NAMESPACE my-namespace`
## ALTER NAMESPACE
*supported in urQL parser, not yet supported in Obelisk*
# ALTER NAMESPACE
Transfer an existing user `<table>` or `<view>` to another `<namespace>`.
```
<alter-namespace> ::=
ALTER NAMESPACE [ <database>. ]<namespace>
ALTER NAMESPACE [ <database>. ] <namespace>
TRANSFER { TABLE | VIEW } [ <db-qualifer> ]{ <table> | <view> }
[ <as-of-time> ]
```
## API
### API
```
+$ alter-namespace
$: %alter-namespace
@ -59,11 +77,11 @@ Transfer an existing user `<table>` or `<view>` to another `<namespace>`.
object-type=object-type
target-namespace=@tas
target-name=@tas
as-of=(unit @da)
as-of=(unit as-of)
==
```
## Arguments
### Arguments
**`<namespace>`**
Name of the target namespace into which the object is to be transferred.
@ -75,32 +93,39 @@ Indicates the type of the target object.
Name of the object to be transferred to the target namespace.
**`<as-of-time>`**
Timestamp of namespace update. Defaults to NOW (current time). When specified timestamp must be greater than latest system timestamp for the database.
Timestamp of namespace update. Defaults to NOW (current time). When specified, the timestamp must be greater than both the latest database schema and content timestamps.
## Remarks
### 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`
### Produced Metadata
Schema timestamp (labelled 'system time')
## Exceptions
namespace does not exist
### Exceptions
schema changes must be by local agent
database `<database>` does not exist
namespace `<namespace>` as-of schema time out of order
namespace `<namespace>` as-of content time out of order
namespace `<namespace>` does not exist
alter namespace state change after query in script
`<table>` or `<view>` does not exist
`<as-of-time>` less than latests system timestamp
# DROP NAMESPACE
Deletes a `<namespace>` and all its associated objects.
## DROP NAMESPACE
*supported in urQL parser, not yet supported in Obelisk*
Deletes a `<namespace>` and all its associated objects when `FORCE` specified.
```
<drop-namespace> ::=
DROP NAMESPACE [ FORCE ] [ <database>. ]<namespace>
DROP NAMESPACE [ FORCE ] [ <database>. ] <namespace>
[ <as-of-time> ]
```
## API
### API
```
+$ drop-namespace
$:
@ -108,32 +133,38 @@ Deletes a `<namespace>` and all its associated objects.
database-name=@tas
name=@tas
force=?
as-of=(unit @da)
as-of=(unit as-of)
==
```
## Arguments
### Arguments
**`FORCE`**
Optionally, force deletion of `<namespace>`.
Optionally force deletion of `<namespace>`, dropping all objects associated with the namespace.
**`<namespace>`**
The name of `<namespace>` to delete.
**`<as-of-time>`**
Timestamp of namespace deletion. Defaults to NOW (current time). When specified timestamp must be greater than latest system timestamp for the database.
Timestamp of namespace deletion. Defaults to `NOW`` (current time). When specified timestamp must be greater than both the latest database schema and content timestamps.
### Remarks
## 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`.
### Produced Metadata
## Exceptions
`<namespace>` does not exist.
`<namespace>` has populated tables and FORCE was not specified.
`<as-of-time>` specified and not less than latest system timestamp for database.
Schema timestamp (labelled 'system time')
### Exceptions
schema changes must be by local agent
namespace `<namespace>` does not exist
namespace `<namespace>` as-of schema time out of order
namespace `<namespace>` as-of content time out of order
drop namespace state change after query in script
`<namespace>` has populated tables and `FORCE` was not specified.

View File

@ -1,8 +1,10 @@
# 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.
# DDL: Table
_NOTE_: Further investigation is needed to understand if there's a reason to specify foreign key names (see CREATE INDEX).
## CREATE TABLE
Creates a new table within the specified or default database.
`<table>`s are the source of indexed persistent `<table-sets>`s in Obelisk.
```
<create-table> ::=
@ -19,7 +21,7 @@ _NOTE_: Further investigation is needed to understand if there's a reason to spe
[ <as-of-time> ]
```
## API
### API
```
+$ create-table
$:
@ -29,99 +31,114 @@ _NOTE_: Further investigation is needed to understand if there's a reason to spe
clustered=?
pri-indx=(list ordered-column)
foreign-keys=(list foreign-key)
as-of=(unit @da)
as-of=(unit as-of)
==
```
## Arguments
### Arguments
Note: All names must adhere to the hoon term naming standard.
**`<table>`**
This is a user-defined name for the new table. It must adhere to the hoon term naming standard.
If not explicitly qualified, it defaults to the Obelisk agent's current database and the 'dbo' namespace..
This is a user-defined name for the new table.
If not explicitly qualified, it defaults to the Obelisk agent's current database and the 'dbo' namespace.
**`<column> <aura>`**
The list of user-defined column names and associated auras. Names must adhere to the hoon term naming standard.
For more details, refer to [01-preliminaries](01-preliminaries.md)
The list of user-defined column names and associated auras.
For more details on auras, refer to [01-preliminaries](01-preliminaries.md)
**`[ CLUSTERED | LOOK-UP ] ( <column> [ ,... n ]`**
These are column names in the required unique primary index. Defining the index as `LOOK-UP` is optional.
These are column names in the required unique primary index. `CLUSTERED` is the default.
*foreign keys supported in urQL parser, not yet supported in Obelisk*
**`<foreign-key> ( <column> [ ASC | DESC ] [ ,... n ]`**
This is a user-defined name for `<foreign-key>`. It must adhere to the hoon term naming standard.
This is a user-defined name for `<foreign-key>`.
This list comprises column names in the table for association with a foreign table along with sort ordering. Default is `ASC` (ascending).
Note: The Obelisk engine does not yet implement foreign keys.
**`<table> ( <column> [ ,... n ]`**
Referenced foreign `<table>` and columns. Count and associated column auras must match the specified columns from the new `<table>` and comprise a `UNIQUE` index on the referenced foreign `<table>`.
**`ON DELETE { NO ACTION | CASCADE | SET DEFAULT }`**
This argument specifies the action to be taken on the rows in the table that have a referential relationship when the referenced row is deleted from the foreign table.
* NO ACTION (default)
* `NO ACTION` (default)
The Obelisk agent raises an error and the delete action on the row in the parent foreign table is aborted.
* CASCADE
* `CASCADE`
Corresponding rows are deleted from the referencing table when that row is deleted from the parent foreign table.
* SET DEFAULT
* `SET DEFAULT`
All the values that make up the foreign key in the referencing row(s) are set to their bunt (default) values when the corresponding row in the parent foreign table is deleted.
The Obelisk agent raises an error if the parent foreign table has no entry with bunt values.
**`ON UPDATE { NO ACTION | CASCADE | SET DEFAULT }`**
This argument specifies the action to be taken on the rows in the table that have a referential relationship when the referenced row is updated in the foreign table.
* NO ACTION (default)
* `NO ACTION` (default)
The Database Engine raises an error and the update action on the row in the parent table is aborted.
* CASCADE
* `CASCADE`
Corresponding rows are updated in the referencing table when that row is updated in the parent table.
* SET DEFAULT
* `SET DEFAULT`
All the values that make up the foreign key in the referencing row(s) are set to their bunt (default) values when the corresponding row in the parent foreign table is updated.
The Obelisk agent raises an error if the parent foreign table has no entry with bunt values.
**`<as-of-time>`**
Timestamp of table creation. Defaults to NOW (current time). When specified timestamp must be greater than system timestamp for the database.
Timestamp of table creation. Defaults to `NOW` (current time). When specified, the timestamp must be greater than both the latest database schema and content timestamps.
### Remarks
## Remarks
This command mutates the state of the Obelisk agent.
`PRIMARY KEY` must be unique.
`FOREIGN KEY` constraints ensure data integrity for the data contained in the column or columns. They necessitate that each value in the column exists in the corresponding referenced column or columns in the referenced table. `FOREIGN KEY` constraints can only reference columns that are subject to a `PRIMARY KEY` or `UNIQUE INDEX` constraint in the referenced table.
NOTE: The specific definition of `CLUSTERED` in Hoon, possibly an ordered map, is to be determined during development.
### Produced Metadata
## Produced Metadata
Schema timestamp (labelled 'system time')
## Exceptions
Content timestamp (labelled 'data time')
name within namespace already exists for table
table referenced by FOREIGN KEY does not exist
table column referenced by FOREIGN KEY does not exist
aura mis-match in FOREIGN KEY
`<as-of-time>` timestamp prior to database creation
### Exceptions
## Example
table must be created by local agent
database `<database>` does not exist
table `<table>` as-of schema time out of order
table `<table>`as-of data time out of order
namespace `<namespace>` does not exist
duplicate column names `<columns>`
duplicate column names in key `<columns>`
key column not in column definitions `<pri-indx>`
`<table>` exists in `<namespace>`
`<table>` referenced by `FOREIGN KEY` does not exist
`<table-column>` column referenced by `FOREIGN KEY` does not exist
aura mis-match in `FOREIGN KEY`
create table state change after query in script
### Example
```
CREATE TABLE order-detail
(invoice-nbr @ud, line-item @ud, product-id @ud, special-offer-id @ud, message @t)
(invoice-nbr @ud, line-item @ud, product-id @ud, special-offer-id @ud, message @t)
PRIMARY KEY CLUSTERED (invoice-nbr, line-item)
FOREIGN KEY fk-special-offer-order-detail (product-id, specialoffer-id)
REFERENCES special-offer (product-id, special-offer-id)
```
# ALTER TABLE
## ALTER TABLE
*supported in urQL parser, not yet supported in Obelisk*
Modify the columns and/or `<foreign-key>`s of an existing `<table>`.
(Available in the urQL parser. Not currently implemented in the Obelisk DB engine.)
```
<alter-> ::=
@ -144,7 +161,7 @@ ALTER TABLE my-table
DROP FOREIGN KEY fk-1, fk-2
```
## API
### API
```
+$ alter-table
$:
@ -155,11 +172,13 @@ DROP FOREIGN KEY fk-1, fk-2
drop-columns=(list @tas)
add-foreign-keys=(list foreign-key)
drop-foreign-keys=(list @tas)
as-of=(unit @da)
as-of=(unit as-of)
==
```
## Arguments
### Arguments
Note: All names must adhere to the hoon term naming standard.
**`<table>`**
Name of `<table>` to alter.
@ -167,19 +186,17 @@ Name of `<table>` to alter.
**`ADD | ALTER COLUMN ( <column> <aura> [ ,... n ] )`**
Denotes a list of user-defined column names and associated auras. `ALTER` is used to change the aura of an existing column.
Names must follow the Hoon term naming standard. See [ref-ch02-types](ref-ch02-types.md)
**`DROP COLUMN ( <column> [ ,... n ] )`**
Denotes a list of existing column names to delete from the `<table>` structure.
**`[ NONCLUSTERED | CLUSTERED ] ( <column> [ ,... n ]`**
These are column names in the required unique primary index. Defining the index as `CLUSTERED` is optional.
**`[ CLUSTERED | LOOK-UP ] ( <column> [ ,... n ]`**
These are column names in the required unique primary index. `CLUSTERED` is the default.
**`ADD | DROP`**
The action is to add or drop a foreign key.
**`<foreign-key> ( <column> [ ASC | DESC ] [ ,... n ]`**
This is a user-defined name for `<foreign-key>`. It must adhere to the hoon term naming standard.
This is a user-defined name for `<foreign-key>`.
This list comprises column names in the table for association with a foreign table along with sort ordering. Default is `ASC` (ascending).
**`<table> ( <column> [ ,... n ]`**
@ -188,16 +205,13 @@ Referenced foreign `<table>` and columns. Count and associated column auras must
**`ON DELETE { NO ACTION | CASCADE | SET DEFAULT }`**
This argument specifies the action to be taken on the rows in the table that have a referential relationship when the referenced row is deleted from the foreign table.
* NO ACTION (default)
* `NO ACTION` (default)
The Obelisk agent raises an error and the delete action on the row in the parent foreign table is aborted.
* CASCADE
* `CASCADE`
Corresponding rows are deleted from the referencing table when that row is deleted from the parent foreign table.
* SET DEFAULT
* `SET DEFAULT`
All the values that make up the foreign key in the referencing row(s) are set to their bunt (default) values when the corresponding row in the parent foreign table is deleted.
The Obelisk agent raises an error if the parent foreign table has no entry with bunt values.
@ -205,45 +219,49 @@ The Obelisk agent raises an error if the parent foreign table has no entry with
**`ON UPDATE { NO ACTION | CASCADE | SET DEFAULT }`**
This argument specifies the action to be taken on the rows in the table that have a referential relationship when the referenced row is updated in the foreign table.
* NO ACTION (default)
* `NO ACTION` (default)
The Database Engine raises an error and the update action on the row in the parent table is aborted.
* CASCADE
* `CASCADE`
Corresponding rows are updated in the referencing table when that row is updated in the parent table.
* SET DEFAULT
* `SET DEFAULT`
All the values that make up the foreign key in the referencing row(s) are set to their bunt (default) values when the corresponding row in the parent foreign table is updated.
The Obelisk agent raises an error if the parent foreign table has no entry with bunt values.
**`<as-of-time>`**
Timestamp of table aleration. Defaults to NOW (current time). When specified timestamp must be greater than latest database system timestamp and greater than the latest data timestamp for the table.
Timestamp of table alteration. Defaults to `NOW` (current time). When specified, the timestamp must be greater than both the latest database schema and content timestamps.
### Remarks
## Remarks
This command mutates the state of the Obelisk agent.
`FOREIGN KEY` constraints ensure data integrity for the data contained in the column or columns. They necessitate that each value in the column exists in the corresponding referenced column or columns in the referenced table. `FOREIGN KEY` constraints can only reference columns that are subject to a `PRIMARY KEY` or `UNIQUE INDEX` constraint in the referenced table.
## Produced Metadata
update `<database>.sys.table-columns`
update `<database>.sys.table-columns`
update `<database>.sys.table-ref-integrity`
### Produced Metadata
## Exceptions
Schema timestamp (labelled 'system time')
### Exceptions
table must be altered by local agent
database `<database>` does not exist
`<table>` does not exists in `<namespace>`
alter a column that does not exist
add a column that does exist
drop a column that does not exist
table referenced by FOREIGN KEY does not exist
table column referenced by FOREIGN KEY does not exist
aura mis-match in FOREIGN KEY
`<as-of-time>` timestamp prior to latest system timestamp for table
`<table>` referenced by `FOREIGN KEY` does not exist
`<table-column>` column referenced by `FOREIGN KEY` does not exist
aura mis-match in `FOREIGN KEY`
alter table `<table>` as-of schema time out of order
alter table `<table>`as-of data time out of order
alter table state change after query in script
# DROP TABLE
Deletes a `<table>` and all associated objects
## DROP TABLE
Deletes a `<table>` and all associated objects.
```
<drop-table> ::=
@ -251,43 +269,51 @@ Deletes a `<table>` and all associated objects
[ <as-of-time> ]
```
## API
### API
```
+$ drop-table
$:
%drop-table
table=qualified-object
force=?
as-of=(unit @da)
as-of=(unit as-of)
==
```
## Arguments
### Arguments
**`FORCE`**
Optionally, force deletion of a table.
Optionally force deletion of table when table is populated, used in a view, or used in a foreign key.
**`<table>`**
Name of `<table>` to delete.
**`<as-of-time>`**
Timestamp of table deletion. Defaults to NOW (current time). When specified timestamp must be greater than latest database system timestamp and greater than the latest data timestamp for the table.
Timestamp of table deletion. Defaults to `NOW` (current time). When specified, the timestamp must be greater than both the latest database schema and content timestamps.
### Remarks
## Remarks
This command mutates the state of the Obelisk agent.
Cannot drop if used in a view or foreign key, unless `FORCE` is specified, resulting in cascading object drops.
Cannot drop if used in a view or foreign key, unless `FORCE` is specified, resulting in cascading object drops. Affected views and foreign keys dropped.
Cannot drop when the `<table>` is populated unless `FORCE` is specified.
## Produced Metadata
DELETE from `<database>.sys.tables`.
DELETE from `<database>.sys.views`.
DELETE from `<database>.sys.indices`.
### Produced Metadata
## Exceptions
`<table>` does not exist.
`<table>` is populated and FORCE was not specified.
`<table>` used in `<view>` and FORCE was not specified.
`<table>` used in `<foreign-key>` and FORCE was not specified.
`<as-of-time>` `<timestamp>` prior to latest system timestamp `<timestamp>`.
Schema timestamp (labelled 'system time')
Content timestamp (labelled 'data time'), if the table was populated
### Exceptions
table must be dropped by local agent
database `<database>` does not exist
table `<table>` as-of schema time out of order
table `<table>`as-of data time out of order
namespace `<namespace>` does not exist
drop table state change after query in script
drop table `<table>` does not exist in `<namespace>`
drop table `<table>` has data, use `FORCE` to `DROP`
drop table `<table>` used in `<view>`, use `FORCE` to `DROP`
drop table `<table>` used in `<foreign-key>`, use `FORCE` to `DROP`

View File

@ -1,88 +1,102 @@
(currently supported in urQL parser, likely to be revised, not yet supported in Obelisk)
# DDL: Index
*supported in urQL parser, not yet supported in Obelisk*
# CREATE INDEX
This command creates an index over selected column(s) of an existing table.
## CREATE INDEX
This command creates an index over selected columns of an existing table.
### AST
```
<create-index> ::=
CREATE [ UNIQUE ] [ LOOK-UP | CLUSTERED ] INDEX <index>
CREATE [ UNIQUE ] [ CLUSTERED | LOOK-UP ] INDEX <index>
ON [ <db-qualifer> ] <table>
( <column> [ ASC | DESC ] [ ,...n ] )
[ <as-of-time> ]
```
## Examples
### Examples
```
CREATE INDEX ix_vendor-id ON product-vendor (vendor-id);
CREATE UNIQUE INDEX ix_vendor-id2 ON dbo.product-vendor
CREATE INDEX ix-vendor-id ON product-vendor (vendor-id);
CREATE UNIQUE INDEX ix-vendor-id2 ON dbo.product-vendor
(vendor-id DESC, name ASC, address DESC);
CREATE INDEX ix_vendor-id3 ON purchasing..product-vendor (vendor-id);
CREATE INDEX ix-vendor-id3 ON purchasing..product-vendor (vendor-id);
```
## API
### API
```
+$ create-index
$:
%create-index
name=@t
object-name=qualified-object :: because index can be over table or view
object-name=qualified-object
is-unique=?
is-clustered=?
columns=(list ordered-column)
==
```
## Arguments
### Arguments
**`UNIQUE`**
Specifies that no two rows are permitted to have the same index key value.
**`LOOK-UP | CLUSTERED`**
`CLUSTERED` creates an index in which the logical order of the key values determines the physical order of the corresponding rows in a table. A `<table>` or `<view>` can have only one clustered index at a time.
**`[ CLUSTERED | LOOK-UP ]`**
`CLUSTERED` is the default.
**`<index>`**
User-defined name for the new index. This name must follow the Hoon term naming standard.
User-defined name for the new index. This name must follow the Hoon term naming standard. Index names are unique within tables.
**`<table>`**
**`[ <db-qualifer> ] <table>`**
Name of existing table the index targets.
If not explicitly qualified, defaults to the Obelisk agent's current database and 'dbo' namespace.
**`<column> [ ASC | DESC ] [ ,...n ] `**
List of column names in the target table. This list represents the sort hierarchy and optionally specifies the sort direction for each level. The default sorting is `ASC` (ascending).
## Remarks
**`<as-of-time>`**
Timestamp of index creation. Defaults to `NOW` (current time). When specified, the timestamp must be greater than both the latest database schema and content timestamps.
### Remarks
This command mutates the state of the Obelisk agent.
Index names cannot start with 'pk-' or 'fk-' as these prefixes are reserved for primary keys and foreign keys respectively.
### Produced Metadata
_NOTE_: Further investigation is required to determine how "clustering" works in Hoon.
Schema timestamp (labelled 'system time')
## Produced Metadata
## Example
INSERT `table name`, `namespace` `index-name`, `LOOK-UP | CLUSTERED`, `is-unique`, `<timestamp>` into `<database>.sys.indices`
## Exceptions
### Exceptions
index must be created by local agent
index name already exists for table
database `<database>` does not exist
table does not exist
column does not exist
create index `<index>` as-of schema time out of order
create index `<index>`as-of data time out of order
UNIQUE specified and existing values are not unique for the column(s) specified
index name begins with 'pk-' or 'fk-'
create index state change after query in script
### Example
*missing*
## ALTER INDEX
*supported in urQL parser, not yet supported in Obelisk*
# ALTER INDEX
Modifies the structure of an existing `<index>` on a user `<table>` or `<view>`.
```
<alter-index> ::=
ALTER [ UNIQUE ] [ NONCLUSTERED | CLUSTERED ] INDEX [ <db-qualifer> ]<index>
ON { <table> | <view> }
ALTER [ UNIQUE ] [ CLUSTERED | LOOK-UP ] INDEX <index>
ON [ <db-qualifer> ] <table>
[ ( <column> [ ASC | DESC ] [ ,...n ] ) ]
{ DISABLE | RESUME}
[ <as-of-time> ]
```
## API
### API
```
+$ alter-index
$:
@ -94,18 +108,18 @@ Modifies the structure of an existing `<index>` on a user `<table>` or `<view>`.
==
```
## Arguments
### Arguments
**`UNIQUE`**
Specifies that no two rows are permitted to have the same index key value.
**`NONCLUSTERED | CLUSTERED`**
`CLUSTERED` creates an index in which the logical order of the key values determines the physical order of the corresponding rows in a table. A `<table>` or `<view>` can have only one clustered index at a time.
**`[ CLUSTERED | LOOK-UP ]`**
`CLUSTERED` is the default.
**`[ <db-qualifer> ]<index>`**
**`<index>`**
Specifies the target index.
**`<table> | <view>`**
**`[ <db-qualifer> ] <table>`**
Name of the underlying object of the index.
**`<column> [ ASC | DESC ] [ ,...n ] `**
@ -114,34 +128,51 @@ List of column names in the target table. This list represents the sort hierarch
**`DISABLE | RESUME`**
Used to disable an active index or resume a disabled index.
## Remarks
**`<as-of-time>`**
Timestamp of index alteration. Defaults to `NOW` (current time). When specified, the timestamp must be greater than both the latest database schema and content timestamps.
### Remarks
This command mutates the state of the Obelisk agent.
Cannot alter primary key and foreign key indices.
`RESUME` will rebuild the index if the underlying object is dirty.
Note: Further investigation into hoon ordered maps is needed to determine what exactly "clustered" means in hoon.
### Produced Metadata
## Produced Metadata
update `<database>.sys.indices`
Schema timestamp (labelled 'system time')
## Exceptions
### Exceptions
index must be altered by local agent
index name does not exist for table
database `<database>` does not exist
table does not exist
column does not exist
alter index `<index>` as-of schema time out of order
alter index `<index>`as-of data time out of order
UNIQUE specified and existing values are not unique for the column(s) specified
alter index state change after query in script
### Example
*missing*
## DROP INDEX
*supported in urQL parser, not yet supported in Obelisk*
# DROP INDEX
Deletes an existing `<index>`.
```
<drop-index> ::=
DROP INDEX <index>
ON [ <db-qualifer> ] { <table> | <view> }
ON [ <db-qualifer> ] <table>
[ <as-of-time> ]
```
## API
### API
```
+$ drop-index
$:
@ -151,29 +182,39 @@ Deletes an existing `<index>`.
==
```
## Arguments
### Arguments
**`<index>`**
The name of the index to delete.
**`<table> | <view>`**
**`[ <db-qualifer> ] <table>`**
`<table>` or `<view>` with the named index.
**`<as-of-time>`**
Timestamp of dropping index. Defaults to `NOW` (current time). When specified, the timestamp must be greater than both the latest database schema and content timestamps.
### Remarks
## Remarks
This command mutates the state of the Obelisk agent.
Indexes with names that begin with "pk-" cannot be dropped, as these are table primary keys.
This command can be used to delete a `<foreign-key>`.
If `<view>` is shadowing `<table>`, the system attempts to find `<index>` on `<view>` first, then `<table>`.
## Produced Metadata
### Produced Metadata
DELETE FROM `<database>.sys.indices`
DELETE FROM `<database>.sys.table-ref-integrity`
Schema timestamp (labelled 'system time')
## Exceptions
`<table>` or `<view>` does not exist
`<index>` does not exist on `<table>` or `<view>`.
### Exceptions
index must be dropped by local agent
index name does not exist for table
database `<database>` does not exist
table does not exist
drop index `<index>` as-of schema time out of order
drop index `<index>`as-of data time out of order
drop index state change after query in script
### Example
*missing*

View File

@ -1,10 +1,10 @@
# INSERT
Inserts rows into a `<table-set>`.
Inserts rows into a `<table>`.
```
<insert> ::=
INSERT INTO <table-set>
INSERT INTO <table>
[ ( <column> [ ,...n ] ) ]
{ VALUES (<scalar-expression> [ ,...n ] ) [ ...n ]
| <transform> }
@ -17,9 +17,7 @@ Inserts rows into a `<table-set>`.
| TBD }
```
Currently only constants are supported as `VALUES`.
## API
### API
```
+$ insert
$:
@ -27,51 +25,69 @@ Currently only constants are supported as `VALUES`.
table=qualified-object
columns=(unit (list @t))
values=insert-values
as-of=(unit as-of)
==
```
## Arguments
### Arguments
**`<table-set>`**
**`<table>`**
The target of the `INSERT` operation.
**`<column>` [ ,...n ]**
When present, the column list must account for all column identifiers (names or aliases) in the target once. It determines the order in which update values are applied and the output `<table-set>`'s column order.
When present, the column list must account for all column identifiers (names or aliases) in the target once. It determines the order in which the update values are applied and the output `<table>`'s column order.
**(`<scalar-expression>` [ ,...n ] ) [ ,...n ]**
*fully supported in urQL parser, only literals supported in Obelisk*
Row(s) of literal values to insert into target. Source auras must match target columnwise.
**`<transform>`**
*transform supported in urQL parser, not yet supported in Obelisk*
Transform creating source `<table-set>` to insert into target. Source auras must match target columnwise.
## Remarks
(Transform is a wrapper for query.)
When `<table-set>` is a `<table>` the command potentially mutates `<table>`, resulting in a state change of the Obelisk agent.
**`<as-of-time>`**
Timestamp of table creation. Defaults to `NOW` (current time). When specified, the timestamp must be greater than both the latest database schema and content timestamps.
When `INSERT` operates on a `<table>`, it must be in the terminal (last) step of a `<transform>` or a stand-alone `INSERT`.
### Remarks
Data in the *sys* namespace cannot be inserted into.
This command mutates the state of the Obelisk agent.
When `<table-set>` is a virtual table, the command produces an output `<table-set>` which may be consumed as a pass-thru by a subsequent `<transform>` step.
The `VALUES` or `<query>` must provide data for all columns in the expected order.
The `VALUES` or `<transform>` must provide data for all columns in the expected order.
Cord values are represented in single quotes `'this is a cord'`. Single quotes within cord values must be escaped with double backslash as `'this is a cor\\'d'`.
If `( <column> [ ,...n ] )` is not specified, the inserted columns must be arranged in the same order as the target `<table-set>`.
When the target `<table-set>` is a `<table>`, the input `<row-type>` must match the `<table>` `<row-type>`.
When target `<table-set>` is not a `<table>` and the input is from a `<transform>` then the target `<table-set>` and `<transform>` `<table-set>` must have the same all-column `<row-type>`. New `<row-type>` sub-types may be introduced.
If `( <column> [ ,...n ] )` is not specified, the inserted columns must be arranged in the same order as the target `<table>` columns.
Note that multiple parentheses enclosed rows of column values are NOT comma separated.
## Produced Metadata
### Produced Metadata
`@@ROWCOUNT` returns the total number of rows inserted
Row count
Content timestamp (labelled 'data time')
## Exceptions
`<table>` does not exist
### Exceptions
insert state change after query in script
database `<database>` does not exist
insert into table `<table>` as-of data time out of order
insert into table `<table>` as-of schema time out of order
table `<namespace>`.`<table>` does not exist
insert invalid column: `<columns>`
aura mismatch in value
cannot add duplicate key: `<row-key>`
`GRANT` permission on `<table>` violated
unique key violation
colum misalignment
## Example
```
INSERT INTO reference.species-vital-signs-ranges
(species, temp-low, temp-high, heart-rate-low, heart-rate-high, respiratory-rate-low, respiratory-rate-high)
VALUES
('Dog', .99.5, .102.5, 60, 140, 10, 35)
('Cat', .99.5, .102.5, 140, 220, 20, 30)
('Rabbit', .100.5, .103.5, 120, 150, 30, 60);
```

View File

@ -1,17 +1,17 @@
# UPDATE
(currently supported in urQL parser, not yet supported in Obelisk)
*supported in urQL parser, not yet supported in Obelisk*
Changes content of selected columns in existing rows of a `<table-set>`.
```
<update> ::=
UPDATE [ <ship-qualifier> ] <table-set>
UPDATE [ <ship-qualifier> ] <table>
SET { <column> = <scalar-expression> } [ ,...n ]
[ WHERE <predicate> ]
[ <as-of-time> ]
```
## API
### API
```
+$ update
$:
@ -20,40 +20,44 @@ Changes content of selected columns in existing rows of a `<table-set>`.
columns=(list @t)
values=(list value-or-default)
predicate=(unit predicate)
as-of=(unit as-of)
==
```
## Arguments
### Arguments
**`<table-set>`**
**`<table>`**
The target of the `UPDATE` operation.
**`<column>` = `<scalar-expression>`**
`<column>` is a column name or alias of a target column. `<scalar-expression>` is a valid expression within the statement context.
**`<scalar-expression>`**
`<scalar-expression>` is a valid expression within the statement context.
**`<predicate>`**
Any valid `<predicate>`, including predicates on CTEs.
## Remarks
**`<as-of-time>`**
Timestamp of table creation. Defaults to `NOW` (current time). When specified, the timestamp must be greater than both the latest database schema and content timestamps.
When `<table-set>` is a `<table>`, the command potentially mutates the data within `<table>`, resulting in a state change of the Obelisk agent.
### Remarks
A stand-alone `UPDATE` statement can only operate on a `<table>`, producing a `<transform>` of one command step with no CTEs.
This command mutates the state of the Obelisk agent.
Data in the *sys* namespace cannot be updated.
When `<table-set>` is a virtual table, the command produces an output `<table-set>` which may be consumed as a pass-thru by a subsequent `<transform>` step.
Cord literal values are represented in single quotes 'this is a cord'. Single quotes within cord values must be escaped with double backslash as `'this is a cor\\'d'`.
The `VALUES` or `<query>` must provide data for all columns in the expected order.
### Produced Metadata
Cord values are represented in single quotes 'this is a cord'. Single quotes within cord values must be escaped with double backslash as `'this is a cor\\'d'`.
Row count
Content timestamp (labelled 'data time')
## Produced Metadata
### Exceptions
`@@ROWCOUNT` returns the total number of rows updated
## Exceptions
`<table>` does not exist
update state change after query in script
database `<database>` does not exist
update into table `<table>` as-of data time out of order
update into table `<table>` as-of schema time out of order
table `<namespace>`.`<table>` does not exist
update invalid column: `<columns>`
aura mismatch on `SET`
`GRANT` permission on `<table>` violated
unique key violation
aura mismatch on `SET`

View File

@ -1,46 +1,53 @@
# DELETE
(currently supported in urQL parser, not yet supported in Obelisk)
*supported in urQL parser, not yet supported in Obelisk*
Deletes rows from a `<table-set>`.
```
<delete> ::=
DELETE [ FROM ] <table-set>
[ WHERE <predicate> ]
DELETE [ FROM ] <table>
[ WHERE <predicate> ]
[ <as-of-time> ]
```
## API
### API
```
+$ delete
$:
%delete
table=qualified-object
predicate=(unit predicate)
as-of=(unit as-of)
==
```
## Arguments
### Arguments
**`<table-set>`**
**`<table>`**
The target of the `DELETE` operation.
**`<predicate>`**
Any valid `<predicate>`, including predicates on CTEs.
## Remarks
**`<as-of-time>`**
Timestamp of table creation. Defaults to `NOW` (current time). When specified, the timestamp must be greater than both the latest database schema and content timestamps.
When `<table-set>` is a `<table>`, the command potentially mutates `<table>` resulting in a state change of the Obelisk agent.
### Remarks
A stand-alone `DELETE` statement can only operate on a `<table>` and produces a `<transform>` of one command step.
This command mutates the state of the Obelisk agent.
Data in the *sys* namespace cannot be deleted.
When `<table-set>` is a virtual table, the command produces an output `<table-set>` which may be consumed as a pass-thru by a subsequent `<transform>` step.
### Produced Metadata
## Produced Metadata
Row count
Content timestamp (labelled 'data time')
@@ROWCOUNT returns the total number of rows deleted
### Exceptions
## Exceptions
`<table>` does not exist
delete state change after query in script
database `<database>` does not exist
delete from table `<table>` as-of data time out of order
delete from table `<table>` as-of schema time out of order
table `<namespace>`.`<table>` does not exist
delete invalid predicate: `<predicate>`
`GRANT` permission on `<table>` violated

View File

@ -1,5 +1,5 @@
# TRUNCATE TABLE
(currently supported in urQL parser, not yet supported in Obelisk)
*supported in urQL parser, not yet supported in Obelisk*
Removes all rows in a base table.
@ -9,30 +9,40 @@ Removes all rows in a base table.
[ <as-of-time> ]
```
## API
### API
```
+$ truncate-table
$:
%truncate-table
table=qualified-object
as-of=(unit as-of)
==
```
## Arguments
### Arguments
**`<table>`**
The target table.
## Remarks
**`<as-of-time>`**
Timestamp of table creation. Defaults to `NOW` (current time). When specified, the timestamp must be greater than both the latest database schema and content timestamps.
### Remarks
The command potentially mutates `<table>`, resulting in a state change of the Obelisk agent.
Tables in the *sys* namespace cannot be truncated.
## Produced Metadata
### Produced Metadata
none
Row count
Content timestamp (labelled 'data time')
## Exceptions
`<table>` does not exist
### Exceptions
truncate table state change after query in script
database `<database>` does not exist
truncate table `<table>` as-of data time out of order
truncate table `<table>` as-of schema time out of order
table `<namespace>`.`<table>` does not exist
`GRANT` permission on `<table>` violated

View File

@ -1,6 +1,6 @@
(currently supported in urQL parser, likely to be revised, under development in Obelisk)
# QUERY
*supported in urQL parser, partially supported and under development in Obelisk*
The `<query>` statement provides a means to create `<table-set>`s derived from persisted and/or cached `<table-set>`s and/or constants. Data rows can be joined based on predicates, specific columns can be selected, and the resulting rows can be filtered by predicate.
```
@ -13,7 +13,6 @@ The `<query>` statement provides a means to create `<table-set>`s derived from p
} [ ...n ]
| CROSS JOIN <table-set> [ [AS] <alias> ]
]
[ WHERE <predicate> ]
[ GROUP BY { <qualified-column>
| <column-alias>
@ -44,7 +43,7 @@ Cross database joins are permitted, but not cross ship joins.
`HAVING <predicate>` filters aggregated rows returned from the `<query>`. The column references in the predicate must be either one of the grouping columns or be contained in an aggregate function.
Avoid using `ORDER BY` in CTEs or in any query prior to the last step in a `<transform>`, unless required by `TOP` or `BOTTOM` specified in the `SELECT` statement or, in the case of CTEs, it is used in an `<expression>` expecting a scalar result.
Avoid using `ORDER BY` in CTEs or in any query prior to the last step in a `<transform>`, unless required by `TOP` or `BOTTOM` specified in the `SELECT` statement.
```
<predicate> ::=
@ -65,12 +64,12 @@ Avoid using `ORDER BY` in CTEs or in any query prior to the last step in a `<tra
| expression [ NOT ] BETWEEN expression [ AND ] expression
| [ NOT ] EXISTS { <column value> | <scalar-query> } }
```
*BETWEEN ... AND ... is not yet implemented in the urQL parser*
When applied to a column `EXISTS` tests whether the returned `<row-type>` includes the required column. In the case of `<scalar-query>`, it tests whether a CTE returns any rows.
`[ NOT ] EQUIV` is a binary operator, similar to (not) equals `<>`, `=`. However, comparing two `NOT EXISTS` yields true.
`<scalar-query>` is a CTE that selects for one column. Depending on whether the operator expects a set or a value, it operates on the entire result set or on the first row returned, respectively. If the CTE is not ordered, results may be unpredictable.
`<scalar-query>` is a CTE that selects for one column. Depending on whether the operator expects a set or a value, it operates on the entire result set or on the first row returned, respectively.
```
<binary-operator> ::=
@ -89,6 +88,7 @@ Whitespace is not required between operands and binary-operators, except when th
| <aggregate-function>( { <column> | <scalar> } )
}
```
*<aggregate-function> is not yet implemente in the urQL parser*
`<scalar-query>` is a CTE that returns only one column. The first returned value is accepted and subsequent values ignored. Ordering the CTE may be required for predictable results.
```
@ -103,7 +103,7 @@ Whitespace is not required between operands and binary-operators, except when th
[ [ <ship-qualifier> ]<table-view> | <alias> ].<column-name>
```
## API
### API
```
+$ query
$:
@ -118,7 +118,7 @@ Whitespace is not required between operands and binary-operators, except when th
==
```
## Arguments
### Arguments
**`<table-set> [ [AS] <alias> ]`**
Any valid `<table-set>`.
@ -131,22 +131,30 @@ Used to select columns for ordering and grouping. `<column-ordinal>`s are 1-base
**`[ TOP <n> ] [ BOTTOM <n> ]`**
`SELECT` only the first and/or last `n` rows returned by the rest of the query. If the result set is less than `n`, the entire set of rows is returned.
Selects only the first and/or last `n` rows returned by the rest of the query. If the result set is less than `n`, the entire set of rows is returned.
`TOP` and `BOTTOM` require the presence of an `ORDER BY` clause.
## Remarks
### Remarks
The `SELECT` clause may choose columns from a single CTE, in which case the `FROM` clause is absent. It may also choose only constants and `SCALAR` functions on constants, in which case it returns a result set of one row.
The `SELECT` clause may choose columns from a single CTE, in which case the `FROM` clause is absent. It may also choose only literal constants and `SCALAR` functions on literals, columns, or scalar queries, in which case it will return a result set of one row.
The simplest possible query is `SELECT 0`.
`<query>` alone does not change the Obelisk agent state.
## Produced Metadata
*as-of-time currently missing from specification*
`@@ROWCOUNT` returns the total number of rows returned.
### Produced Metadata
## Exceptions
Row count
Provided `<query>` attempts execution (i.e., syntax and internal consistency checks pass), the only exceptions possible are performance-related, such as timeouts and memory constraints.
### Exceptions
`TOP` or `BOTTOM` specified without `ORDER BY` clause.
Provided `<query>` parses and passes internal consistency checks, the only other exceptions possible are performance-related, such as timeouts and memory constraints.
### Example
*missing*

View File

@ -1,6 +1,6 @@
(currently supported in urQL parser, likely to be revised, may or may not be implemented in Obelisk)
# MERGE
*supported in urQL parser, not yet supported in Obelisk*
*some experimental stuff proposed here, take with a grain of salt*
`MERGE` is a statement that conditionally performs `INSERT`, `UPDATE`, or `DELETE` operations. It modifies the content of the `<target-table>`, merging data from the `<source-table>` and static `<common-table-expression>` sources.
@ -41,12 +41,7 @@ If the resulting virtual-table row type is a union type, then the output must be
THEN <merge-not-matched> ] [ ...n ]
[ WHEN NOT MATCHED BY SOURCE [ AND <unmatched-source-predicate> ]
THEN <merge-matched> ] [ ...n ]
[ AS OF { NOW
| <timestamp>
| n { SECONDS | MINUTES | HOURS | DAYS | WEEKS | MONTHS | YEARS } AGO
| <inline-scalar>
}
]
[ <as-of-time> ]
```
```
@ -106,8 +101,7 @@ The count out `INSERT` columns and `VALUES` must match.
No operation performed.
## API
### API
```
+$ merge
$:
@ -119,10 +113,11 @@ No operation performed.
matched=(list matching)
unmatched-by-target=(list matching)
unmatched-by-source=(list matching)
as-of=(unit as-of)
==
```
## Arguments
### Arguments
**`[ { INTO | FROM } ] <target-table> [ [ AS ] <alias> ]`**
@ -199,7 +194,7 @@ If there is no unconditional `<merge-not-matched>` action, it is the same as spe
**`WHEN NOT MATCHED BY SOURCE [ AND <unmatched-source-predicate> ] THEN <merge-matched>`**
Specifies that all rows of `<arget-table>`, which don't match the rows returned by `<table-source>` ON `<merge-predicate>`, and that satisfy any additional search condition, are updated or deleted according to the `<merge-matched>` clause.
Specifies that all rows of `<target-table>`, which don't match the rows returned by `<table-source>` ON `<merge-predicate>`, and that satisfy any additional search condition, are updated or deleted according to the `<merge-matched>` clause.
`WHEN NOT MATCHED BY SOURCE` clause without `AND <unmatched-source-predicate>` implies unconditionally apply the `<merge-matched>` action.
@ -211,7 +206,7 @@ If there is no unconditional `<merge-matched>` action, it is the same as specify
When no rows are returned by `<table-source>`, columns in the source table can't be accessed, and therefore the `<merge-matched>` action cannot reference columns in `<table-source>`.
## Remarks
### Remarks
When `<target-table>` is updated in place or `<new-table>` specified as a base `<table>`, the command potentially results in a state change of the Obelisk agent.
@ -225,15 +220,15 @@ At least one of the three `MATCHED` / `NOT MATCHED` clauses must be specified, b
`INSERT`, `UPDATE`, or `DELETE` actions specified on `<target-table>` are limited by any constraints defined on it (when it is a base `<table>`), including unique indices and any cascading referential integrity constraints.
It `<target-table>` is updated in place, or `<new-table>` created, every `INSERT` clause must account for all columns in `<target-table>`. Inserting fewer columns results in a new row sub-type, which is allowed when creating a virtual `<table-set>`.
It `<target-table>` is updated in place, or a `<new-table>` created, every `INSERT` clause must account for all columns in `<target-table>`. Inserting fewer columns results in a new row sub-type, which is allowed when creating a virtual `<table-set>`.
Any `<binary-operator>` referencing a column each from `<target-table>` and `<source-table>` satisfies the requirement that `ON <merge-predicate>` not produce a cartesian join. However, it is to be noted a cartestian join cannot be entirely prevented depending on column contents.
## Produced Metadata
### Produced Metadata
`@@ROWCOUNT` returns the total number of rows [inserted=@ud updated=@ud deleted=@ud].
## Exceptions
### Exceptions
`<target-table>` does not exist
`GRANT` permission on `<target-table>` violated
`<source-table>` does not exist

View File

@ -1,31 +1,38 @@
(currently supported in urQL parser, likely to be revised, not yet supported in Obelisk)
# Permissions
*supported in urQL parser, not yet supported in Obelisk*
# GRANT
Grants permission to read from and/or write to selected `<database>`, `<namespace>`, or `<table-object>` on host ship to selected foreign ships.
## GRANT
NOTE: There needs to be a security model over local desks, something along these lines:
1. Only the DB CREATE-ing desk can CREATE, ALTER, DROP, GRANT, REVOKE (see #7)
2. Default desk read DB permission by other local desks are opt-out
3. Default desk write to DB permission by other local desks are opt-in
4. Invert desk read permissions, making them opt-in
5. Invert desk write permissions, making them opt-out
6. `<database>` desk permissions apply to foreign ships otherwise granted permission
7. Any agent within the Obelisk desk (e.g. a human UI) has full permissions
Grants permission to selected foreign ships to read from and/or write to selected `<database>`, `<namespace>`, or `<table-object>` objects on host ship.
### Security Model
1. By default, any agent on the host ship can create and maintain databases and all objects and content therein.
2. No agent from a foreign ship can ever create a database or alter the schema of an existing database.
3. By default, no agent from a foreign ship has any rights on any database.
4. Granting and revoking rights are explained in the docs for their respective commands.
5. Granting and revoking is effective in real-time, outside the scope of `<as-of-time>`.
To Do:
1. Add agent to the security model.
2. Allow revoking of rights by on-ship agent. (for real security this has to be opt-in...do this in create database)
### AST
```
<grant> ::=
GRANT { ADMINREAD | READONLY | READWRITE }
TO { PARENT | SIBLINGS | MOONS | <@p> [ ,...n ] }
ON { DATABASE <database>
| NAMESPACE [<database>.]<namespace>
| [<db-qualifer>]<table-object>
| NAMESPACE [<database>.] <namespace>
| [<db-qualifer>] <table-object>
}
```
## Example
### Example
`GRANT READONLY TO ~sampel-palnet ON NAMESPACE my-namespace`
## API
### API
```
$:
%grant
@ -35,7 +42,7 @@ $:
==
```
## Arguments
### Arguments
**ADMINREAD**
Grants read permission on `<database>.sys` tables and views.
@ -68,7 +75,8 @@ Grant permissin on named namespace to all `<table>s` and `<view>`s.
**`[<db-qualifer>]<table-object>`**
Grant permission is on named object, whether is is a `<table>` or `<view>`.
## Remarks
### Remarks
This command mutates the state of the Obelisk agent.
Write permission includes `DELETE`, `INSERT`, and `UPDATE`.
@ -79,17 +87,20 @@ When a granted database object is dropped, all applicable `GRANT`s are also drop
In the case where a shadowing `<view>` is dropped, the grant then applies to the `<table>`. In the case where a new `<view>` shadows a granted `<table>`, the grant newly applies to the `<view>`.
## Produced Metadata
### Produced Metadata
INSERT grantee, grant, target, `<timestamp>` INTO `<database>.sys.grants`
## Exceptions
### Exceptions
`<database>` does not exist.
`<namespace>` does not exist.
`<table-object>` does not exist.
`GRANT` target type does not exist. (e.g. host is a `MOON` and `GRANT` is `ON MOONS`)
# REVOKE
## REVOKE
Revokes permission to read from and/or write to selected database objects on the host ship to selected foreign ships.
```
@ -97,13 +108,13 @@ Revokes permission to read from and/or write to selected database objects on the
REVOKE { ADMINREAD | READONLY | READWRITE | ALL }
FROM { PARENT | SIBLINGS | MOONS | ALL | <@p> [ ,...n ] }
ON { DATABASE <database>
| NAMESPACE [<database>.]<namespace>
| [<db-qualifer>]<table-object>
| NAMESPACE [<database>.] <namespace>
| [<db-qualifer>] <table-object>
}
```
## API
### API
```
+$ revoke
$:
@ -114,7 +125,7 @@ Revokes permission to read from and/or write to selected database objects on the
==
```
## Arguments
### Arguments
**ADMINREAD**
Revokes read permission on `<database>.sys` tables and views. The `ON` clause must be `<database>`.
@ -146,12 +157,14 @@ Revoke permissin on named namespace.
**`[<db-qualifer>]<table-object>`**
Revoke permission is on named object, whether it is a `<table>` or `<view>`.
## Remarks
### Remarks
This command mutates the state of the Obelisk agent.
## Produced Metadata
### Produced Metadata
DROP grantee, grant, target FROM `<database>.sys.grants`
## Exceptions
### Exceptions
`GRANT` does not exist.

View File

@ -10,13 +10,13 @@ Only available in database "sys".
**database @tas** Database name.
**sys-agent @tas** Agent making latest database schema state.
**sys-agent @tas** Agent responsible for the latest database schema state.
**sys-tmsp @da** Timestamp of latest database schema state.
**data-ship @p** Ship making latest database user data state
**data-ship @p** Ship making the latest database user data state
**data-agent @tas** Agent making latest user data state.
**data-agent @tas** Agent responsible for the latest user data state.
**data-tmsp @da** Timestamp of latest user data state.
@ -46,21 +46,21 @@ namespace
**name @tas** Table name.
**ship @p** Ship making latest table state change.
**ship @p** Ship making the latest table state change.
**agent @tas** Agent making latest table state change.
**agent @tas** Agent responsible for the latest table state change.
**tmsp @da** Timestamp of latest table state change.
**row-count @ud** Count of rows in table.
**clustered @f** Primary key of table is clustered or look-up.
**clustered @f** Indicates whether the primary key of the table is clustered or a look-up.
**key-ordinal @ud** Ordinal of column in primary key.
**key @tas** Column in primary key.
**key-ascending @f** Column in primary key is ascending or descending
**key-ascending @f** Indicates whether the column in the primary key is ascending or descending
**col-ordinal @ud** Ordinal of column in table's canonical ordering.
@ -76,7 +76,7 @@ namespace, name, key-ordinal, col-ordinal
### Columns
**namespace @tas** Namespace of table.
**namespace @tas** Namespace of the table.
**name @tas** Table name.
@ -96,9 +96,9 @@ namespace, name, col-ordinal
**tmsp @da** Timestamp of database schema change of state.
**agent @tas** Agent making state change.
**agent @tas** Agent responsible for the state change.
**component @tas** To do: 2 columns, component and namespace along with view rewrite
**component @tas** (To do: 2 columns, component and namespace along with view rewrite)
**name @tas** Added or altered component.
@ -112,9 +112,9 @@ tmsp descending, component, name
**tmsp @da** Timestamp of table data change of state.
**ship @p** Ship making state change.
**ship @p** Ship making the state change.
**agent @tas** Agent making state change.
**agent @tas** Agent responsible for the state change.
**namespace @tas** Table namespace.