Skip to content

Commit

Permalink
feat(duckdb): implement _get_schema_using_query
Browse files Browse the repository at this point in the history
  • Loading branch information
cpcloud authored and kszucs committed Mar 30, 2022
1 parent 7342393 commit 93cd730
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 120 deletions.
6 changes: 6 additions & 0 deletions ibis/backends/duckdb/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,9 @@ def fetch_from_cursor(
):
df = cursor.cursor.fetch_df()
return schema.apply_to(df)

def _get_schema_using_query(self, query: str) -> sch.Schema:
"""Return an ibis Schema from a SQL string."""
with self.con.connect() as con:
rel = con.connection.c.query(query)
return sch.infer(rel)
118 changes: 0 additions & 118 deletions ibis/backends/duckdb/tests/test_parser.py

This file was deleted.

15 changes: 13 additions & 2 deletions ibis/backends/duckdb/parser.py → ibis/expr/datatypes/duckdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ def parse_type(text: str, default_decimal_parameters=(18, 3)) -> DataType:
lparen = spaceless_string("(")
rparen = spaceless_string(")")

lbracket = spaceless_string("[")
rbracket = spaceless_string("]")

langle = spaceless_string("<")
rangle = spaceless_string(">")

Expand Down Expand Up @@ -114,11 +117,18 @@ def angle_type():
return value_type

@p.generate
def array():
def list_array():
yield spaceless_string("list")
value_type = yield angle_type
return Array(value_type)

@p.generate
def pg_array():
value_type = yield non_pg_array_type
yield lbracket
yield rbracket
return Array(value_type)

@p.generate
def map():
yield spaceless_string("map")
Expand All @@ -143,5 +153,6 @@ def struct():
yield rangle
return Struct.from_tuples(field_names_types)

ty = primitive | decimal | array | map | struct
non_pg_array_type = primitive | decimal | list_array | map | struct
ty = pg_array | non_pg_array_type
return ty.parse(text)
120 changes: 120 additions & 0 deletions ibis/tests/expr/test_duckdb_datatype_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import pytest
from pytest import param

import ibis.expr.datatypes as dt
from ibis.expr.datatypes.duckdb import parse_type

EXPECTED_SCHEMA = dict(
a=dt.int64,
b=dt.int64,
c=dt.int64,
d=dt.boolean,
e=dt.boolean,
f=dt.boolean,
g=dt.binary,
h=dt.binary,
i=dt.binary,
j=dt.binary,
k=dt.date,
l=dt.float64,
m=dt.float64,
n=dt.Decimal(18, 3),
o=dt.Decimal(18, 3),
p=dt.Decimal(10, 3),
q=dt.int32,
r=dt.int32,
s=dt.int32,
t=dt.int32,
u=dt.interval,
v=dt.float32,
w=dt.float32,
x=dt.float32,
y=dt.int16,
z=dt.int16,
A=dt.int16,
B=dt.time,
C=dt.Timestamp('UTC'),
D=dt.Timestamp('UTC'),
E=dt.int8,
F=dt.int8,
G=dt.uint64,
H=dt.uint32,
I=dt.uint16,
J=dt.uint8,
K=dt.uuid,
L=dt.string,
M=dt.string,
N=dt.string,
O=dt.string,
P=dt.string,
Q=dt.Array(dt.int32),
R=dt.Map(dt.string, dt.int64),
S=dt.Struct.from_dict(
dict(
a=dt.int32,
b=dt.string,
c=dt.Array(dt.Map(dt.string, dt.Array(dt.float64))),
)
),
)


@pytest.mark.parametrize(
("column", "type"),
[
param(colname, type, id=type.lower())
for colname, type in [
("a", "BIGINT"),
("b", "INT8"),
("c", "LONG"),
("d", "BOOLEAN"),
("e", "BOOL"),
("f", "LOGICAL"),
("g", "BLOB"),
("h", "BYTEA"),
("i", "BINARY"),
("j", "VARBINARY"),
("k", "DATE"),
("l", "DOUBLE"),
("m", "FLOAT8"),
("n", "NUMERIC"),
("o", "DECIMAL"),
("p", "DECIMAL(10, 3)"),
("q", "INTEGER"),
("r", "INT4"),
("s", "INT"),
("t", "SIGNED"),
("u", "INTERVAL"),
("v", "REAL"),
("w", "FLOAT4"),
("x", "FLOAT"),
("y", "SMALLINT"),
("z", "INT2"),
("A", "SHORT"),
("B", "TIME"),
("C", "TIMESTAMP"),
("D", "DATETIME"),
("E", "TINYINT"),
("F", "INT1"),
("G", "UBIGINT"),
("H", "UINTEGER"),
("I", "USMALLINT"),
("J", "UTINYINT"),
("K", "UUID"),
("L", "VARCHAR"),
("M", "CHAR"),
("N", "BPCHAR"),
("O", "TEXT"),
("P", "STRING"),
("Q", "LIST<INTEGER>"),
("R", "MAP<STRING, BIGINT>"),
(
"S",
"STRUCT<a: INT, b: TEXT, c: LIST<MAP<TEXT, LIST<FLOAT8>>>>",
),
]
],
)
def test_parser(column, type):
ty = parse_type(type)
assert ty == EXPECTED_SCHEMA[column]

0 comments on commit 93cd730

Please sign in to comment.