A shape is a powerful syntactic construct that can be used to describe
            type variants in queries, data in INSERT and UPDATE statements,
            and to specify the format of statement output.
Shapes always follow an expression, and are a list of shape elements enclosed in curly braces:
expr "{"
    shape_element [, ...]
"}"Shape element has the following syntax:
[ "[" IS object-type "]" ] pointer-specIf an optional object-type filter is used, pointer-spec will only apply to those objects in the expr set that are instances of object-type.
pointer-spec is one of the following:
a name of an existing link or property of a type produced by expr;
a declaration of a computable link or property in the form
[@]name := ptrexpra subshape in the form
pointer-name: [ "[" IS target-type "]" ] "{" ... "}"`The pointer-name is the name of an existing link or property, and target-type is an optional object type that specifies the type of target objects selected or inserted, depending on the context.
A shape in an UPDATE statement is used to specify how links and properties
                of an object are updated.
UPDATE Issue
FILTER .name = 'Issue #1'
SET
# Update shape follows
{
    name := 'Issue #1 (important)',
    comments := Issue.comments UNION (INSERT Comment {
                    body := 'Issue #1 updated'
                })
};The above statement updates the name property and adds a comments link
                to a new comment for a given Issue object.
See UPDATE for more information on the use of
                shapes in UPDATE statements.
A shape in a SELECT clause (or the UNION clause of a
                FOR statement) determines the output format for the objects in a set
                computed by an expression annotated by the shape.
For example, the below query returns a set of Issue objects and includes
                a number and an associated owner User object, which in turn includes
                the name and the email for that user.
db> ... ... ... ... ... ... ...
SELECT
    Issue {
        number,
        owner: {  # sub-shape, selects Issue.owner objects
           name,
           email
        }
    };
{
    'number': 1,
    'owner': {
        'name': 'Alice',
        'email': 'alice@example.com'
    }
}Typically the cardinality of an expression can be statically determined from the individual parts. Sometimes it is necessary to specify the cardinality explicitly. For example, when using computables in shapes it may be desirable to specify the cardinality of the computable because it affects serialization.
WITH
    MODULE example
SELECT User {
    name,
    multi nicknames := (SELECT 'Foo')
};Cardinality is normally statically inferred from the query, so
                    overruling this inference may only be done to relax the cardinality,
                    so it is not valid to specify the single qualifier for a computable
                    expression that may return multiple items.
A query could use a shape to create an alias to a real link. In this case, the link properties on that link are preserved on the aliased link as well. Consider the following schema:
type User {
    required property name -> str;
    multi link friends -> User {
        property since -> datetime;
    }
}Suppose that for a certain query the link friends needs to be
                    renamed into associates without changing the underlying schema. A
                    shape annotation can be used to provide an alias for the link:
WITH
    MODULE example,
    SpecialUser := (
        SELECT User {
            associates := User.friends
        }
    )
SELECT SpecialUser {
    name,
    associates: {
        name,
        @since
    }
};When a simple path is used as the definition of a computable link, that has the effect of aliasing the underlying link and thus preserving any link properties as well. For a path that has more than one step, it is always the last step that is aliased.