https://github.com/yancya/relationizer
Relationizer create evaluatable string as SQL
https://github.com/yancya/relationizer
sql
Last synced: about 2 months ago
JSON representation
Relationizer create evaluatable string as SQL
- Host: GitHub
- URL: https://github.com/yancya/relationizer
- Owner: yancya
- License: mit
- Created: 2016-09-09T04:24:45.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2026-02-12T20:10:37.000Z (about 2 months ago)
- Last Synced: 2026-02-13T03:35:17.963Z (about 2 months ago)
- Topics: sql
- Language: Ruby
- Homepage:
- Size: 37.1 KB
- Stars: 3
- Watchers: 2
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# Relationizer
A Ruby gem that converts `Array` into SQL relation literals. Supports BigQuery and PostgreSQL.
## Installation
```ruby
gem 'relationizer'
```
```
$ bundle install
```
## Usage
`include` the backend module you need and call `create_relation_literal(schema, tuples)`.
- `schema` — A Hash of column names to types. Set the value to `nil` to auto-infer the type from the tuples.
- `tuples` — Row data as `Array`.
### BigQuery
```ruby
require 'relationizer/big_query'
class MyQuery
include Relationizer::BigQuery
end
q = MyQuery.new
q.create_relation_literal(
{ id: nil, name: nil },
[[1, 'hoge'], [2, 'fuga']]
)
#=> "SELECT * FROM UNNEST(ARRAY>[(1, 'hoge'), (2, 'fuga')])"
```
#### Auto type inference
| Ruby type | BigQuery type |
|-----------------------|---------------|
| `Integer` | INT64 |
| `Float` / `BigDecimal` | FLOAT64 |
| `String` | STRING |
| `TrueClass` / `FalseClass` | BOOL |
| `Time` / `DateTime` | TIMESTAMP |
| `Date` | DATE |
| `Array` | ARRAY |
#### Manual type specification
Pass a Symbol as the schema value to override auto-inference. Useful when a column contains mixed types or when tuples are empty.
```ruby
# Force ratio column to FLOAT64 (mixed Integer and Float)
q.create_relation_literal(
{ id: nil, ratio: :FLOAT64 },
[[1, 1], [2, 3.14]]
)
#=> "SELECT * FROM UNNEST(ARRAY>[(1, 1), (2, 3.14)])"
# Empty tuples (manual type specification is required)
q.create_relation_literal(
{ id: :INT64, name: :STRING },
[]
)
#=> "SELECT * FROM UNNEST(ARRAY>[])"
```
#### Array columns
```ruby
q.create_relation_literal(
{ id: nil, name: nil, combination: nil },
[[1, 'hoge', [1, 2, 3]], [2, 'fuga', [4, 5, 6]]]
)
#=> "SELECT * FROM UNNEST(ARRAY>>[(1, 'hoge', [1, 2, 3]), (2, 'fuga', [4, 5, 6])])"
```
#### Single column
BigQuery does not support single-column STRUCTs in UNNEST, so a dummy column is added internally. Only the original column is returned in the SELECT.
```ruby
q.create_relation_literal(
{ id: nil },
[[1], [2], [3]]
)
#=> "SELECT id FROM UNNEST(ARRAY>[(1, NULL), (2, NULL), (3, NULL)])"
```
### PostgreSQL
```ruby
require 'relationizer/postgresql'
class MyQuery
include Relationizer::Postgresql
end
q = MyQuery.new
q.create_relation_literal(
{ id: nil, name: nil },
[[1, 'hoge'], [2, 'fuga']]
)
#=> %Q{SELECT "id"::INT8, "name"::TEXT FROM (VALUES('1', 'hoge'), ('2', 'fuga')) AS t("id", "name")}
```
#### Auto type inference
| Ruby type | PostgreSQL type |
|-----------------------|-----------------|
| `Integer` | INT8 |
| `Float` | FLOAT8 |
| `BigDecimal` | DECIMAL |
| `String` | TEXT |
| `TrueClass` / `FalseClass` | BOOLEAN |
| `Time` / `DateTime` | TIMESTAMPTZ |
| `Date` | DATE |
#### NULL
`nil` values are converted to SQL `NULL`.
```ruby
q.create_relation_literal(
{ id: nil },
[[1], [nil]]
)
#=> %Q{SELECT "id"::INT8 FROM (VALUES('1'), (NULL)) AS t("id")}
```
## Errors
- `ReasonlessTypeError` — Raised when types are mixed within a single column (e.g. Integer and String in the same column)
- `TypeNotFoundError` (BigQuery only) — Raised when tuples are empty and types are not manually specified
## License
[MIT License](http://opensource.org/licenses/MIT)