Rayforce Rayforce ← Back to home
GitHub

Select, Update, Insert & Upsert

Query, mutate, and manage table data with Rayfall's declarative query syntax. All query forms compile to a fused DAG for morsel-driven parallel execution.

Select

The select form is the primary way to query tables. It supports projection, filtering, computed columns, and group-by aggregation through a single dictionary argument.

Basic Projection

Select all columns from a table (identity query):

; Create a sample table
(set t (table [sym price volume]
    (list [AAPL GOOG MSFT] [150 280 420] [500 400 900])))

; Select all rows and columns
(select {from: t})
; sym  price volume
; ---  ----- ------
; AAPL   150    500
; GOOG   280    400
; MSFT   420    900

Select specific columns with computed expressions:

(select {from: t cols: {sym: sym notional: (* price volume)}})
; sym  notional
; ---  --------
; AAPL    75000
; GOOG   112000
; MSFT   378000

Filtering with where:

The where: clause accepts any predicate expression. Predicates are pushed down through the DAG for early elimination of rows:

(select {from: t where: (> price 200)})
; sym  price volume
; ---  ----- ------
; GOOG   280    400
; MSFT   420    900

Combine multiple conditions:

(select {from: t where: (and (> price 100) (< volume 600))})
; sym  price volume
; ---  ----- ------
; AAPL   150    500
; GOOG   280    400

Group-by Aggregation

The by: clause groups rows by one or more key columns. Aggregation functions in cols: operate within each group:

(set trades (table [sym side price qty]
    (list [AAPL AAPL GOOG GOOG AAPL]
          [Buy Sell Buy Buy Buy]
          [150 152 280 282 149]
          [100 200 50 75 300])))

; Group by sym, aggregate price and qty
(select {from: trades by: {sym: sym}
         cols: {avg_price: (avg price)
                total_qty: (sum qty)
                n: (count price)}})
; sym  avg_price total_qty  n
; ---  --------- ---------  -
; AAPL     150.3       600  3
; GOOG       281       125  2

Group by multiple keys:

(select {from: trades by: {sym: sym side: side}
         cols: {total: (sum qty)}})
; sym  side total
; ---  ---- -----
; AAPL Buy    400
; AAPL Sell   200
; GOOG Buy    125

Filter + Group-by

Combine where: and by: in the same query. The filter is applied before grouping:

(select {from: trades
         where: (== side 'Buy)
         by: {sym: sym}
         cols: {buy_qty: (sum qty)}})
; sym  buy_qty
; ---  -------
; AAPL     400
; GOOG     125

Update

The update form modifies columns in-place on a quoted table variable. It supports the same where: and by: clauses as select.

Column Mutation

Update one or more columns with a new expression. The table is modified in-place when the first argument is a quoted symbol:

(set tab (table [sym price volume]
    (list [AAPL GOOG MSFT] [102 203 99] [500 400 900])))

; Increment volume by 1
(update {volume: (+ 1 volume) from: 'tab})
; sym  price volume
; ---  ----- ------
; AAPL   102    501
; GOOG   203    401
; MSFT    99    901

Conditional Update

Apply updates only to rows matching a predicate:

; Apply a custom function to price where volume == 901
(update {price: ((fn [x] (+ x 11)) price) from: 'tab where: (== volume 901)})
; sym  price volume
; ---  ----- ------
; AAPL   102    501
; GOOG   203    401
; MSFT   110    901

Set a column to a constant for matching rows:

(update {price: 0 from: 'tab where: (== volume 901)})

Update with Group-by

Combine where: and by: for grouped conditional updates:

(update {price: 0 from: 'tab by: sym where: (> volume 400)})

Insert

The insert function appends rows to a table. It accepts rows as a list of atoms, a list of vectors, a dictionary, or another table. Column order is flexible — missing columns receive null values.

Insert from List

(set t (table [ID Name Value]
    (list [1 2 3] ['Alice 'Bob 'Charlie] [10.0 20.0 30.0])))

; Insert a single record
(set t (insert t (list 4 'David 40.0)))

; Insert multiple records (list of vectors)
(set t (insert t (list [5 6] ['Eve 'Frank] [50.0 60.0])))

Insert from Dictionary

Dictionaries allow columns in any order. Missing columns are filled with null:

; Columns in different order
(set t (insert t (dict [Value Name ID] (list 120.0 'Leo 12))))

; Partial columns — Value will be null
(set t (insert t (dict [ID Name] (list 14 'Nancy))))

Insert from Table

; Append another table (column order can differ)
(set t (insert t (table [Value ID Name]
    (list [180.0 190.0] [18 19] ['Rose 'Sam]))))

In-place Insert

Pass a quoted table symbol for in-place mutation:

; Mutate table in-place (no set needed)
(insert 't (dict [Value Name ID] (list 200.0 'Tom 20)))

Upsert

The upsert function inserts new rows or updates existing ones based on a key column index. The second argument is the 0-based column index used as the match key.

Insert New Rows

(set t (table [ID Name Value]
    (list [1 2 3] ['Alice 'Bob 'Charlie] [10.0 20.0 30.0])))

; Upsert on column 1 (ID). ID=4 is new, so insert.
(set t (upsert t 1 (list 4 'David 40.0)))

Update Existing Rows

; ID=2 exists — update in place
(set t (upsert t 1 (list 2 'Bobby 25.0)))
; ID Name    Value
; -- ----    -----
;  1 Alice    10.0
;  2 Bobby    25.0  ← updated
;  3 Charlie  30.0
;  4 David    40.0

Upsert from Dictionary

Like insert, columns can be in any order:

; Columns reordered — upsert matches on ID
(set t (upsert t 1 (dict [Name Value ID] (list 'Bobby2 22.0 2))))

; Mixed insert + update in one call
(set t (upsert t 1 (dict [Value ID Name]
    (list [35.0 140.0] [3 14] ['Charlie2 'Nancy]))))

In-place Upsert

(upsert 't 1 (dict [Value Name ID] (list 170.0 'Quinn 17)))

Delete

The delete function removes rows matching a predicate. It returns a new table without the matched rows.

(set t (table [x y] (list [1 2 3 4] [A B C D])))

; Delete rows where x > 2
(set t (delete t (> x 2)))
; x y
; - -
; 1 A
; 2 B

Quick Reference

Form Syntax Description
select (select {from: t cols: {...} where: pred by: {...}}) Query with projection, filtering, and grouping
update (update {col: expr from: 't where: pred}) In-place column mutation
insert (insert t rows) or (insert 't rows) Append rows (list, dict, or table)
upsert (upsert t key-idx rows) Insert or update by key column
delete (delete t pred) Remove matching rows
Execution model. All select and update queries compile to a lazy DAG. The optimizer applies predicate pushdown, filter reordering, operator fusion, and dead-code elimination before the fused morsel-driven executor processes data in 1024-element chunks.