<commit_before>module RethinkDB where

-- A Symbol is essentially an identifier, a way to refer to other
-- entities (tables, attributes, etc.) in the AST.
type Symbol = String

-- These are Aliases to symbols and are meant to clarify which
-- entities various parts of the AST refer to.
type TableName = Symbol   -- Reference to a table
type AttrName = Symbol    -- Reference to a JSON attribute
type DBName = Symbol      -- Reference to a database
type Var = Symbol         -- Reference to a variable/argument

-- A way to refer to tables in the AST. A user can be explicit
-- (i.e. specify database name where table belongs) or implicit
-- (i.e. just specify the table name, in which case the table will be
-- selected from the ones in the scope, and an error will be thrown if
-- the name is ambigious).
data TableRef = TableRef (Maybe DBName) TableName
                deriving Show

data Type = -- TODO

data Term
    = Var Var
    | Let [(Var, Term)] Term
    | Call Builtin [Term]
    | If Term Term Term

    -- Literals
    | Number JSONNumber
    | String String
    | Bool Bool
    | Null
    | Array [Term]
    | Map [(AttrName, Term)]

    -- no "And", "Or" needed; can be desugared to "If".
    | ViewAsStream View         -- turns a view into a stream

data Builtin
    = Not                       -- logical negation

    -- Map/record operations
    | GetAttr AttrName
    | HasAttr AttrName

    -- merges two maps, preferring the key-value pairs from its second argument
    -- in case of conflict. used eg. to do field update.
    | MapMerge

    -- Array operations
    | ArrayCons | ArrayConcat | ArraySlice | ArrayNth | ArrayLength

    -- Arithmetic & comparison operations
    | Add | Subtract | Multiply | Divide | Modulo
    | Compare Comparison
    -- don't need unary negation "-x", desugars to "0 - x".

    -- Stream operations
    | Filter Predicate
    | Map Mapping
    | OrderBy OrderDirection Mapping
    | Distinct Mapping
    | Limit Int
    | Count                     -- counts # of elements in a stream
    | Union                     -- merges streams in undefined order

    | StreamToArray
    | ArrayToStream

    | Reduce Reduction
    | GroupBy Mapping Reduction -- TODO: document

    -- Arbitrary javascript function.
    -- js funcs need to be type-annotated
    -- TODO: figure out precise semantics
    | Javascript ([Type], Type) String

data Comparison = EQ | NE | LT | LE | GT | GE

-- TODO: possibly reductions, mappings, predicates should be *either* lambdas,
-- as they are now, or Javascript functions. (We could just desugar the latter
-- to the former, though...)
data Reduction
    = Reduction {
        reductionBase :: Term,
        reductionArg1 :: Var,
        reductionArg2 :: Var,
        reductionBody :: Term
        }

data Mapping
    = Mapping {
        mappingArg :: Var,
        mappingBody :: Term
        }

data Predicate
    = Predicate {
        predicateArg :: Var,
        predicateBody :: Term
        }

data View
    = Table TableRef
    | FilterView View Predicate

data OrderDirection = Ascending | Descending

-- "magically" uses the query's type to determine whether to stream results?
data ReadQuery = ReadQuery Term

data WriteQuery
    = Update View (Var, Term)
    | Insert TableRef [Term]
    | InsertStream TableRef Stream -- or should this just be a ForEach?
    | ForEach Stream Var [WriteQuery]
<commit_msg>more qlspec3 revisions<commit_after>module RethinkDB where

-- A Symbol is essentially an identifier, a way to refer to other
-- entities (tables, attributes, etc.) in the AST.
type Symbol = String

-- These are Aliases to symbols and are meant to clarify which
-- entities various parts of the AST refer to.
type TableName = Symbol   -- Reference to a table
type AttrName = Symbol    -- Reference to a JSON attribute
type DBName = Symbol      -- Reference to a database
type Var = Symbol         -- Reference to a variable/argument

-- A way to refer to tables in the AST. A user can be explicit
-- (i.e. specify database name where table belongs) or implicit
-- (i.e. just specify the table name, in which case the table will be
-- selected from the ones in the scope, and an error will be thrown if
-- the name is ambigious).
data TableRef = TableRef (Maybe DBName) TableName
                deriving Show

data Type = -- TODO

