This commit is contained in:
jackfoxy 2023-05-24 19:33:27 -07:00
parent 8bc1197b32
commit 21514eb9a1
10 changed files with 450 additions and 300 deletions

View File

@ -2,78 +2,53 @@
## Manifesto ## Manifesto
The relational data model has been conspicuously missing from Urbit. Why is this fundamental technology, with a sound foundation in relational algebra, set theory, and first order predicate calculus so frequently overlooked? 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.
1. RDBMS technology is not typically covered in today's CS curriculums. 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.
2. Developers don't want to hassle with setting up a server.
3. Proprietary closed-source RDBMS implementations.
4. Trendy _no sql_ alternatives.
5. Re-inventing the wheel for reasons.
6. The prevalence of artificial keys in real world SQL implementations.
Some of these reasons are irrational, others are just wrong.
1. Speculatively, this may be because there is nothing new to discover. The relational model rests on well-understood math theory.
2. Urbit fixes this.
3. Urbit fixes this.
4. Most programmers will never face a situation where an RDBMS is inadequate or inferior for the task. _Key-value Store_ is a very simple relational database.
5. Programmers with little or no SQL exposure mistakenly think they can write better/faster IO by hand, whereas experienced engineers know to use SQL first for all the functionality wherein it can be used (except sorting, which is not strictly part of the relational model).
6. Almost all sample databases for learning SQL incorporate artificial keys, which reinforces wrong practices, so most SQL database implementations also make this mistake. Explaining the case for using natural keys on tables over artificial keys is beyond the scope of this document. See for instance [keys demo](https://github.com/ami-levin/Keys-Session/blob/master/Keys_Demo.sql).
An Urbit native RDBMS implementation opens new opportunities for composability. All of a ship's data is transparently available for _mash up_ apps and _ad hoc_ queries. Search comes for free.
An Urbit RDBMS deserves a _first principles_ approach to design and implementation. The _urQL_ language is heavily influenced by _The Third Manifesto_ (Date and Darwen), emphasizing composability and type safety. Areas where SQL was too hastily designed and/or developed without regard to theory (like nullable columns) have been eliminated, making urQL much more like the _Query Language_ Codd and Date would have been proud of.
## Functionality ## Functionality
The Urbit RDBMS, Obelisk, consists of The Urbit RDBMS, Obelisk, consists of:
1. A scripting language (this document) and parser 1. A scripting language and parser (as documented here).
2. A plan builder 2. A plan builder.
3. A front-end agent app...anyone can write one from the parser and plan APIs. 3. A front-end agent app using the parser and APIs.
The scripting language, _urQL_, derives from SQL and varies in a few cases. The scripting language, _urQL_, is a derivation of SQL with significant variations.
Queries are constructed in FROM..WHERE..SELECT.. order, the order of events in plan execution. Queries are constructed in FROM..WHERE..SELECT.. order, mirroring the order of events in plan execution. (Users should be aware of the event ordering.)
(The user should be cognizant of the ordering of events.)
Columns are typed atoms. Columns are typed atoms. Table definitions do not permit nullable columns.
Table definitions do not allow for nullable columns.
All user-defined names (excepting aliases) follow the hoon term naming standard. All user-defined names (excepting aliases) follow the hoon term naming standard.
All except the simplest functions are collected in their own clause and inlined into SELECT clause and predicates by alias. Functions, apart from the simplest ones, are grouped in their own clause and inlined into SELECT clause and predicates by alias.
Inlined sub-queries banned improving readability. 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.
JOINs and/or CTEs handle all such use cases and emphasize composability.
CTEs can be referenced for certain use cases in predicates.
Relational division is supported with a DIVIDED BY operator. Relational division is supported with a DIVIDED BY operator.
Set operations support nesting of queries on the right side. Set operations support nesting of queries on the right side of the operator.
All data manipulation commands (DELETE, INSERT, MERGE, UPDATE) as well as the SELECT statement can accept a dataset output by a prior TRANSFORM step and send its output dataset to the next step. 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 allowed provided the ship's pilot has granted permission. 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.
Cross database joins are allowed, but not cross ship joins.
Views cannot be defined on foreign databases.
Queries can operate on previous versions and data of the databases via the AS OF clause. 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. We anticipate these will be points for integration with hoon and other agents. 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 ## urQL language diagrams and general syntax
[ ] indicate optional entries. [ ] indicate optional entries.
{ } nest options | delimited. { } 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 ]. In some cases { } groups a portion of the diagram to indicate optional repeating [ ,...n ].
\<...> user supplied argument which either expands to a diagram defined elsewhere or hints for user input, e.g. `<alias>`, `<new-table>`. \<...> Represents a user-supplied argument that either expands to a diagram defined elsewhere or hints at user input, e.g. `<alias>`, `<new-table>`.
The intelligent reader is assumed intuitive enough to understand these are labels corresponding to typed nouns in the given context.
Text outside of brackets represents required keywords. Text outside of brackets represents required keywords.
Keywords are uppercase. This is not a requirement, but is strongly suggested for readability. Keywords are uppercase. This is not a requirement, but is strongly suggested for readability.
All whitespace is the same, a single space or LF suffices. All whitespace is treated the same; a single space or line feed suffices.
Whitespace around delimiting `;` and `,` is optional. Whitespace around delimiting `;` and `,` is optional.
Whitespace is required on the outside of parentheses and optional on the inside. Whitespace is required on the outside of parentheses and optional on the inside.
@ -81,18 +56,23 @@ 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 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 standards except that upper-case alphabetic characters are allowed and alias evaluation is case agnositc, e.g. `t1` and `T1` represent the same alias. 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 owned by the system and read only for all user commands. 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.
The namespace *sys* may not be specified in any other database.
## Common hints used throughout the reference ## Common structures throughout the reference
The following are some common language structures used throughout the reference:
``` ```
<db-qualifer> ::= <db-qualifer> ::= { <database>.<namespace>. | <database>.. | <namespace>. }
{ <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-qualifer> ::= <ship-qualifer> ::=
{ @p.<database>.<namespace>. { @p.<database>.<namespace>.
@ -100,16 +80,13 @@ The namespace *sys* may not be specified in any other database.
| <db-qualifer> } | <db-qualifer> }
``` ```
Adds ship qualification.
``` ```
<common-table-expression> ::= <common-table-expression> ::= <transform> [ AS ] <alias>
<transform> [ AS ] <alias> --to do: refine this, it's not exactly <transform>
``` ```
`<transform> ::=` from transform diagram. `<transform> ::=` from transform diagram.
When used as a `<common-table-expression>` (CTE) `<transform>` output must be a pass-thru virtual-table.
In a CTE the `WITH` clause is virtually the prior CTEs defined in the parent `<transform>`.
`<alias> ::= @t` case-agnostic, see alias naming discussion above. `<alias> ::= @t` case-agnostic, see alias naming discussion above.
Each CTE is always referenced by alias, never inlined. Each CTE is always referenced by alias, never inlined.
@ -122,9 +99,7 @@ Each CTE is always referenced by alias, never inlined.
| * | *
``` ```
If not qualified, `<table> | <view>` references the host ship, current database, and the default user namespace, `dbo`. When `<view>, <table>` have the same name within a namespace, `<view>` is said to "shadow" `<table>` wherever syntax accepts `<table>` or `<view>`.
When `<view>, <table>` have the same name within a namespace, `<view>` is said to "shadow" `<table>` wherever syntax accepts `<table> | <view>`.
A base-table, `<table>`, is the only manifestation of `<table-set>` that is not a computation. A base-table, `<table>`, is the only manifestation of `<table-set>` that is not a computation.
@ -138,17 +113,15 @@ Similarly `*` as the output of `DELETE`, `INSERT`, `MERGE` creates a pass-thru v
## Issues ## Issues
(incomplete list) 1. Stored procedures - To Be Designed (TBD)
1. stored procedures TBD 2. Triggers - TBD
2. triggers TBD 3. Localization of date/time - TBD (See: https://github.com/sigilante/l10n)
3. https://github.com/sigilante/l10n localization of date/time TBD 4. `SELECT` single column named top, bottom, or distinct may cause problems
4. `SELECT` single column named top, bottom, or distinct is problematic 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.
5. Add `DISTINCT` and other advanced aggregate features. Grouping Sets. Rollup. Cube. GROUPING function. Feature T301 'Functional dependencies' from SQL 1999 specification. 6. Change column:ast and value-literal:ast to vase in parser and AST.
6. investigate changing column:ast and value-literal:ast to vase in parser 7. Set operators, multiple commands per `<transform>` not complete in the parser.
7. set operators, multiple commands per transform 8. Scalar and aggregate functions incompletely implemented in parser and not fully desinged.
8. scalar and aggregate functions 9. Add aura @uc Bitcoin address 0c1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa
19. grouping FROM/SELECT statements after set operation in `<transform>` 10. Custom types and support for arbitrary noun columns - TBD
10. add aura @uc Bitcoin address 0c1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa 11. Pivoting and windowing will be implemented in a future release.
11. a path forward for arbitrary noun columns? 12. `<view>` not implemented in parser and caching is TBD
12. pivoting and windowing will be in a future release.
13. `<view>` caching TBD.

View File

@ -2,8 +2,7 @@
All data representations (nouns) of the Obelisk system are strongly typed. All data representations (nouns) of the Obelisk system are strongly typed.
## Column Types ## Column Types
The fundamental data element is an atom typed by an aura. 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. .
All data cells (the intersection of a `<table-set>` row and column) are a typed atom.
Obelisk supports the following auras: Obelisk supports the following auras:
@ -44,43 +43,41 @@ Columns are typed by an aura and indexed by name.
## Table Row and Table Types ## Table Row and Table Types
All datasets in Obelisk are sets, meaning each typed element (the `<row-type>`) only exists once. All datasets in Obelisk are sets, meaning each typed element, `<row-type>`, only exists once.
They are also commonly regarded as tables, but this is only true when the index of each cell (row/column intersenction) can be calculated, and this is only true when the `SELECT` statement includes and `ORDER BY` clause. 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.
All tables either are, or derive from, base-tables spawned by `CREATE TABLE`. All tables originate from, or are derived from, base tables created by the `CREATE TABLE` command.
Base-table (`<table>`) rows have exactly one type, the table's atomic aura-typed columns in a fixed order. A base-table (`<table>`) row has a default type, which is the table's atomic aura-typed columns in a fixed order.
``` ```
<row-type> ::= <row-type> ::= list <aura>
list <aura>
``` ```
Each base-table is itself typed by its `<row-type>`. Each base table is typed by its `<row-type>`.
``` ```
<table-type> ::= <table-type> ::= (list <row-type>)
(list <row-type>)
``` ```
Base-table definitions include a unique primary ordering of rows, hence it has list type, not set type. This is not the case for every other instance of `<table-set>`. A base table's definition includes a unique primary row order, giving it `list` type rather than `set` type. This is not true for all `<table-set>` instances.
Rows from `<view>`s, `<common-table-expression>`'s, and command output from `<transform>`, or any other table that is not a base-table can only have an immutable row ordering, if it was so specified (i.e. the `SELECT` statement has an `ORDER BY` clause). In general all these other tables have types that are unions of `<row-type>`s. Rows from `<view>`s, `<common-table-expression>`s, and the command output from `<transform>`, or any other table that is not a base-table, can only have an immutable row order if it is explicitly specified (i.e., the `SELECT` statement includes an `ORDER BY` clause). In general, these other tables have types that are unions of `<row-type>`s.
When the `<table-set-type>` is a union of `<row-type>`s there is a `<row-type>` that represents the full width of the SELECT statement and as many `<row-type>` sub-types as necessary to represent any unjoined LEFT or RIGHT JOINs that resulted in a row. When the `<table-set-type>` is a union of `<row-type>`s. There is a `<row-type>` representing the full width of the `SELECT` statement and as many `<row-type>` sub-types as necessary to represent any unjoined outer `JOIN`s that result in a selected row.
Sub-types are column-wise aligned with the all-column `<row-type>`, regardless of how the SELECT statement is constructed. Sub-types align their columns with the all-column `<row-type>`, regardless of the SELECT statement's construction.
In general `<table-set>`s have the type: In general, `<table-set>`s have the type:
``` ```
<table-set-type> ::= <table-set-type> ::=
(list <row-type>) (list <row-type>)
| (set (<all-column-row-type> | <row-sub-type-1> | ... | <row-sub-type-n> )) | (set (<all-column-row-type> | <row-sub-type-1> | ... | <row-sub-type-n> ))
``` ```
## Other Types ## Additional Types
All the static types in Obelisk API are defined in sur/ast/hoon. All the static types in Obelisk API are defined in `sur/ast/hoon`.
## Remarks ## Remarks
Ultimately even `<table>`s can be typed as sets, because `SELECT` without `ORDER BY` has undefined row order. Even `<table>`s can be typed as sets, because a `SELECT` statement without an `ORDER BY` clause has an undefined row order.
On the other hand, regardless of the presence of `ORDER BY` any `<table-set>` emitted by any step in a `<transform>` is a list of `<row-type>` in some (possibly arbitrary) order. Regardless of the presence of `ORDER BY`, any `<table-set>` emitted by any step in a `<transform>`, a CTE, or a `<view>` is a list of `<row-type>` in some (possibly arbitrary) order.
And ultimately "set" is the most important concept because every `<table-set>` will have one unique row value for any given `sub-type` of `<row-type>`. Ultimately, "set" is the most important concept because every `<table-set>` will have one unique row value for any given sub-type of `<row-type>`.

View File

@ -1,15 +1,15 @@
# CREATE DATABASE # CREATE DATABASE
Creates a new user-space database available to any agent running on the ship. There is no sand-boxing. This command creates a new user-space database accessible to any agent running on the ship. There is no sandboxing implemented.
TO DO: consider adding an owner-desk property and GRANT desk permissions. _NOTE_: Additional features like owner-desk property and GRANT desk permissions are under consideration.
``` ```
CREATE DATABASE <database> <create-database> ::=
CREATE DATABASE <database>
``` ```
## Example ## Example
``` ```
<create-database> ::=
CREATE DATABASE my-database CREATE DATABASE my-database
``` ```
@ -21,27 +21,25 @@ CREATE DATABASE <database>
## Arguments ## Arguments
**`<database>`** **`<database>`**
User-defined name for the new database. Must follow the hoon term naming standard. This is the user-defined name for the new database. It must comply with the Hoon term naming standard.
## Remarks ## Remarks
The command results in a state change of the Obelisk agent. This command mutates the state of the Obelisk agent.
`CREATE DATABASE` must be the only command in a script. `CREATE DATABASE` must be executed independently within a script. The script will fail if there are prior commands. Subsequent commands will be ignored.
The script will fail if there are prior commands.
As the first command it will succeed and subsequent commands will be ignored.
## Produced Metadata ## Produced Metadata
INSERT `name`, `<timestamp>` into `sys.sys.databases` INSERT `name`, `<timestamp>` into `sys.sys.databases`
Creates all `<database>.sys` tables. Create all `<database>.sys` tables
## Exceptions ## Exceptions
database already exists database already exists
# CREATE INDEX # CREATE INDEX
Creates an index over selected column(s) on an existing table. This command creates an index over selected column(s) of an existing table.
``` ```
<create-index> ::= <create-index> ::=
@ -74,23 +72,28 @@ CREATE INDEX ix_vendor-id3 ON purchasing..product-vendor (vendor-id);
## 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.
**`<index>`** **`<index>`**
User-defined name for the new index. Must follow the hoon term naming standard. User-defined name for the new index. This name must follow the Hoon term naming standard.
**`<table>`** **`<table>`**
Name of existing table the index targets. Name of existing table the index targets.
If not explicitly qualified defaults to the Obelisk agent's current database and 'dbo' namespace. If not explicitly qualified, defaults to the Obelisk agent's current database and 'dbo' namespace.
**`<column> [ ASC | DESC ] [ ,...n ] `** **`<column> [ ASC | DESC ] [ ,...n ] `**
List of column names in the target table, representing the sort hierarchy, and optionally sort direction for each level, defaulting to `ASC`, ascending. 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 ## Remarks
The command results in a state change of the Obelisk agent. This command mutates the state of the Obelisk agent.
Index name cannot start with 'pk-' as these names are internally reserved for primary keys. Index names cannot start with 'pk-' or 'fk-' as these prefixes are reserved for primary keys and foreign keys respectively.
Index name cannot start with 'fk-' as these names are internally reserved for primary keys.
TO DO: investigate hoon ordered maps to determine what exactly "clustered" means in hoon. It may be that multiple clustering indices are possibley, freaking out most DBAs. _NOTE_: Further investigation is required to determine how "clustering" works in Hoon.
## Produced Metadata ## Produced Metadata
@ -105,12 +108,10 @@ UNIQUE specified and existing values are not unique for the column(s) specified
index name begins with 'pk-' or 'fk-' index name begins with 'pk-' or 'fk-'
# CREATE NAMESPACE # CREATE NAMESPACE
Namespaces provide a means of grouping database components including tables and views. Namespaces group various database components, including tables and views. When not explicitly specified, namespace designations default to `dbo`.
When not otherwise specified namepace designations default to `dbo`.
``` ```
<create-namespace> ::= <create-namespace> ::= CREATE NAMESPACE [<database>.]<namespace>
CREATE NAMESPACE [<database>.]<namespace>
``` ```
## Example ## Example
@ -124,11 +125,12 @@ When not otherwise specified namepace designations default to `dbo`.
## Arguments ## Arguments
**`<namespace>`** **`<namespace>`**
User-defined name for the new index. Must follow the hoon term naming standard. This is a user-defined name for the new namespace. It must adhere to the hoon term naming standard.
The namespace "sys" is reserved for system use.
Note: The "sys" namespace is reserved for system use.
## Remarks ## Remarks
The command results in a state change of the Obelisk agent. This command mutates the state of the Obelisk agent.
## Produced Metadata ## Produced Metadata
@ -139,7 +141,7 @@ INSERT `name`, `<timestamp>` into `<database>.sys.namespaces`
namespace already exists namespace already exists
# CREATE PROCEDURE # CREATE PROCEDURE
Procedures are urQL scripts that accept parameters. Procedures are parameterized urQL scripts.
``` ```
<create-proc> ::= <create-proc> ::=
@ -151,19 +153,21 @@ Procedures are urQL scripts that accept parameters.
## Remarks ## Remarks
TBD TBD
Cannot be used to create database.
Cannot be used to create a database.
# CREATE TABLE # CREATE TABLE
Tables are the only means of indexed persistent `<table-sets>`s. `<table>`s are the only means of indexed persistent `<table-sets>`s in Obelisk.
Any update to `<table>` contents results the Obelisk agent changeing state. Any update to `<table>` contents results in a state change of the Obelisk agent.
_NOTE_: Further investigation is needed to understand if there's a reason to specify foreign key names (see CREATE INDEX).
TO DO: any reason to specify foreign key name (see CREATE INDEX).
``` ```
<create-table> ::= <create-table> ::=
CREATE TABLE CREATE TABLE
[ <db-qualifer> ]<table> [ <db-qualifer> ]<table>
( { <column> <aura> } ( <column> <aura>
[ ,... n ] ) [ ,... n ] )
PRIMARY KEY [ NONCLUSTERED | CLUSTERED ] ( <column> [ ,... n ] ) PRIMARY KEY [ NONCLUSTERED | CLUSTERED ] ( <column> [ ,... n ] )
[ { FOREIGN KEY <foreign-key> ( <column> [ ASC | DESC ] [ ,... n ] ) [ { FOREIGN KEY <foreign-key> ( <column> [ ASC | DESC ] [ ,... n ] )
@ -197,25 +201,25 @@ REFERENCES special-offer (product-id, special-offer-id)
## Arguments ## Arguments
**`<table>`** **`<table>`**
User-defined name for the new table. Must follow the hoon term naming standard. This is a user-defined name for the new table. It must adhere to the hoon term naming standard.
If not explicitly qualified defaults to the Obelisk agent's current database and 'dbo' namespace. If not explicitly qualified, it defaults to the Obelisk agent's current database and the 'dbo' namespace..
**`<column> <aura>`** **`<column> <aura>`**
List of user-define column names and associated auras. Names must follow the hoon term naming standard. The list of user-defined column names and associated auras. Names must adhere to the hoon term naming standard.
See [ref-ch02-types](ref-ch02-types.md) For more details, refer to [ref-ch02-types](ref-ch02-types.md)
**`[ NONCLUSTERED | CLUSTERED ] ( <column> [ ,... n ]`** **`[ NONCLUSTERED | CLUSTERED ] ( <column> [ ,... n ]`**
Columns in the required unique primary index. Defining the index as `CLUSTERED` is optional. These are column names in the required unique primary index. Defining the index as `CLUSTERED` is optional.
**`<foreign-key> ( <column> [ ASC | DESC ] [ ,... n ]`** **`<foreign-key> ( <column> [ ASC | DESC ] [ ,... n ]`**
User-defined name for `<foreign-key>`. Must follow the hoon term naming standard. This is a user-defined name for `<foreign-key>`. It must adhere to the hoon term naming standard.
List of columns in the table for association with a foreign table along with sort ordering. Default is `ASC` ascending. 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 ]`** **`<table> ( <column> [ ,... n ]`**
Referenced foreign `<table>` and columns. Count and associated column auras must match the specified columns from the new `<table>`. 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 }`** **`ON DELETE { NO ACTION | CASCADE | SET DEFAULT }`**
Specifies an action on the rows in the table if those rows have a referential relationship and the referenced row is deleted from the foreign table. 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)
@ -227,15 +231,17 @@ Corresponding rows are deleted from the referencing table when that row is delet
* SET DEFAULT * SET DEFAULT
All the values that make up the foreign key are set to their bunt values when the corresponding row in the parent foreign table is deleted. 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 table has no entry with bunt values.
The Obelisk agent raises an error if the parent foreign table has no entry with bunt values.
**`ON UPDATE { NO ACTION | CASCADE | SET DEFAULT }`** **`ON UPDATE { NO ACTION | CASCADE | SET DEFAULT }`**
Specifies an action on the rows in the table if those rows have a referential relationship and the referenced row is deleted from the foreign table.
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. The Database Engine raises an error and the update action on the row in the parent table is aborted.
* CASCADE * CASCADE
@ -243,15 +249,18 @@ Corresponding rows are updated in the referencing table when that row is updated
* SET DEFAULT * SET DEFAULT
All the values that make up the foreign key are set to their bunt values when the corresponding row in the parent table is updated. 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 table has no entry with bunt values.
The Obelisk agent raises an error if the parent foreign table has no entry with bunt values.
## Remarks ## Remarks
The command results in a state change of the Obelisk agent. This command mutates the state of the Obelisk agent.
`PRIMARY KEY` is unique. `PRIMARY KEY` must be unique.
TO DO: What constitutes `CLUSTERED` in hoon? An ordered map? This will shake-out during development. `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
@ -269,12 +278,12 @@ table column referenced by FOREIGN KEY does not exist
aura mis-match in FOREIGN KEY aura mis-match in FOREIGN KEY
# CREATE TRIGGER # CREATE TRIGGER
A trigger automatically runs when a specified table or view event occurs in the Obelisk agent. It runs a previously defined `<procedure>`. A trigger automatically runs when a specified table or view event occurs in the Obelisk agent. It runs a previously defined `<procedure>`.
An `INSTEAD OF` trigger fires before the triggering event can occur and replaces it. Otherwise the procedure runs after the triggering event succedes and all state changed by both the triggering event and trigger `<procedure>` is included in one and the same state change. An `INSTEAD OF` trigger fires before the triggering event can occur and replaces it. Otherwise the procedure runs after the triggering event succedes and all state changed by both the triggering event and trigger `<procedure>` is included in one and the same state change.
Trigger events are INSERT, UPDATE, or DELETE statements on a `<table>`. Triggering events are `INSERT`, `UPDATE`, and `DELETE` statements on a `<table>` and simple execution in the case of `<view>`.
The trigger event for a `<view>` is simple execution.
``` ```
<create-trigger> ::= <create-trigger> ::=
@ -288,14 +297,19 @@ The trigger event for a `<view>` is simple execution.
## Remarks ## Remarks
TBD TBD
could be used to trigger any database process or agent
`{ [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ] }` does not apply to views.
This command could be used to trigger any database process or agent.
# CREATE TYPE
TBD
`CREATE TYPE <type>`
# CREATE VIEW # CREATE VIEW
A view creates a `<table-set>` whose contents (columns and rows) are defined by a `<transform>`. A view creates a `<table-set>` whose contents (columns and rows) are defined by a `<transform>`.
Potential caching of views is TBD. The possibility of caching of views is TBD.
``` ```
<create-view> ::= <create-view> ::=
@ -315,21 +329,24 @@ Potential caching of views is TBD.
## Arguments ## Arguments
**`<view>`** **`<view>`**
User-defined name for the new view. Must follow the hoon term naming standard. The user-defined name for the new view, which must adhere to the Hoon term naming standard.
**`<transform>`** **`<transform>`**
`<transform>` producing the output `<table-set>`. The `<transform>` that produces the output `<table-set>`.
## Remarks ## Remarks
The command results in a state change of the Obelisk agent. This command mutates the state of the Obelisk agent.
Views are read only. Views are read only.
The last step of the `<transform>` must establish unique column names, whether inherited from prior `<table-set>`s or aliased columns.
The final step of the `<transform>` must establish unique column names, whether inherited from prior `<table-set>`s or aliased columns.
Views cannot be defined on foreign ship databases.
## Produced Metadata ## Produced Metadata
INSERT `name`, `<transform>`, `<timestamp>` into `<database>.sys.views` INSERT `name`, `<transform>`, `<timestamp>` INTO `<database>.sys.views`
INSERT `name`, `<ordinal>`, `<column>` into `<database>.sys.view-columns` INSERT `name`, `<ordinal>`, `<column>` INTO `<database>.sys.view-columns`
## Exceptions ## Exceptions

View File

@ -25,20 +25,20 @@ Deletes rows from a `<table-set>`.
## Arguments ## Arguments
**`<table-set>`** **`<table-set>`**
Target of the `DELETE` operation. The target of the `DELETE` operation.
**`<predicate>`** **`<predicate>`**
Any valid `<predicate>` including predicates on CTEs. Any valid `<predicate>`, including predicates on CTEs.
## Remarks ## Remarks
When `<table-set>` is a `<table>` the command potentially mutates `<table>` and if so results in a state change of the Obelisk agent. When `<table-set>` is a `<table>`, the command potentially mutates `<table>` resulting in a state change of the Obelisk agent.
A stand-alone `DELETE` statement can only operate on a `<table>` and produces a `<transform>` of one command step. A stand-alone `DELETE` statement can only operate on a `<table>` and produces a `<transform>` of one command step.
Data in the namespace *sys* cannot be deleted. 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. 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
@ -70,7 +70,7 @@ Inserts rows into a `<table-set>`.
| expression <binary-operator> expression } | expression <binary-operator> expression }
``` ```
`<scalar-function>` TBD, see functions chapter undergoing design development. Details of `<scalar-function>` are TBD. Refer to the Functions chapter currently under development.
## API ## API
``` ```
@ -86,44 +86,40 @@ Inserts rows into a `<table-set>`.
## Arguments ## Arguments
**`<table-set>`** **`<table-set>`**
Target of the `INSERT` operation. The target of the `INSERT` operation.
**`<column>` [ ,...n ]** **`<column>` [ ,...n ]**
When present the column list must account for all column identifiers (names or aliases) in the target once. 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.
Establishes the order in which update values are applied and the output `<table-set>`'s column order.
**(`<scalar-expression>` [ ,...n ] ) [ ,...n ]** **(`<scalar-expression>` [ ,...n ] ) [ ,...n ]**
Row(s) of literal values to insert into target. Row(s) of literal values to insert into target. Source auras must match target columnwise.
Auras must match target columnwise.
**`<transform>`** **`<transform>`**
Transform creating source `<table-set>` to insert into target. Transform creating source `<table-set>` to insert into target. Source auras must match target columnwise.
Source auras must match target columnwise.
## Remarks ## Remarks
When `<table-set>` is a `<table>` the command potentially mutates `<table>` and if so results in a state change of the Obelisk agent. When `<table-set>` is a `<table>` the command potentially mutates `<table>`, resulting in a state change of the Obelisk agent.
A stand-alone `INSERT` statement can only operate on a `<table>` and produces a `<transform>` of one command step with no CTEs. A stand-alone `INSERT` statement can only operate on a `<table>`, producing a `<transform>` of one command step with no CTEs.
Data in the namespace *sys* cannot be inserted into. Data in the *sys* namespace cannot be inserted into.
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. 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 `<query>` must provide data for all columns in the expected order.
Cord values are represented in single quotes `'this is a cord'`. 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'`.
Escape single quotes with double backslash thusly `'this is a cor\\'d'`.
When `( <column> [ ,...n ] )` not specified, inserted columns must be arranged in same order as target `<table-set>`. If `( <column> [ ,...n ] )` is not specified, the inserted columns must be arranged in the same order as the target `<table-set>`.
When target `<table-set>` is a `<table>` input `<row-type>` must match the `<table>` `<row-type>`. 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. 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.
## Produced Metadata ## Produced Metadata
@@ROWCOUNT returns the total number of rows inserted `@@ROWCOUNT` returns the total number of rows inserted
## Exceptions ## Exceptions
`<table>` does not exist `<table>` does not exist
@ -153,13 +149,13 @@ Removes all rows in a base table.
## Arguments ## Arguments
**`<table>`** **`<table>`**
Target table. The target table.
## Remarks ## Remarks
The command potentially mutates `<table>` and if so results in a state change of the Obelisk agent. The command potentially mutates `<table>`, resulting in a state change of the Obelisk agent.
Tables in the namespace *sys* cannot be truncated. Tables in the *sys* namespace cannot be truncated.
## Produced Metadata ## Produced Metadata
@ -196,33 +192,31 @@ Changes content of selected columns in existing rows of a `<table-set>`.
## Arguments ## Arguments
**`<table-set>`** **`<table-set>`**
Target of the `UPDATE` operation The target of the `UPDATE` operation.
**`<column>` = `<scalar-expression>`** **`<column>` = `<scalar-expression>`**
`<column>` is a column name or alias of a target column. `<column>` is a column name or alias of a target column. `<scalar-expression>` is a valid expression within the statement context.
`<scalar-expression>` valid expression within the statement context.
**`<predicate>`** **`<predicate>`**
Any valid `<predicate>` including predicates on CTEs. Any valid `<predicate>`, including predicates on CTEs.
## Remarks ## Remarks
When `<table-set>` is a `<table>` the command potentially mutates `<table>` and if so results in a state change of the Obelisk agent. When `<table-set>` is a `<table>`, the command potentially mutates the data within `<table>`, resulting in a state change of the Obelisk agent.
A stand-alone `UPDATE` statement can only operate on a `<table>` and produces a `<transform>` of one command step with no CTEs. A stand-alone `UPDATE` statement can only operate on a `<table>`, producing a `<transform>` of one command step with no CTEs.
Data in the namespace *sys* cannot be updated. 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. 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 `<query>` must provide data for all columns in the expected order.
Cord values are represented in single quotes 'this is a cord'. 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'`.
Escape single quotes with double backslash thusly `'this is a cor\\'d'`.
## Produced Metadata ## Produced Metadata
@@ROWCOUNT returns the total number of rows updated `@@ROWCOUNT` returns the total number of rows updated
## Exceptions ## Exceptions
`<table>` does not exist `<table>` does not exist

View File

@ -139,5 +139,9 @@ See CH 8 Functions for full documentation on Scalars.
** ** ** **
## Remarks
## Produced Metadata
## Exceptions ## Exceptions

View File

@ -31,17 +31,18 @@ If the resulting virtual-table row type is a union type, then the output must be
BREAKING CHANGE: The parser currently parses the syntax *MERGE... PRODUCING... WITH...*. This will eventually be refactored to *WITH... MERGE...*. BREAKING CHANGE: The parser currently parses the syntax *MERGE... PRODUCING... WITH...*. This will eventually be refactored to *WITH... MERGE...*.
``` ```
MERGE [ { INTO | FROM } ] <target-table> [ [ AS ] <alias> ] <merge> ::=
[ PRODUCING NEW <new-table> [ [ AS ] <alias> ] ] MERGE [ { INTO | FROM } ] <target-table> [ [ AS ] <alias> ]
USING <source-table> [ [ AS ] <alias> ] [ PRODUCING NEW <new-table> [ [ AS ] <alias> ] ]
[ [ SCALAR ] [ ,...n ] ] USING <source-table> [ [ AS ] <alias> ]
[ ON <merge-predicate> ] [ [ SCALAR ] [ ,...n ] ]
[ WHEN MATCHED [ AND <matched-predicate> ] [ ON <merge-predicate> ]
THEN <merge-matched> ] [ ...n ] [ WHEN MATCHED [ AND <matched-predicate> ]
[ WHEN NOT MATCHED [ BY TARGET ] [ AND <unmatched-target-predicate> ] THEN <merge-matched> ] [ ...n ]
THEN <merge-not-matched> ] [ ...n ] [ WHEN NOT MATCHED [ BY TARGET ] [ AND <unmatched-target-predicate> ]
[ WHEN NOT MATCHED BY SOURCE [ AND <unmatched-source-predicate> ] THEN <merge-not-matched> ] [ ...n ]
THEN <merge-matched> ] [ ...n ] [ WHEN NOT MATCHED BY SOURCE [ AND <unmatched-source-predicate> ]
THEN <merge-matched> ] [ ...n ]
``` ```
``` ```

View File

@ -68,6 +68,12 @@ API:
## Remarks ## Remarks
`<transform>` within a CTE may not have its own `WITH` clause.
The `<transform>` `WITH` clause, in which CTEs are grouped, makes each CTE available to subsequent CTEs defined in the parent `<transform>`.
When used as a `<common-table-expression>` (CTE) `<transform>` output must be a pass-thru virtual-table.
## Produced Metadata ## Produced Metadata
## Exceptions ## Exceptions

View File

@ -1,13 +1,14 @@
# GRANT # GRANT
Grants permission to read from and/or write to selected `<database>` on host ship to selected foreign ships. Grants permission to read from and/or write to selected `<database>`, `<namespace>`, or `<table-object>` on host ship to selected foreign ships.
``` ```
GRANT { ADMINREAD | READONLY | READWRITE } <grant> ::=
TO { PARENT | SIBLINGS | MOONS | <@p> [ ,...n ] } GRANT { ADMINREAD | READONLY | READWRITE }
ON { DATABASE <database> TO { PARENT | SIBLINGS | MOONS | <@p> [ ,...n ] }
| NAMESPACE [<database>.]<namespace> ON { DATABASE <database>
| [<db-qualifer>]<table-object> | NAMESPACE [<database>.]<namespace>
} | [<db-qualifer>]<table-object>
}
``` ```
## Example ## Example
@ -27,10 +28,10 @@ $:
**ADMINREAD** **ADMINREAD**
Grants read permission on `<database>.sys` tables and views. Grants read permission on `<database>.sys` tables and views.
`ON` clause must be `<database>`. The `ON` clause must be `<database>`.
**READONLY** **READONLY**
Grants read permission on selected object. Grants read-only permission on selected object.
**READWRITE** **READWRITE**
Grants read and write permission on selected object. Grants read and write permission on selected object.
@ -57,15 +58,14 @@ Grant permissin on named namespace to all `<table>s` and `<view>`s.
Grant permission is on named object, whether is is a `<table>` or `<view>`. Grant permission is on named object, whether is is a `<table>` or `<view>`.
## Remarks ## Remarks
The command results in a state change of the Obelisk agent. This command mutates the state of the Obelisk agent.
Write permission includes `DELETE`, `INSERT`, and `UPDATE`. Write permission includes `DELETE`, `INSERT`, and `UPDATE`.
When a granted database object is dropped all applicable `GRANT`s are also dropped. When a granted database object is dropped, all applicable `GRANT`s are also dropped.
`<table-object>` remain valid whether a `<view>` is shadowing a `<table>` or not. `<table-object>` remains valid whether a `<view>` is shadowing a `<table>` or not.
In the case where a shadowing `<view>` is dropped the grant then applies to the `<table>`. 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>`.
In the case where a new `<view>` shadows a granted `<table>` the grant newly applies to the `<view>`.
## Produced Metadata ## Produced Metadata
@ -79,10 +79,11 @@ INSERT grantee, grant, target, `<timestamp>` INTO `<database>.sys.grants`
# REVOKE # REVOKE
Revokes permission to read from and/or write to selected database objects on host ship to selected foreign ships. Revokes permission to read from and/or write to selected database objects on the host ship to selected foreign ships.
``` ```
REVOKE { ADMINREAD | READONLY | READWRITE | ALL } <revoke> ::=
REVOKE { ADMINREAD | READONLY | READWRITE | ALL }
FROM { PARENT | SIBLINGS | MOONS | ALL | <@p> [ ,...n ] } FROM { PARENT | SIBLINGS | MOONS | ALL | <@p> [ ,...n ] }
ON { DATABASE <database> ON { DATABASE <database>
| NAMESPACE [<database>.]<namespace> | NAMESPACE [<database>.]<namespace>
@ -105,38 +106,37 @@ REVOKE { ADMINREAD | READONLY | READWRITE | ALL }
## Arguments ## Arguments
**ADMINREAD** **ADMINREAD**
Revokes read permission on `<database>.sys` tables and views. Revokes read permission on `<database>.sys` tables and views. The `ON` clause must be `<database>`.
`ON` clause must be `<database>`.
**READONLY** **READONLY**
Revokes read permission on selected object. Revokes read-only permission on selected object.
**READWRITE** **READWRITE**
Revokes read and write (DELETE, INSERT, UPDATE) permission on selected object. Revokes read and write (DELETE, INSERT, UPDATE) permission on selected object.
**PARENT** **PARENT**
Grantee is parent of ship on which Obelisk agent is running. The grantee is the parent of the ship on which the Obelisk agent is running.
**SIBLINGS** **SIBLINGS**
Grantees are all other moons of the parent of ship on which Obelisk agent is running. The grantees are all other moons of the parent of the ship on which the Obelisk agent is running, which is also a moon.
**MOONS** **MOONS**
Grantees are all moons of the ship on which Obelisk agent is running. The grantees are all moons of the ship on which the Obelisk agent is running.
**<@p> [ ,...n ]** **<@p> [ ,...n ]**
List of ships to grant permission to. List of ships from which permission will be revoked.
**`<database>`** **`<database>`**
Grant permissin on named database. Revoke permission on the named database.
**`[<database>.]<namespace>`** **`[<database>.]<namespace>`**
Revoke permissin on named namespace. Revoke permissin on named namespace.
**`[<db-qualifer>]<table-object>`** **`[<db-qualifer>]<table-object>`**
Revoke permission is on named object, whether is is a `<table>` or `<view>`. Revoke permission is on named object, whether it is a `<table>` or `<view>`.
## Remarks ## Remarks
The command results in a state change of the Obelisk agent. This command mutates the state of the Obelisk agent.
## Produced Metadata ## Produced Metadata
DROP grantee, grant, target FROM `<database>.sys.grants` DROP grantee, grant, target FROM `<database>.sys.grants`

View File

@ -1,14 +1,14 @@
# ALTER INDEX # ALTER INDEX
Alters the structure of an existing `<index>` Modifies the structure of an existing `<index>` on a user `<table>` or `<view>`.
``` ```
ALTER [ UNIQUE ] [ NONCLUSTERED | CLUSTERED ] INDEX [ <db-qualifer> ]<index> <alter-index> ::=
ON { <table> | <view> } ALTER [ UNIQUE ] [ NONCLUSTERED | CLUSTERED ] INDEX [ <db-qualifer> ]<index>
[ ( <column> [ ASC | DESC ] [ ,...n ] ) ] ON { <table> | <view> }
{ DISABLE | RESUME} [ ( <column> [ ASC | DESC ] [ ,...n ] ) ]
{ DISABLE | RESUME}
``` ```
## API ## API
``` ```
+$ alter-index +$ alter-index
@ -23,32 +23,51 @@ ON { <table> | <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.
**`[ <db-qualifer> ]<index>`** **`[ <db-qualifer> ]<index>`**
Target index. Specifies the target index.
**`<table> | <view>`**
Name of the underlying object of the index.
**`<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).
**`DISABLE | RESUME`**
Used to disable an active index or resume a disabled index.
## Remarks ## Remarks
The command results in a state change of the Obelisk agent. This command mutates the state of the Obelisk agent.
Cannot alter primary key and foreign key indices. Cannot alter primary key and foreign key indices.
`RESUME` will rebuild the index if the underlying object is dirty. `RESUME` will rebuild the index if the underlying object is dirty.
TO DO: investigate hoon ordered maps to determine what exactly "clustered" means in hoon. It may be that multiple clustering indices are possibley, freaking out most DBAs. 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`
## Exceptions ## Exceptions
index name does not exist for table
table does not exist
column does not exist column does not exist
UNIQUE specified and existing values are not unique for the column(s) specified UNIQUE specified and existing values are not unique for the column(s) specified
# ALTER NAMESPACE # ALTER NAMESPACE
Transfer an existing user `<table>` or `<view>` to another `<namespace>`.
``` ```
ALTER NAMESPACE [ <database>. ]<namespace> <alter-namespace> ::=
TRANSFER { TABLE | VIEW } [ <db-qualifer> ]{ <table> | <view> } ALTER NAMESPACE [ <database>. ]<namespace>
TRANSFER { TABLE | VIEW } [ <db-qualifer> ]{ <table> | <view> }
``` ```
## API ## API
``` ```
+$ alter-namespace +$ alter-namespace
@ -64,43 +83,56 @@ ALTER NAMESPACE [ <database>. ]<namespace>
## Arguments ## 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..
## Remarks ## Remarks
The command results in a state change of the Obelisk agent. This command mutates the state of the Obelisk agent.
The namespace *sys* cannot be altered, nor can objects be transferred in or out of it. Objects cannot be transferred in or out of namespace *sys*.
## Produced Metadata ## Produced Metadata
update `<database>.sys.tables`
update `<database>.sys.views`
## Exceptions ## Exceptions
namespace does not exist
`<table>` or `<view>` does not exist
# ALTER PROCEDURE # ALTER PROCEDURE
TBD TBD
``` ```
ALTER { PROC | PROCEDURE } <alter-proc> ::=
ALTER { PROC | PROCEDURE }
[<db-qualifer>]<procedure> [<db-qualifer>]<procedure>
[ { #<parameter> <data-type> } ] [ ,...n ] [ { #<parameter> <data-type> } ] [ ,...n ]
AS { <urql command>; | *hoon } [ ;...n ] AS { <urql command>; | *hoon } [ ;...n ]
``` ```
# ALTER TABLE # ALTER TABLE
Modify the columns and/or `<foreign-key>`s of an existing `<table>`.
``` ```
ALTER TABLE [ <db-qualifer> ]{ <table> } <alter-> ::=
{ ALTER COLUMN ( { <column> <aura> } [ ,... n ] ) ALTER TABLE [ <db-qualifer> ]{ <table> }
| ADD COLUMN ( { <column> <aura> } [ ,... n ] ) { ADD COLUMN ( <column> <aura> [ ,... n ] )
| DROP COLUMN ( { <column> } [ ,... n ] ) | ALTER COLUMN ( <column> <aura> [ ,... n ] )
| ADD FOREIGN KEY <foreign-key> (<column> [ ,... n ]) | DROP COLUMN ( <column> [ ,... n ] )
REFERENCES [<namespace>.]<table> (<column> [ ,... n ]) | ADD FOREIGN KEY <foreign-key> (<column> [ ,... n ])
[ ON DELETE { NO ACTION | CASCADE } ] REFERENCES [<namespace>.]<table> (<column> [ ,... n ])
[ ON UPDATE { NO ACTION | CASCADE } ] [ ON DELETE { NO ACTION | CASCADE } ]
[ ,... n ] [ ON UPDATE { NO ACTION | CASCADE } ]
| DROP FOREIGN KEY ( <foreign-key> [ ,... n ] } ) [ ,... n ]
| DROP FOREIGN KEY ( <foreign-key> [ ,... n ] } )
``` ```
Example: Example:
@ -126,34 +158,103 @@ DROP FOREIGN KEY fk-1, fk-2
## Arguments ## Arguments
** ** **`<table>`**
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.
**`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 list comprises column names in the table for association with a foreign table along with sort ordering. Default is `ASC` (ascending).
**`<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)
The Obelisk agent raises an error and the delete action on the row in the parent foreign table is aborted.
* CASCADE
Corresponding rows are deleted from the referencing table when that row is deleted from the parent foreign table.
* 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)
The Database Engine raises an error and the update action on the row in the parent table is aborted.
* CASCADE
Corresponding rows are updated in the referencing table when that row is updated in the parent table.
* 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.
## Remarks ## Remarks
The command results in a state change of the Obelisk agent. 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 ## Produced Metadata
update `<database>.sys.table-columns`
update `<database>.sys.table-columns`
update `<database>.sys.table-ref-integrity`
## Exceptions ## Exceptions
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
# ALTER TRIGGER # ALTER TRIGGER
TBD TBD
``` ```
ALTER TRIGGER { [ <db-qualifer> ]{ <trigger> } | ALL ] <alter-trigger> ::=
ALTER TRIGGER { [ <db-qualifer> ]{ <trigger> } | ALL }
ON { SERVER | <database.name> | <table> | <view> } ON { SERVER | <database.name> | <table> | <view> }
[ ENABLE | DISABLE ] [ ENABLE | DISABLE ]
``` ```
# ALTER VIEW # ALTER VIEW
Alter the structure of an existing `<view>`.
``` ```
ALTER VIEW [ <db-qualifer> ]{ <view> } <alter-view> ::=
( { [<alias>.] <column> } [ ,...n ] ) ALTER VIEW [ <db-qualifer> ]{ <view> }
AS <select_statement> ( { [<alias>.] <column> } [ ,...n ] )
AS <select_statement>
``` ```
## API ## API
``` ```
+$ alter-view +$ alter-view
@ -166,11 +267,18 @@ AS <select_statement>
## Arguments ## Arguments
** ** **`<view>`**
Specifies the name of the view to alter.
**`<transform>`**
Refers to the `<transform>` producing the output `<table-set>`.
## Remarks ## Remarks
The command results in a state change of the Obelisk agent. This command mutates the state of the Obelisk agent.
## Produced Metadata ## Produced Metadata
UPDATE `<database>.sys.views`
UPDATE `<database>.sys.view-columns`
## Exceptions ## Exceptions
view does not exist.

View File

@ -1,7 +1,8 @@
# DROP DATABASE # DROP DATABASE
Deletes an existing `<database>` and all associated objects.
`DROP DATABASE [ FORCE ] <database-name>` ```
<drop-database> ::= DROP DATABASE [ FORCE ] <database>
```
## API ## API
``` ```
@ -15,26 +16,34 @@
## Arguments ## Arguments
** ** **`FORCE`**
Optionally, force deletion of a database.
**`<database>`**
The name of the database to delete.
## Remarks ## Remarks
The command results in a state change of the Obelisk agent. This command mutates the state of the Obelisk agent.
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.
## Produced Metadata ## Produced Metadata
DELETE row from `sys.sys.databases`.
## Exceptions ## Exceptions
`<database>` does not exist.
`<database>` has populated tables and FORCE was not specified.
# DROP INDEX # DROP INDEX
Deletes an existing `<index>`.
``` ```
DROP INDEX <index-name> <drop-index> ::=
ON [ <db-qualifer> ] { <table-name> | <view-name> } DROP INDEX <index>
ON [ <db-qualifer> ] { <table> | <view> }
``` ```
## API ## API
``` ```
+$ drop-index +$ drop-index
@ -47,27 +56,39 @@ DROP INDEX <index-name>
## Arguments ## Arguments
** ** **`<index>`**
The name of the index to delete.
**`<table> | <view>`**
`<table>` or `<view>` with the named index.
## Remarks ## Remarks
The command results in a state change of the Obelisk agent. This command mutates the state of the Obelisk agent.
Cannot drop indices whose names begin with "pk-" as these are table primary keys. Indexes with names that begin with "pk-" cannot be dropped, as these are table primary keys.
drop of fk- same as alter-table This command can be used to delete a `<foreign-key>`.
TO DO: update create-index to indicate name must be unique
work out at what level? If `<view>` is shadowing `<table>`, the system attempts to find `<index>` on `<view>` first, then `<table>`.
how to deal with alter namespace considerations.
## Produced Metadata ## Produced Metadata
DELETE FROM `<database>.sys.indices`
DELETE FROM `<database>.sys.table-ref-integrity`
## Exceptions ## Exceptions
`<table>` or `<view>` does not exist
`<index>` does not exist on `<table>` or `<view>`.
# DROP NAMESPACE # DROP NAMESPACE
Deletes a `<namespace>` and all its associated objects.
`DROP NAMESPACE [ FORCE ] [ <database-name>. ]<namespace-name>` ```
<drop-namespace> ::=
DROP NAMESPACE [ FORCE ] [ <database>. ]<namespace>
```
## API ## API
``` ```
@ -82,24 +103,33 @@ TO DO: update create-index to indicate name must be unique
## Arguments ## Arguments
** ** **`FORCE`**
Optionally, force deletion of `<namespace>`.
**`<namespace>`**
The name of `<namespace>` to delete.
## Remarks ## Remarks
The command results in a state change of the Obelisk agent. This command mutates the state of the Obelisk agent.
Only succeeds when no tables or views are in the namespace, unless `FORCE` is specified, possibly resulting in cascading object drops described in `DROP TABLE`. 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`.
Cannot drop namespaces *dbo* and *sys*. The namespaces *dbo* and *sys* cannot be dropped.
## Produced Metadata ## Produced Metadata
DELETE row from `<database>.sys.namespaces`.
## Exceptions ## Exceptions
`<namespace>` does not exist.
`<namespace>` has populated tables and FORCE was not specified.
# DROP TABLE # DROP TABLE
Deletes a `<table>` and all associated objects
`DROP TABLE [ FORCE ] [ <db-qualifer> ]{ <table-name> }` ```
<drop-table> ::= DROP TABLE [ FORCE ] [ <db-qualifer> ]{ <table> }
```
## API ## API
``` ```
@ -111,28 +141,40 @@ Cannot drop namespaces *dbo* and *sys*.
== ==
``` ```
## Arguments ## Arguments
** ** **`FORCE`**
Optionally, force deletion of a table.
**`<table>`**
Name of `<table>` to delete.
## Remarks ## Remarks
The command results in a state change of the Obelisk agent. 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.
Cannot drop when the `<table>` is populated unless `FORCE` is specified.
## Produced Metadata ## Produced Metadata
DELETE from `<database>.sys.tables`.
DELETE from `<database>.sys.views`.
DELETE from `<database>.sys.indices`.
## Exceptions ## 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.
# DROP TRIGGER # DROP TRIGGER
TBD TBD
``` ```
DROP TRIGGER [ <db-qualifer> ]{ <trigger-name> } <drop-trigger> ::=
ON { <table-name> | <view-name> } DROP TRIGGER [ <db-qualifer> ]{ <trigger> }
ON { <table> | <view> }
``` ```
@ -140,7 +182,7 @@ DROP TRIGGER [ <db-qualifer> ]{ <trigger-name> }
TBD TBD
`DROP TYPE <type-name>` `DROP TYPE <type>`
## Remarks ## Remarks
@ -149,7 +191,9 @@ Cannot drop if type-name is in use.
# DROP VIEW # DROP VIEW
`DROP VIEW [ FORCE ] [ <db-qualifer> ]<view-name>` ```
<drop-view> ::= DROP VIEW [ FORCE ] [ <db-qualifer> ]<view>
```
## API ## API
@ -164,14 +208,20 @@ Cannot drop if type-name is in use.
## Arguments ## Arguments
** ** **`FORCE`**
Force delete of `<view>`.
**`<view>`**
Name of `<view>` to delete.
## Remarks ## Remarks
The command results in a state change of the Obelisk agent. This command mutates the state of the Obelisk agent.
Cannot drop if used in another view, unless `FORCE` is specified, resulting in cascading object drops. Views that are in use in another view cannot be dropped unless `FORCE` is specified, which may result in cascading object drops.
## Produced Metadata ## Produced Metadata
DELETE from `<database>.sys.views`.
## Exceptions ## Exceptions
`<view>` does not exist.
`<view>` is in use by other `<view>` and FORCE was not specified.