Describe​

describe – provide human-readable description of a schema or a schema object

  1. describe schema [ as {ddl | sdl | test [ verbose ]} ];
  2. describe schema-type name [ as {ddl | sdl | text [ verbose ]} ];
  3. where schema-type is one of
  4. object
  5. annotation
  6. constraint
  7. function
  8. link
  9. module
  10. property
  11. scalar type
  12. type

Description​

describe generates a human-readable description of a schema object.

The output of a describe command is a str , although it cannot be used as an expression in queries.

There are three output formats to choose from:

as ddl

Provide a valid DDL definition.

The DDL generated is a complete valid definition of the particular schema object assuming all the other referenced schema objects already exist.

This is the default format.

as sdl

Provide an SDL definition.

The SDL generated is a complete valid definition of the particular schema object assuming all the other referenced schema objects already exist.

as text [verbose]

Provide a human-oriented definition.

The human-oriented definition generated is similar to SDL, but it includes all the details that are inherited (if any).

The verbose mode enables displaying additional details, such as annotations and constraints, which are otherwise omitted.

When the describe command is used with the schema the result is a definition of the entire database schema. Only the as ddl option is available for schema description.

The describe command can specify the type of schema object that it should generate the description of:

object name

Match any module level schema object with the specified name.

This is the most general use of the describe command. It does not match modules (and other globals that cannot be uniquely identified just by the name).

annotation name

Match only annotations with the specified name.

constraint name

Match only constraints with the specified name.

function name

Match only functions with the specified name.

link name

Match only links with the specified name.

module name

Match only modules with the specified name.

property name

Match only properties with the specified name.

scalar type name

Match only scalar types with the specified name.

type name

Match only object types with the specified name.

Examples​

Consider the following schema:

  1. abstract type Named {
  2. required property name -> str {
  3. delegated constraint exclusive;
  4. }
  5. }
  6. type User extending Named {
  7. required property email -> str {
  8. annotation title := 'Contact email';
  9. }
  10. }

Here are some examples of a describe command:

  1. describe object User;
  1. {
  2. "create type default::User extending default::Named {
  3. create required single property email -> std::str {
  4. create annotation std::title := 'Contact email';
  5. };
  6. };"
  7. }
  1. describe object User as sdl;
  1. {
  2. "type default::User extending default::Named {
  3. required single property email -> std::str {
  4. annotation std::title := 'Contact email';
  5. };
  6. };"
  7. }
  1. describe object User as text;
  1. {
  2. 'type default::User extending default::Named {
  3. required single link __type__ -> schema::Type {
  4. readonly := true;
  5. };
  6. required single property email -> std::str;
  7. required single property id -> std::uuid {
  8. readonly := true;
  9. };
  10. required single property name -> std::str;
  11. };'
  12. }
  1. describe object User as text verbose;
  1. {
  2. "type default::User extending default::Named {
  3. required single link __type__ -> schema::Type {
  4. readonly := true;
  5. };
  6. required single property email -> std::str {
  7. annotation std::title := 'Contact email';
  8. };
  9. required single property id -> std::uuid {
  10. readonly := true;
  11. constraint std::exclusive;
  12. };
  13. required single property name -> std::str {
  14. constraint std::exclusive;
  15. };
  16. };"
  17. }
  1. describe schema;
  1. {
  2. "create module default if not exists;
  3. create abstract type default::Named {
  4. create required single property name -> std::str {
  5. create delegated constraint std::exclusive;
  6. };
  7. };
  8. create type default::User extending default::Named {
  9. create required single property email -> std::str {
  10. create annotation std::title := 'Contact email';
  11. };
  12. };"
  13. }

The describe command also warns you if there are standard library matches that are masked by some user-defined object. Consider the following schema:

  1. module default {
  2. function len(v: tuple<float64, float64>) -> float64 using (
  3. select (v.0 ^ 2 + v.1 ^ 2) ^ 0.5
  4. );
  5. }

So within the default module the user-defined function len (computing the length of a vector) masks the built-ins:

  1. describe function len as text;
  1. {
  2. 'function default::len(v: tuple<std::float64, std::float64>) ->
  3. std::float64 using (select
  4. (((v.0 ^ 2) + (v.1 ^ 2)) ^ 0.5)
  5. );
  6. # The following builtins are masked by the above:
  7. # function std::len(array: array<anytype>) -> std::int64 {
  8. # volatility := \'Immutable\';
  9. # annotation std::description := \'A polymorphic function to calculate
  10. a "length" of its first argument.\';
  11. # using sql $$
  12. # SELECT cardinality("array")::bigint
  13. # $$
  14. # ;};
  15. # function std::len(bytes: std::bytes) -> std::int64 {
  16. # volatility := \'Immutable\';
  17. # annotation std::description := \'A polymorphic function to calculate
  18. a "length" of its first argument.\';
  19. # using sql $$
  20. # SELECT length("bytes")::bigint
  21. # $$
  22. # ;};
  23. # function std::len(str: std::str) -> std::int64 {
  24. # volatility := \'Immutable\';
  25. # annotation std::description := \'A polymorphic function to calculate
  26. a "length" of its first argument.\';
  27. # using sql $$
  28. # SELECT char_length("str")::bigint
  29. # $$
  30. # ;};',
  31. }