-- TODO: some form of error handling
-- TODO: porcelain
-- TODO: concatmap
data Term
    = Var Var
    | Let [(Var, Term)] Term
    -- NB. can have terms under the builtin. think carefully about how to handle
    -- this in code that deals with ASTs.
    | Call Builtin [Term]
    | If Term Term Term
    -- `try e1 (v. e2)`
    -- runs and returns e1;
    -- if it fails, binds v to the error message and runs & returns e2.
    | Try Term (Var, Term)
    | Error String              -- raises an error with a given message

    -- Literals
    | Number JSONNumber
    | String String
    | Bool Bool
    | Null
    | Array [Term]
    | Map [(AttrName, Term)]

    -- no "And", "Or" needed; can be desugared to "If".
    | ViewAsStream View         -- turns a view into a stream

    -- `GetByKey tref attr expr`
    -- is porcelain for:
    --     try (nth 0 (filter tref (\x. x.attr == expr))) null
    | GetByKey TableRef AttrName Term

data Builtin
    = Not                       -- logical negation

    -- Map/record operations
    | GetAttr AttrName
    | HasAttr AttrName
    | PickAttrs [AttrName]      -- technically porcelain

    -- merges two maps, preferring the key-value pairs from its second argument
    -- in case of conflict. used eg. to do field update.
    | MapMerge

    -- Array operations
    | ArrayCons | ArrayConcat | ArraySlice | ArrayNth | ArrayLength

    -- Arithmetic & comparison operations
    | Add | Subtract | Multiply | Divide | Modulo
    | Compare Comparison
    -- don't need unary negation "-x", desugars to "0 - x".

    -- Stream operations
    | Filter Predicate
    | Map Mapping               -- mapping function has type (json -> json)
    | ConcatMap Mapping         -- mapping function has type (json -> stream)
    | OrderBy OrderDirection Mapping
    | Distinct Mapping
    | Limit Int
    | Length                    -- counts # of elements in a stream
    | Union                     -- merges streams in undefined order
    | Nth                       -- nth element from stream

    | StreamToArray
    | ArrayToStream

    | Reduce Reduction
    | GroupBy Mapping Reduction -- TODO: document

    -- Arbitrary javascript function.
    -- js funcs need to be type-annotated
    -- TODO: figure out precise semantics
    | Javascript ([Type], Type) String

    -- "Porcelain"
    | MapReduce Mapping Reduction

data Comparison = EQ | NE | LT | LE | GT | GE

-- TODO: possibly reductions, mappings, predicates should be *either* lambdas,
-- as they are now, or Javascript functions. (We could just desugar the latter
-- to the former, though...)
data Reduction
    = Reduction {
        reductionBase :: Term,
        reductionArg1 :: Var,
        reductionArg2 :: Var,
        reductionBody :: Term
        }

data Mapping
    = Mapping {
        mappingArg :: Var,
        mappingBody :: Term
        }

data Predicate
    = Predicate {
        predicateArg :: Var,
        predicateBody :: Term
        }

data View
    = Table TableRef
    | FilterView View Predicate
    -- TODO: pick closed/open-ness convention
    -- ie. does (range tref "a" 0 3) include or exclude rows where a = 0, 3?
    | RangeView View AttrName (Maybe Term, Maybe Term)

data OrderDirection = Ascending | Descending

-- "magically" uses the query's type to determine whether to stream results?
data ReadQuery = ReadQuery Term

-- TODO: how are we doing deletes?

-- tim proposes returning "null" from a mapping to indicate "delete this row"
-- for an update. GetByKey can also return "null" to indicate "no row found".

data WriteQuery
    = Update View Mapping
    -- TODO: how does insert work if we insert a row with a primary key that
    -- already exists in the table?
    | Insert TableRef [Term]
    | InsertStream TableRef Stream
    | ForEach Stream Var [WriteQuery]
    -- `PointUpdate tref attr key updater`
    -- updates THE row in tref with attr equal to key, using updater
    -- NB. very restricted: attrname MUST be primary key
    | PointUpdate Table AttrName Term Mapping

{'fraction_non_alphanumeric': 0.07889074826679417, 'fraction_numerical': 0.0019125029882859192, 'mean_word_length': 2.265807962529274, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1426524', 'n_tokens_mistral': 2354, 'n_tokens_neox': 2235, 'n_words': 1018}