src/expr

This module contains a simple SQL expression parser which parses select_expr and expr in WHERE/HAVING/ON conditions. Most of Spell's functionalities are made possible because of this parser. Currently, it cannot parse a full SQL.

Example:
parseExpr('COUNT(1) AS count')
// => { type: 'alias', value: 'count',
//      args: [ { type: 'func', name: 'count', args: [ ... ] } ] }

Members

(inner, constant) BINARY_OPERATORS

A (modestly) simplified list of binary operators.

(inner, constant) LOGICAL_OPERATORS

A list of binary logical operators.

(inner, constant) MODIFIERS

A (drastically) simplified list of supported modifiers.

(inner, constant) OPERATOR_ALIAS_MAP

A map of operator alias. Operators like && will be translated into and to make ast handling a bit easier.

(inner, constant) PRECEDENCES

A (drastically) simplified list of operators ordered in priority precedences.

  • https://dev.mysql.com/doc/refman/5.7/en/operator-precedence.html

(inner, constant) UNARY_OPERATORS

A (drastically) simplified list of unary operators.

Methods

(inner) copyExpr(ast, fn)

Walk through an ast with returned tokens preferred over the originals, which is convenient to update the ast.

Parameters:
Name Type Description
ast Object
fn function
Example:
// update all of the identifiers' qualifiers:
copyExpr(ast, ({ type, value }) => {
  if (type == 'id') return { type, qualifiers: ['posts'], value }
});

(inner) findExpr(spell, opts)

Traversing ast to find expresssion that matches opts.

Parameters:
Name Type Description
spell Spell
opts Object

(inner) parseExpr(str, …values) → {Object}

Parameters:
Name Type Attributes Description
str string
values * <repeatable>
Returns:
Type:
Object
Example:
parseExpr('COUNT(id) + 1')
  -> { type: 'op',
       name: '+',
       args:
        [ { type: 'func',
            name: 'count',
            args: [ { type: 'id', value: 'id' } ] },
          { type: 'literal', value: 1 } ] }

// Logical operators can be used in conditional expressions too.
parseExpr('YEAR(createdAt) <= 2017 AND MONTH(createdAt) BETWEEN 4 AND 9')
  -> { type: 'op',
       name: 'and',
       args:
        [ { type: 'op',
            name: '<=',
            args:
             [ { type: 'func', name: 'year',
                 args: [ { type: 'id', value: 'createdAt' } ] },
               { type: 'literal', value: 2017 } ] },
          { type: 'op',
            name: 'between',
            args:
             [ { type: 'func',
                 name: 'month',
                 args: [ { type: 'id', value: 'createdAt' } ] },
               { type: 'literal', value: 4 },
               { type: 'literal', value: 9 } ] } ] }

(inner) parseExprList(str, …values) → {Array.<Object>}

Parse sql expressions into ast for validations and sanitizations.

Parameters:
Name Type Attributes Description
str string
values * <repeatable>
Returns:
Type:
Array.<Object>

(inner) precedes(left, right)

Compare the precedence of two operators. Operators with lower indices have higher priorities.

Parameters:
Name Type Description
left string

name of the left operator

right string

name of the right operator

Example:
precedes('and', 'or')  // => -1
precedes('and', 'and') // => 0
precedes('+', '/') // => 1

(inner) walkExpr(ast, fn)

Walk through an ast, starting from the root token.

Parameters:
Name Type Description
ast Object
fn function