class Rotor::Translator

Translates the tree of a query's block (Meta::Expr, Quarz's docs/14 §6) to SQL, with the values its captures had when the query was built. The block's row is its receiver (where { age > 18 }) or its parameter (where { |u| u.age > 18 }), one per table in a join (where { |u, p| p.user_id == u.id }); a call of a column's getter on a row is the column, and on a model the block captured, its value.

/home/runner/work/rotor/rotor/src/translate.qz:56

Constants

OR: Int

Precedences, loosest first (PostgreSQL's order).

/home/runner/work/rotor/rotor/src/translate.qz:58

AND: Int

/home/runner/work/rotor/rotor/src/translate.qz:59

NOT: Int

/home/runner/work/rotor/rotor/src/translate.qz:60

IS: Int

/home/runner/work/rotor/rotor/src/translate.qz:61

CMP: Int

/home/runner/work/rotor/rotor/src/translate.qz:62

LIKE: Int

/home/runner/work/rotor/rotor/src/translate.qz:63

OTHER: Int

/home/runner/work/rotor/rotor/src/translate.qz:64

ADD: Int

/home/runner/work/rotor/rotor/src/translate.qz:65

MUL: Int

/home/runner/work/rotor/rotor/src/translate.qz:66

ATOM: Int

/home/runner/work/rotor/rotor/src/translate.qz:67

COMPARISONS: Hash[Symbol, String]

/home/runner/work/rotor/rotor/src/translate.qz:69

ARITHMETIC: Hash[Symbol, String]

/home/runner/work/rotor/rotor/src/translate.qz:70

INT_DIV: Meta::MethodRef

The overloads whose SQL differs from the operator's: Int#/(Int) floors and Int#%(Int) takes the divisor's sign; Int#/(Float) is a plain /.

/home/runner/work/rotor/rotor/src/translate.qz:75

INT_MOD: Meta::MethodRef

/home/runner/work/rotor/rotor/src/translate.qz:76

INT_BY_FLOAT: Meta::MethodRef

/home/runner/work/rotor/rotor/src/translate.qz:77

NONE: Int

What row_in gives for what is not a row, and for a self that may be any receiver's.

/home/runner/work/rotor/rotor/src/translate.qz:89

ANY: Int

/home/runner/work/rotor/rotor/src/translate.qz:90

Class methods

def self.called[A, B, R](&q: Quoted[(A, B) -> R]) -> Meta::MethodRef

The method q's body calls.

/home/runner/work/rotor/rotor/src/translate.qz:80

def self.new(sources: Array[Rotor::Source], captures: Array[Object], file: String, scopes: Array[Rotor::Scope], guards: Rotor::Guards = …, non_null: Array[[Int, Symbol]] = …) -> Rotor::Translator

/home/runner/work/rotor/rotor/src/translate.qz:118

def self.of(sources: Array[Rotor::Source], expr: Meta::Expr, captures: Array[Object], file: String) -> [Rotor::Translator, Meta::Expr]

The translator of a quoted block over the rows of sources, and the block's one expression.

/home/runner/work/rotor/rotor/src/translate.qz:128

def self.body(expr: Meta::Expr, file: String) -> [Array[Symbol], Meta::Expr]

A block's parameters and its one expression.

/home/runner/work/rotor/rotor/src/translate.qz:136

def self.scope(params: Array[Symbol], tables: Array[Int]) -> Rotor::Scope

The scope of a block over the rows of tables (indexes among the query's): its receiver when it has no parameters (the row of a single table), else its parameters, one per table (the first parameter for a single table).

/home/runner/work/rotor/rotor/src/translate.qz:152

def self.line_of(e: Meta::Expr) -> Int

The line of e.

/home/runner/work/rotor/rotor/src/translate.qz:175

def self.meet?(ls: Array[Type[Object]], rs: Array[Type[Object]]) -> Bool

Whether values of the classes ls and of rs (nil aside) can be equal: a class in both, Int and Float, nil only or a class the translator does not know (Object) on either side.

/home/runner/work/rotor/rotor/src/translate.qz:314

def self.never_equal(ls: Array[Type[Object]], rs: Array[Type[Object]]) -> String

"a String and a Bool are never equal".

/home/runner/work/rotor/rotor/src/translate.qz:321

def self.a(k: Type[Object]) -> String

"a String", "an Int".

/home/runner/work/rotor/rotor/src/translate.qz:326

def self.test_error(e: Meta::Expr, what: String, file: String) -> String

The error for e, where what (an && or || of an operand other than a Bool) is a value.

/home/runner/work/rotor/rotor/src/translate.qz:346

def self.value_error(e: Meta::Expr, what: String, file: String) -> String

The error for e, which is NULL where what is, used as a value.

/home/runner/work/rotor/rotor/src/translate.qz:351

def self.nil_advice(what: String) -> String

What to do when what can be NULL is not a column, which nil? tells nothing of in SQL: a nil captured or written.

/home/runner/work/rotor/rotor/src/translate.qz:358

def self.column_named?(e: Meta::Expr, what: String) -> Bool

Whether what is shown in e as a call of a getter on a row or self: a column (not a capture, nor a captured model's value).

/home/runner/work/rotor/rotor/src/translate.qz:365

def self.show(e: Meta::Expr) -> String

e as Quarz source, for messages (a row's receiver left implicit).

/home/runner/work/rotor/rotor/src/translate.qz:383

def self.shown_operand(e: Meta::Expr) -> String

show(e), parenthesized when it is an operator's.

/home/runner/work/rotor/rotor/src/translate.qz:420

def self.label(m: Meta::MethodRef) -> String

m for messages: `Int#>`, `Rotor::SQL.lower`.

/home/runner/work/rotor/rotor/src/translate.qz:859

def self.null?(s: Rotor::Sql) -> Bool

Whether s is nil: a known nil, or an if nil either way.

/home/runner/work/rotor/rotor/src/translate.qz:1044

def self.order_key(s: Rotor::Sql) -> Rotor::Sql

s as an order key: an if nil either way (NULL, a constant PostgreSQL refuses there) typed.

/home/runner/work/rotor/rotor/src/translate.qz:1048

def self.union(xs: Array[Type[Object]], ys: Array[Type[Object]]) -> Array[Type[Object]]

xs and the classes of ys not in it.

/home/runner/work/rotor/rotor/src/translate.qz:1134

Methods

def guards -> Array[Rotor::Guard]

The kinds of captured values the translation so far holds for: the same tree with captures of these kinds translates the same, up to the values of its Rotor::Piece::Bound pieces.

/home/runner/work/rotor/rotor/src/translate.qz:124

def inner(sources: Array[Rotor::Source], scope: Rotor::Scope) -> Rotor::Translator

This translator for a block inside the one it translates, whose scope is scope, over sources (the tables a for has joined so far).

/home/runner/work/rotor/rotor/src/translate.qz:165

def row_of(e: Meta::Expr) -> Int

The table whose row e is (an index among the query's), NONE for none.

/home/runner/work/rotor/rotor/src/translate.qz:169

def file -> String

The file the block is written in.

/home/runner/work/rotor/rotor/src/translate.qz:172

def sql(e: Meta::Expr) -> Rotor::Sql

e as SQL (made once for each mode and facts: @sqls).

/home/runner/work/rotor/rotor/src/translate.qz:194

def operand(e: Meta::Expr, typed: Bool = …) -> Rotor::Sql

e as SQL where it is a value, not a condition: an update's value, an order's key, an operand. A comparison that can be NULL (Sql#tri) is refused: NULL is not false there.

/home/runner/work/rotor/rotor/src/translate.qz:283

def one_type(e: Meta::Expr) -> Void

Refuses e as a value when its classes are more than one SQL type holds (a Bool and another value, a String and an Int): a SQL CASE or COALESCE of them is an error in PostgreSQL. Ints and Floats meet in double precision; nil and what the translator does not know the class of (Object) meet anything.

/home/runner/work/rotor/rotor/src/translate.qz:301

def valued_check(e: Meta::Expr) -> Void

one_type of e as a value (an order key).

/home/runner/work/rotor/rotor/src/translate.qz:309

def value(e: Meta::Expr) -> Rotor::Sql

e translated as a value (@value), its refusals left to the caller (operand).

/home/runner/work/rotor/rotor/src/translate.qz:330

def column_of(e: Meta::Expr) -> [Int, Rotor::Column]?

The table and column e is (a column's getter called on a row), or nil.

/home/runner/work/rotor/rotor/src/translate.qz:431

def reads(e: Meta::Expr) -> Array[Array[Rotor::Column]?]

The columns e reads of each table's row, in the table's order, nil for one whose row it may read more of: it calls another method of the row or passes the row on (its value is computed in Quarz, Rotor::Query#select). An association's getter reads the key it needs.

/home/runner/work/rotor/rotor/src/translate.qz:450

def untranslatable(what: String, line: Int) -> Nothing

Raises the error for what at line.

/home/runner/work/rotor/rotor/src/translate.qz:463

def classes(e: Meta::Expr) -> Array[Type[Object]]

The classes e may have in Quarz, as translated: a column's class, a known value's (Nil for nil: a literal, a capture, a captured model's column, an if without else), a comparison's Bool, arithmetic's by its operands' (Int only from two Ints). An if gives its branches' (only the one a known condition takes, as sql does). A column that can be NULL (past the nil? facts) gives Nil as well, so an update refuses it into a non-null column. For an update to check its value against the column, and a condition to be tested for its truthiness: PostgreSQL would convert another class on assignment (round a double precision into a bigint, write a number as text) and refuses one as a condition. (Read as a translation does, guarded.)

l && r and l || r are Quarz's: the classes of what makes the left operand the value (its falsy ones for &&, its truthy ones for ||) and the right operand's.

/home/runner/work/rotor/rotor/src/translate.qz:1069