Skip to content

Commit 31e7741

Browse files
feat: add sqlContext (#185)
* feat: add sqlContext * pr feedback
1 parent 137a2d9 commit 31e7741

File tree

7 files changed

+512
-67
lines changed

7 files changed

+512
-67
lines changed

Cargo.toml

+67-66
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ crate-type = ["cdylib", "lib"]
1515
[dependencies]
1616
ahash = "0.8.7"
1717
bincode = "1.3.3"
18-
napi = { version = "2.14.2", default-features = false, features = [
19-
"napi8",
20-
"serde-json",
18+
napi = { version = "2.16.0", default-features = false, features = [
19+
"napi8",
20+
"serde-json",
2121
] }
22-
napi-derive = { version = "2.14.6", default-features = false }
22+
napi-derive = { version = "2.16.0", default-features = false }
2323
polars-core = { git = "https://github.com/pola-rs/polars.git", rev = "3cf4897e679b056d17a235d48867035265d43cdc", default-features = false }
2424
polars-io = { git = "https://github.com/pola-rs/polars.git", rev = "3cf4897e679b056d17a235d48867035265d43cdc", default-features = false }
2525
polars-lazy = { git = "https://github.com/pola-rs/polars.git", rev = "3cf4897e679b056d17a235d48867035265d43cdc", default-features = false }
@@ -30,68 +30,69 @@ either = "1.9"
3030

3131
[dependencies.polars]
3232
features = [
33-
"binary_encoding",
34-
"rolling_window",
35-
"json",
36-
"dynamic_group_by",
37-
"zip_with",
38-
"simd",
39-
"lazy",
40-
"strings",
41-
"temporal",
42-
"random",
43-
"object",
44-
"fmt",
45-
"performant",
46-
"dtype-full",
47-
"rows",
48-
"round_series",
49-
"is_unique",
50-
"is_in",
51-
"is_first_distinct",
52-
"asof_join",
53-
"cross_join",
54-
"dot_product",
55-
"concat_str",
56-
"row_hash",
57-
"reinterpret",
58-
"mode",
59-
"extract_jsonpath",
60-
"cum_agg",
61-
"rolling_window",
62-
"repeat_by",
63-
"interpolate",
64-
"ewma",
65-
"rank",
66-
"propagate_nans",
67-
"diff",
68-
"pct_change",
69-
"moment",
70-
"diagonal_concat",
71-
"abs",
72-
"dot_diagram",
73-
"dataframe_arithmetic",
74-
"json",
75-
"string_encoding",
76-
"product",
77-
"ndarray",
78-
"unique_counts",
79-
"log",
80-
"serde-lazy",
81-
"partition_by",
82-
"pivot",
83-
"semi_anti_join",
84-
"parquet",
85-
"to_dummies",
86-
"ipc",
87-
"avro",
88-
"list_eval",
89-
"arg_where",
90-
"timezones",
91-
"peaks",
92-
"string_pad",
93-
"cov",
94-
"group_by_list",
33+
"binary_encoding",
34+
"rolling_window",
35+
"json",
36+
"dynamic_group_by",
37+
"zip_with",
38+
"simd",
39+
"lazy",
40+
"strings",
41+
"temporal",
42+
"random",
43+
"object",
44+
"fmt",
45+
"performant",
46+
"dtype-full",
47+
"rows",
48+
"round_series",
49+
"is_unique",
50+
"is_in",
51+
"is_first_distinct",
52+
"asof_join",
53+
"cross_join",
54+
"dot_product",
55+
"concat_str",
56+
"row_hash",
57+
"reinterpret",
58+
"mode",
59+
"extract_jsonpath",
60+
"cum_agg",
61+
"rolling_window",
62+
"repeat_by",
63+
"interpolate",
64+
"ewma",
65+
"rank",
66+
"propagate_nans",
67+
"diff",
68+
"pct_change",
69+
"moment",
70+
"diagonal_concat",
71+
"abs",
72+
"dot_diagram",
73+
"dataframe_arithmetic",
74+
"json",
75+
"string_encoding",
76+
"product",
77+
"ndarray",
78+
"unique_counts",
79+
"log",
80+
"serde-lazy",
81+
"partition_by",
82+
"pivot",
83+
"semi_anti_join",
84+
"parquet",
85+
"to_dummies",
86+
"ipc",
87+
"avro",
88+
"list_eval",
89+
"arg_where",
90+
"timezones",
91+
"peaks",
92+
"string_pad",
93+
"cov",
94+
"group_by_list",
95+
"sql",
9596
]
9697
git = "https://github.com/pola-rs/polars.git"
9798
rev = "3cf4897e679b056d17a235d48867035265d43cdc"

__tests__/sql.test.ts

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import pl from "@polars";
2+
describe("sql", () => {
3+
test("execute", () => {
4+
const df = pl.DataFrame({
5+
values: [
6+
["aa", "bb"],
7+
[null, "cc"],
8+
["dd", null],
9+
],
10+
});
11+
12+
const ctx = pl.SQLContext({ df });
13+
const actual = ctx.execute("SELECT * FROM df").collectSync();
14+
15+
expect(actual).toFrameEqual(df);
16+
const actual2 = ctx.execute("SELECT * FROM df", { eager: true });
17+
expect(actual2).toFrameEqual(df);
18+
});
19+
20+
test("register and query dataframe", () => {
21+
const df = pl.DataFrame({ hello: ["world"] });
22+
const ctx = pl.SQLContext();
23+
ctx.register("frame_data", df);
24+
const actual = ctx.execute("SELECT * FROM frame_data", { eager: true });
25+
26+
const expected = pl.DataFrame({ hello: ["world"] });
27+
28+
expect(actual).toFrameEqual(expected);
29+
ctx.register("null_frame", null);
30+
31+
const actual2 = ctx.execute("SELECT * FROM null_frame", { eager: true });
32+
const expected2 = pl.DataFrame();
33+
expect(actual2).toFrameEqual(expected2);
34+
});
35+
test("register many", () => {
36+
const lf1 = pl.DataFrame({ a: [1, 2, 3], b: ["m", "n", "o"] });
37+
const lf2 = pl.DataFrame({ a: [2, 3, 4], c: ["p", "q", "r"] });
38+
39+
// Register multiple DataFrames at once
40+
const ctx = pl.SQLContext().registerMany({ tbl1: lf1, tbl2: lf2 });
41+
const tables = ctx.tables();
42+
43+
expect(tables).toEqual(expect.arrayContaining(["tbl1", "tbl2"]));
44+
});
45+
test("inspect", () => {
46+
const df = pl.DataFrame({
47+
a: [1, 2, 3],
48+
b: ["m", "n", "o"],
49+
});
50+
51+
const ctx = pl.SQLContext({ df });
52+
const actual = ctx[Symbol.for("nodejs.util.inspect.custom")]();
53+
54+
const expected = "SQLContext: {df}";
55+
56+
expect(actual).toEqual(expected);
57+
});
58+
test("constructor with LazyFrames", () => {
59+
const lf1 = pl.DataFrame({ a: [1, 2, 3], b: ["m", "n", "o"] }).lazy();
60+
const lf2 = pl.DataFrame({ a: [2, 3, 4], c: ["p", "q", "r"] }).lazy();
61+
62+
const ctx = pl.SQLContext({ tbl1: lf1, tbl2: lf2 });
63+
const tables = ctx.tables();
64+
expect(tables).toEqual(expect.arrayContaining(["tbl1", "tbl2"]));
65+
});
66+
test("unregister", () => {
67+
const df = pl.DataFrame({ hello: ["world"] });
68+
const df2 = pl.DataFrame({ hello: ["world"] });
69+
const df3 = pl.DataFrame({ hello: ["world"] });
70+
const ctx = pl.SQLContext({ df, df2, df3 });
71+
72+
ctx.unregister("df");
73+
74+
const tables = ctx.tables();
75+
expect(tables).toEqual(["df2", "df3"]);
76+
77+
ctx.unregister(["df2", "df3"]);
78+
const tables2 = ctx.tables();
79+
expect(tables2).toEqual([]);
80+
});
81+
});

polars/index.ts

+16
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ export * from "./lazy/dataframe";
1717
export * from "./lazy";
1818
import * as lazy from "./lazy";
1919
export * from "./types";
20+
import * as sql from "./sql";
21+
export type { SQLContext } from "./sql";
22+
2023
export type { GroupBy } from "./groupby";
2124
export namespace pl {
2225
export import Expr = lazy.Expr;
@@ -109,6 +112,19 @@ export namespace pl {
109112
export import list = lazy.list;
110113
export import when = lazy.when;
111114
export const version = pli.version();
115+
116+
/**
117+
* Run SQL queries against DataFrame/LazyFrame data.
118+
*
119+
* @warning This functionality is considered **unstable**, although it is close to being
120+
* considered stable. It may be changed at any point without it being considered
121+
* a breaking change.
122+
*/
123+
export function SQLContext(
124+
frames?: Record<string, DataFrame | LazyDataFrame>,
125+
): sql.SQLContext {
126+
return new sql.SQLContext(frames);
127+
}
112128
}
113129
// eslint-disable-next-line no-undef
114130
export default pl;

0 commit comments

Comments
 (0)