438 karma · joined September 20, 2012
Previously co-founder and CTO of Gel Data [1].
[1] https://geldata.com
[ my public key: https://keybase.io/elprans; my proof: https://keybase.io/elprans/sigs/p0bjVrvsPB2J-0pE_ZgpeT-gli6jsZ45wHgeBaMKNNY ]
Yes, `{}` is inferred as `anytype`, but we chose to restrict its use in output for interoperability reasons: the output of a query must be of a concrete, known type.
>> Strictly speaking, EdgeQL sets are multisets [1] > Like nulls, this is another broken aspects of SQL.
From the purity standpoint, yes, but in practice, duplicate values are either expected, or too expensive to eliminate. That said there is a `DISTINCT` [1] aggregate.
> * It conflates types with relation variables
Not exactly. We do use the same symbol to denote a type, and a relation that it represents, but the context of which is which is always clear (i.e. Foo in a cast expression is always a type), but Foo in a regular expression is always a relvar.
> * It's using links rather than foreign key constraints
Links are an abstraction over a foreign key. In the vast majority of cases foreign keys are implemented as 'some_id' -> 'id' anyway. If you want a custom foreign key, you can set an expression constraint on a property or a link.
> * It doesn't seem like the user can even specify a candidate key
type Foo { constraint exclusive on ((.name, .last_name)) }
> * Which is why the "id" field is magical and special
See RM proscription 15 in the Third Manifesto [2]
> * Constraints only seem to apply to scalars
They aren't, see above.
[1] https://edgedb.com/docs/edgeql/funcops/set#operator::DISTINC... [2] https://www.dcs.warwick.ac.uk/~hugh/TTM/DTATRM.pdf
You can also query the actual object type by referring to the __type__ link:
SELECT User {
favorites: {
__type__,
[IS Movie].director,
[IS Book].author,
}
}; edgedb> SELECT {'First', 'Second'} ++ '!';
{'First!', 'Second!'}
EdgeQL queries are essentially set comprehensions. type Movie {
property director -> str
};
type Book {
property author -> str
};
type User {
multi link favorites -> Movie | Book
};
SELECT User {
favorites: {
[IS Movie].director,
[IS Book].author,
}
};The last query is still returning a flat set of Movie objects. The shape selector describes _related_ data that is also needed to be fetched by the query. So, the query actually returns multiple sets that can be reconstructed by the client into a graph of objects (or serialized into JSON).
This is a valid expression:
SELECT (SELECT count(*) FROM table) + 1
This is not: SELECT (SELECT * FROM table), 1
In EdgeQL: SELECT (count(SomeType) + 1)
and SELECT (SomeType, 1)
are equally valid.Not on the planner level. Most of EdgeQL-specific low-level stuff is currently built as an extension with helpers. Our strategy is to upstream as much as possible, including any possible improvements to the planner that benefit EdgeDB.
Lower performance in benchmarks is explained by an I/O bottleneck in the EdgeDB server, the queries are not less efficient. There will be performance improvements in subsequent releases.
[1] https://www.citylab.com/transportation/2018/01/how-toronto-t...
Specifically, in PostgreSQL such UUIDs can be generated using uuid_generate_v1mc()
Yes, although not in the initial release. EdgeDB _does_ support regular views, which, like the queries, can define arbitrary data hierarchies which can be treated like real object types. This topic deserves a separate blog post.
> built-in versioning
Not planned as a native feature as of now, although that's something that can be implemented on top with the query rewrite system.
> story on how to play it nice with backend languages
Immediately, EdgeDB supports a RESTful protocol with JSON as the exchange format. We will be adding native protocol implementations for major languages as well.
That would require introspecting arbitrary relational schemas and trying to represent them as an object graph. I don't think something like this can be done automatically and reliably.
That said, we have a tentative plan to introduce support for external databases (through FDWs, so not necessarily Postgres). The mapping specification would have to be explicit though.
User.<assignee[IS PullRequest].assignees[IS User].name
The reason for the FILTER clause is that you may want to write something like: FILTER User.name = 'Alice' OR User.<assignee[IS PullRequest].status = 'Open'
which is impossible to express if we were to simply filter each node set in the path separately. abstract type Text:
link body -> str
type Post extending Text
type Comment extending Text
And then query Text instances like this: SELECT Text {
body,
title := 'Post' IF Text IS Post ELSE
'Comment' IF Text IS Comment ELSE
'unknown'
};The main differentiating point of EdgeDB is EdgeQL (and native GraphQL support).
[1] https://mail.python.org/pipermail/linux-sig/2017-July/000029...
https://www.beanfield.com/residential/ https://www.coextro.com/