Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Table types #2646

Closed
max-sixty opened this issue May 27, 2023 · 6 comments · Fixed by #4126
Closed

Table types #2646

max-sixty opened this issue May 27, 2023 · 6 comments · Fixed by #4126
Labels
language-design Changes to PRQL-the-language

Comments

@max-sixty
Copy link
Member

What's up?

In #2622 (comment), @aljazerzen makes an interesting suggestion re declaring tables. I'm moving here so we can keep that focused on the nulls question.

Well, my current idea on how to declare tables looks like this:

# table is just a declaration without a value
let foo <{
   id = int,
   name = str || null,
}>

I quite like this!

Only one question — should it be an array of these? e.g.

# table is just a declaration without a value
let foo <[{
   id = int,
   name = str || null,
}]>
@max-sixty max-sixty added the language-design Changes to PRQL-the-language label May 27, 2023
@aljazerzen
Copy link
Member

Only one question — should it be an array of these? e.g.

Oh yes, of course. It's a relation after all - an array of tuples.

This proposal does not introduce anything new, just says that any relational variables without values should be treated as database tables.

@max-sixty
Copy link
Member Author

Great!

Actually one more question — just the syntax: should the items be type definitions rather than =?

# table is just a declaration without a value
let foo <[{
   id<int>,
   name<str || null>,
}]>

@aljazerzen
Copy link
Member

I'd say no.

That's because this is an array of a single tuple:

let foo_type = [
   {id = int, name = str || null}
]

... the tuple fields are "a set of all ints" and "a set of all strings and the null value", but it's a normal variable nonetheless.

It's converted into a type only when <> is used:

let foo <foo_type>

@max-sixty
Copy link
Member Author

That's because this is an array of a single tuple:

let foo_type = [
   {id = int, name = str || null}
]

OK, I'm trying to build a mental model of this. The tuple's values are types, which give us the constraint of "a set of all ints" etc...


If so, I might have thought these would be equivalent:

let foo <[{
   id<int>,
   name<str || null>,
}]> = [{2, "foo"}]

and

let foo_type = [
   {id = int, name = str || null}
]

let foo<foo_type> = [{2, "foo"}]

...but my mental model is still a bit hazy.

@aljazerzen
Copy link
Member

This is the key concept: sets are values that can be converted to types, using < > operator.

let foo = [{a = 3, b = null}]

# foo is used as a value
let my_value = (foo | derive b = a + 1)

# foo is used as a type
let my_table <foo>;

This is possible because there a bit of overlap between "normal values" and "values that can be converted into types". In this case, I leveraged the fact that literals can be converted into a singleton type (a type that can hold only one value).

So < > is converting values to types, recursively.

@aljazerzen
Copy link
Member

Update: with #3786 we have separate grammars for types and expressions. This means my last comment is not relevant anymore and we can change the syntax of table declarations separately from the the grammar of value expressions.


For clarity there are a few more examples:

## a tuple type
type my_tuple = {id = int, b = string || null}

## a relational type
type my_relation = [my_tuple]

## equivalent to the above
type my_relation = [{id = int, b = string || null}]

## a table declaration
## We don't provide the value, only a relational type,
## so the compiler can assume that this variable exists
## as a table in the target database.
let my_table <my_relation>

## equivalent
let my_table <[my_tuple]>

## equivalent, again
let my_table <[{id = int, b = string || null}]>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
language-design Changes to PRQL-the-language
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants