canonical / sqlair

Friendly type mapping for SQL databases
Apache License 2.0
17 stars 9 forks source link

Add parsing support for input expressions in INSERT statements #131

Closed Aflynn50 closed 7 months ago

Aflynn50 commented 8 months ago

This PR adds parsing support for two new forms of input expression. These will allow ergonomic type mapping with INSERT statements. The new forms match the existing forms of output expression. More information can be found in Spec PL014.

The new forms of input expression are:

1. Insert all Go values on the right hand side into the table.

INSERT INTO table (*) VALUES (<accessorList>)

<accessorList> is a comma separated list of Go object accessors.

The object accessors are the form: $Struct.tag - This will cause the value in the field with the “db” tag tag of Struct to be inserted into the column with the name tag. $Map.key will cause the value at location key in Map to be inserted into the column key. $Struct.* will cause all values in fields with “db” tags in Struct to be inserted into the column named by the tag.

This syntax allows columns from multiple Go objects to be inserted without separately enumerating the columns. It is expected to be used in the majority of situations.

2. Insert specific columns from Go value.

The syntax makes it easy to insert a small subset of columns from types containing many.

INSERT INTO table (<colList>) VALUES (<accessorList>)

<colList> is a comma separated list of column names and is a comma separated list of Go object accessors.

The different object accessors having the following meanings: $Struct.tag - The tag must match a column <colList>. The value in the struct will be inserted into the column tag. $Map.key - The key must match a column <colList>. The value at key in the map will be inserted into the column key. $Struct.* - Any values with tags matching a column in <colList> will be inserted. $Map.* - columns in <colList> that are not captured by another object assessor are drawn from the map. It must be unambiguous which columns are to be found in Map when the query is prepared or an error will be returned (e.g. a query with two $Map.* accessors is ambiguous).