├── actions
├── image
│ └── TAG
└── runner
│ ├── ufw_before_rules.txt
│ ├── multipass.sh
│ └── cloud-init.yaml
├── .prettierignore
├── lib
├── src
│ ├── wasm_main.cc
│ ├── extensions
│ │ ├── json_extension.cc
│ │ └── parquet_extension.cc
│ └── utils
│ │ └── thread.cc
├── include
│ └── duckdb
│ │ └── web
│ │ ├── arrow_stream_factory.h
│ │ ├── extensions
│ │ ├── json_extension.h
│ │ └── parquet_extension.h
│ │ ├── utils
│ │ ├── thread.h
│ │ ├── spin_mutex.h
│ │ ├── shared_mutex.h
│ │ ├── parallel.h
│ │ ├── debug.h
│ │ └── parking_lot.h
│ │ ├── io
│ │ ├── file_page_defaults.h
│ │ └── glob.h
│ │ ├── test
│ │ └── config.h
│ │ ├── environment.h
│ │ ├── insert_options.h
│ │ ├── arrow_type_mapping.h
│ │ ├── udf.h
│ │ ├── arrow_insert_options.h
│ │ ├── json_dataview.h
│ │ ├── functions
│ │ └── table_function_relation.h
│ │ └── json_typedef.h
├── .gitignore
├── .clang-format
├── README.md
├── test
│ ├── tester.cc
│ ├── bugs_test.cc
│ └── ifstream_test.cc
└── cmake
│ ├── gflags.cmake
│ ├── rapidjson.cmake
│ └── spdlog.cmake
├── tools
└── dataprep
│ ├── .gitignore
│ ├── Cargo.toml
│ └── src
│ └── error.rs
├── data
├── .gitignore
├── test.csv
└── test.json
├── examples
├── bare-node
│ ├── .gitignore
│ ├── package.json
│ └── index.cjs
├── esbuild-node
│ ├── .gitignore
│ ├── bundle.mjs
│ ├── tsconfig.json
│ ├── package.json
│ └── index.mjs
├── bare-browser
│ ├── .gitignore
│ ├── node_modules
│ │ └── .bin
│ │ │ └── http-server
│ ├── package.json
│ └── bundle.mjs
└── esbuild-browser
│ ├── .gitignore
│ ├── index.html
│ ├── tsconfig.json
│ ├── serve.json
│ ├── package.json
│ └── index.ts
├── packages
├── duckdb-wasm-app
│ ├── src
│ │ ├── utils
│ │ │ ├── format.ts
│ │ │ └── platform.ts
│ │ ├── model
│ │ │ ├── index.ts
│ │ │ └── model_context.ts
│ │ ├── pages
│ │ │ ├── docs.module.css
│ │ │ ├── shell.module.css
│ │ │ ├── blog.module.css
│ │ │ ├── docs.tsx
│ │ │ ├── table.tsx
│ │ │ ├── versus.module.css
│ │ │ └── table.module.css
│ │ └── components
│ │ │ ├── minibar_chart.module.css
│ │ │ ├── page_structure.tsx
│ │ │ ├── page_structure.module.css
│ │ │ ├── minibar_chart.tsx
│ │ │ └── feature_table.module.css
│ ├── .eslintignore
│ ├── .gitignore
│ ├── test
│ │ ├── index.ts
│ │ └── shell.test.ts
│ ├── types
│ │ ├── crate.d.ts
│ │ ├── csv.d.ts
│ │ ├── html.d.ts
│ │ ├── png.d.ts
│ │ ├── sql.d.ts
│ │ ├── svg.d.ts
│ │ ├── tbl.d.ts
│ │ ├── wasm.d.ts
│ │ ├── parquet.d.ts
│ │ ├── worker.d.ts
│ │ ├── css-modules.d.ts
│ │ └── editor-worker.d.ts
│ ├── static
│ │ ├── favicons
│ │ │ ├── favicon.ico
│ │ │ ├── favicon-16x16.png
│ │ │ ├── favicon-32x32.png
│ │ │ ├── mstile-150x150.png
│ │ │ ├── sharingduckdb.jpg
│ │ │ ├── apple-touch-icon.png
│ │ │ ├── android-chrome-192x192.png
│ │ │ ├── android-chrome-384x384.png
│ │ │ ├── android-chrome-512x512.png
│ │ │ ├── browserconfig.xml
│ │ │ ├── site.webmanifest
│ │ │ └── safari-pinned-tab.svg
│ │ ├── fonts
│ │ │ ├── Nunito-Bold.ttf
│ │ │ ├── Nunito-Light.ttf
│ │ │ ├── Nunito-Regular.ttf
│ │ │ ├── Nunito-SemiBold.ttf
│ │ │ └── fonts.module.css
│ │ └── svg
│ │ │ ├── icons
│ │ │ ├── minus.svg
│ │ │ ├── plus.svg
│ │ │ ├── warn.svg
│ │ │ ├── check.svg
│ │ │ ├── delete.svg
│ │ │ ├── view-list.svg
│ │ │ ├── close.svg
│ │ │ ├── minus-circle.svg
│ │ │ ├── tray_full.svg
│ │ │ ├── add.svg
│ │ │ ├── delete-outline.svg
│ │ │ ├── monitor.svg
│ │ │ ├── file-document-outline.svg
│ │ │ ├── table.svg
│ │ │ ├── file-chart.svg
│ │ │ ├── cloud.svg
│ │ │ ├── shell.svg
│ │ │ ├── file-table.svg
│ │ │ ├── duckdb_logo.svg
│ │ │ ├── file-table-box.svg
│ │ │ ├── timer.svg
│ │ │ ├── pivot.svg
│ │ │ ├── data-matrix.svg
│ │ │ ├── server.svg
│ │ │ ├── data-matrix-scan.svg
│ │ │ ├── clockfast.svg
│ │ │ └── book.svg
│ │ │ └── logo
│ │ │ └── duckdb.svg
│ ├── .eslintrc
│ ├── webpack.release.js
│ ├── webpack.debug.corp.js
│ ├── tsconfig.json
│ └── webpack.tests.js
├── duckdb-wasm-shell
│ ├── crate
│ │ ├── src
│ │ │ ├── error.rs
│ │ │ ├── xterm
│ │ │ │ ├── sugar
│ │ │ │ │ └── mod.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── addons
│ │ │ │ │ ├── mod.rs
│ │ │ │ │ ├── ligatures.rs
│ │ │ │ │ ├── unicode11.rs
│ │ │ │ │ ├── serialize.rs
│ │ │ │ │ ├── webgl.rs
│ │ │ │ │ ├── web_links.rs
│ │ │ │ │ └── attach.rs
│ │ │ ├── comfy
│ │ │ │ ├── utils
│ │ │ │ │ └── mod.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── style
│ │ │ │ │ ├── modifiers.rs
│ │ │ │ │ ├── cell.rs
│ │ │ │ │ └── column.rs
│ │ │ ├── duckdb
│ │ │ │ ├── mod.rs
│ │ │ │ ├── version.rs
│ │ │ │ └── web_file.rs
│ │ │ ├── shell_options.rs
│ │ │ └── lib.rs
│ │ └── Cargo.toml
│ ├── .eslintignore
│ ├── .gitignore
│ ├── src
│ │ ├── index.ts
│ │ ├── platform.ts
│ │ ├── version.ts
│ │ └── utils
│ │ │ └── format.ts
│ ├── .eslintrc
│ ├── tsconfig.json
│ └── README.md
├── duckdb-wasm
│ ├── src
│ │ ├── bindings
│ │ │ ├── .gitignore
│ │ │ ├── duckdb-coi.pthread.d.ts
│ │ │ ├── duckdb-coi.d.ts
│ │ │ ├── duckdb-eh.d.ts
│ │ │ ├── duckdb-mvp.d.ts
│ │ │ ├── tokens.ts
│ │ │ ├── progress.ts
│ │ │ ├── index.ts
│ │ │ ├── web_file.ts
│ │ │ ├── udf_function.ts
│ │ │ ├── duckdb_module.ts
│ │ │ ├── bindings_browser_mvp.ts
│ │ │ ├── bindings_node_eh.ts
│ │ │ ├── bindings_node_mvp.ts
│ │ │ ├── bindings_browser_coi.ts
│ │ │ ├── bindings_browser_eh.ts
│ │ │ └── insert_options.ts
│ │ ├── utils
│ │ │ ├── index.ts
│ │ │ ├── binary_dump.ts
│ │ │ └── opfs_util.ts
│ │ ├── index.ts
│ │ ├── parallel
│ │ │ └── index.ts
│ │ ├── index_docs.ts
│ │ ├── worker.ts
│ │ ├── version.ts
│ │ ├── status.ts
│ │ └── targets
│ │ │ ├── duckdb.ts
│ │ │ ├── duckdb-browser-blocking.ts
│ │ │ ├── duckdb-node-blocking.ts
│ │ │ ├── duckdb-node-eh.worker.ts
│ │ │ ├── duckdb-browser-coi.worker.ts
│ │ │ ├── duckdb-browser-eh.worker.ts
│ │ │ ├── duckdb-browser-mvp.worker.ts
│ │ │ └── duckdb-node-mvp.worker.ts
│ ├── .eslintignore
│ ├── jasmine.json
│ ├── .prettierrc.js
│ ├── types
│ │ ├── wasm.d.ts
│ │ └── web-worker.d.ts
│ ├── .gitignore
│ ├── karma
│ │ ├── tests-debug.cjs
│ │ ├── tests-firefox.cjs
│ │ ├── tests-all.cjs
│ │ ├── tests-chrome.cjs
│ │ ├── tests-chrome-coverage.cjs
│ │ └── s3rver
│ │ │ └── s3rver.js
│ ├── .eslintrc.json
│ ├── typedoc.json
│ ├── test
│ │ ├── json.test.ts
│ │ ├── regression
│ │ │ ├── index.ts
│ │ │ ├── github_1467.test.ts
│ │ │ └── github_1833.test.ts
│ │ ├── string_test_helper.ts
│ │ ├── table_test.ts
│ │ ├── long_queries.test.ts
│ │ └── tokenizer.test.ts
│ ├── tsconfig.json
│ └── coverage.mjs
├── benchmarks
│ ├── .eslintignore
│ ├── .gitignore
│ ├── src
│ │ ├── utils
│ │ │ ├── index.ts
│ │ │ ├── shuffle.ts
│ │ │ └── format.ts
│ │ ├── internal
│ │ │ └── index.ts
│ │ ├── system
│ │ │ └── index.ts
│ │ ├── suite_internal.ts
│ │ ├── suite_system_tpch_arquero.ts
│ │ ├── suite_system_sum_csv.ts
│ │ ├── suite_system_tpch_duckdb.ts
│ │ ├── suite_system_tpch_lovefield.ts
│ │ └── suite_system_tpch_sqljs.ts
│ ├── .prettierrc.js
│ ├── types
│ │ ├── wasm.d.ts
│ │ ├── worker.d.ts
│ │ └── web-worker.d.ts
│ ├── .eslintrc.json
│ ├── scripts
│ │ └── tpch
│ │ │ ├── 6.sql
│ │ │ ├── 14.sql
│ │ │ ├── 17.sql
│ │ │ ├── 4.sql
│ │ │ ├── 13.sql
│ │ │ ├── 3.sql
│ │ │ ├── 5.sql
│ │ │ ├── 1.sql
│ │ │ ├── 16.sql
│ │ │ ├── 18.sql
│ │ │ ├── 10.sql
│ │ │ ├── 11.sql
│ │ │ ├── 20.sql
│ │ │ ├── 22-sqlite.sql
│ │ │ ├── 21.sql
│ │ │ ├── 9-sqlite.sql
│ │ │ ├── 12.sql
│ │ │ ├── 15.sql
│ │ │ ├── 9.sql
│ │ │ ├── 22.sql
│ │ │ ├── 2.sql
│ │ │ ├── 8-sqlite.sql
│ │ │ ├── 19.sql
│ │ │ ├── 8.sql
│ │ │ ├── 7-sqlite.sql
│ │ │ └── 7.sql
│ └── tsconfig.json
└── react-duckdb
│ ├── src
│ └── index.ts
│ └── package.json
├── .gitattributes
├── misc
├── duckdb_wasm.png
├── duckdb_wasm.afdesign
├── duckdb_wasm_circle.png
├── duckdb_wasm_circle.afdesign
├── github_social_preview.png
├── duckdb.svg
├── duckdb_wasm.svg
└── duckdb_wasm_light.svg
├── Cargo.toml
├── .prettierrc.js
├── patches
├── rapidjson
│ └── cmake_minimum_required.patch
├── duckdb
│ ├── preloaded_httpfs.patch
│ ├── no_httpfs.patch
│ ├── fix_config_size_t.patch
│ ├── bind_copy_direct_io.patch
│ └── fix_load_database.patch
└── arrow
│ └── hashing_compile_in_emscripten.patch
├── scripts
├── npm_publish_react.sh
├── npm_publish_shell.sh
├── npm_publish_lib.sh
├── reset_pages_subtree.sh
├── npm_measure_lib.sh
├── generate_uni.sh
├── npm_restore.sh
├── build_duckdb_badge.sh
├── build_loadable.sh
├── npm_version.sh
├── deploy_benchmarks.sh
├── format.sh
├── generate_tpch_duckdb.sh
├── generate_tpch_tbl.sh
├── sync_versions.mjs
└── generate_benchmark_data.sh
├── .clang-format
├── docker-compose.yml
├── .github
├── ISSUE_TEMPLATE
│ └── config.yml
├── dependabot.yml
└── workflows
│ └── npm_tags.yml
├── .gitignore
├── tsconfig.json
├── extension_config_wasm.cmake
├── package.json
├── LICENSE
└── .gitmodules
/actions/image/TAG:
--------------------------------------------------------------------------------
1 | 0.75
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | submodules
2 | dist
--------------------------------------------------------------------------------
/lib/src/wasm_main.cc:
--------------------------------------------------------------------------------
1 | int main() {}
2 |
--------------------------------------------------------------------------------
/tools/dataprep/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 |
--------------------------------------------------------------------------------
/data/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !vega
3 | !.gitignore
4 |
--------------------------------------------------------------------------------
/examples/bare-node/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 |
--------------------------------------------------------------------------------
/lib/include/duckdb/web/arrow_stream_factory.h:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/src/utils/format.ts:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/crate/src/error.rs:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/data/test.csv:
--------------------------------------------------------------------------------
1 | "a","b","c"
2 | 1,2,3
3 | 4,5,6
4 | 7,8,9
5 |
--------------------------------------------------------------------------------
/examples/esbuild-node/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /index.cjs
3 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # bash can't handle crlf line breaks
2 | *.sh text eol=lf
3 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/bindings/.gitignore:
--------------------------------------------------------------------------------
1 | /duckdb*.js
2 | /duckdb*.wasm
3 |
--------------------------------------------------------------------------------
/examples/bare-browser/.gitignore:
--------------------------------------------------------------------------------
1 | /duckdb-browser*
2 | /*.wasm
3 | /node_modules
4 |
--------------------------------------------------------------------------------
/lib/.gitignore:
--------------------------------------------------------------------------------
1 | /.cache
2 | /.ccls-cache
3 | /build
4 | /compile_commands.json
5 |
--------------------------------------------------------------------------------
/packages/benchmarks/.eslintignore:
--------------------------------------------------------------------------------
1 | *.cjs
2 | *.js
3 | *.mjs
4 | /karma/*.cjs
5 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/.eslintignore:
--------------------------------------------------------------------------------
1 | *.cjs
2 | *.js
3 | *.mjs
4 | /*.json
5 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/src/model/index.ts:
--------------------------------------------------------------------------------
1 | export * from './model_context';
2 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/.eslintignore:
--------------------------------------------------------------------------------
1 | *.cjs
2 | *.js
3 | *.mjs
4 | /*.json
5 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/.eslintignore:
--------------------------------------------------------------------------------
1 | *.cjs
2 | *.js
3 | *.mjs
4 | /karma/*.cjs
5 |
--------------------------------------------------------------------------------
/examples/esbuild-browser/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /*.wasm
3 | /*.js
4 | /*.js.map
5 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/.gitignore:
--------------------------------------------------------------------------------
1 | /dist
2 | /crate/pkg
3 | /build
4 | /node_modules
5 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/.gitignore:
--------------------------------------------------------------------------------
1 | /dist
2 | /crate/pkg
3 | /build
4 | /node_modules
5 |
--------------------------------------------------------------------------------
/misc/duckdb_wasm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duckdb/duckdb-wasm/HEAD/misc/duckdb_wasm.png
--------------------------------------------------------------------------------
/examples/bare-browser/node_modules/.bin/http-server:
--------------------------------------------------------------------------------
1 | ../../../../node_modules/http-server/bin/http-server
--------------------------------------------------------------------------------
/packages/benchmarks/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /duckdb_webapi.*
3 | /dist
4 | *.d.ts.map
5 |
6 |
--------------------------------------------------------------------------------
/packages/benchmarks/src/utils/index.ts:
--------------------------------------------------------------------------------
1 | export * from './format';
2 | export * from './shuffle';
3 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/crate/src/xterm/sugar/mod.rs:
--------------------------------------------------------------------------------
1 | pub mod builder;
2 | pub mod constructor;
3 |
--------------------------------------------------------------------------------
/data/test.json:
--------------------------------------------------------------------------------
1 | {"a": 1, "b": 2.0, "c": "foo", "d": false}
2 | {"a": 4, "b": -5.5, "c": null, "d": true}
3 |
--------------------------------------------------------------------------------
/misc/duckdb_wasm.afdesign:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duckdb/duckdb-wasm/HEAD/misc/duckdb_wasm.afdesign
--------------------------------------------------------------------------------
/misc/duckdb_wasm_circle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duckdb/duckdb-wasm/HEAD/misc/duckdb_wasm_circle.png
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/test/index.ts:
--------------------------------------------------------------------------------
1 | import { testShell } from './shell.test';
2 |
3 | testShell();
4 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/jasmine.json:
--------------------------------------------------------------------------------
1 | {
2 | "failFast": true,
3 | "timeoutInterval": 900000
4 | }
5 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/utils/index.ts:
--------------------------------------------------------------------------------
1 | export * from './binary_dump';
2 | export * from './s3_helper';
3 |
--------------------------------------------------------------------------------
/packages/benchmarks/.prettierrc.js:
--------------------------------------------------------------------------------
1 | const base = require('../../.prettierrc.js');
2 | module.exports = base;
3 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/.prettierrc.js:
--------------------------------------------------------------------------------
1 | const base = require('../../.prettierrc.js');
2 | module.exports = base;
3 |
--------------------------------------------------------------------------------
/misc/duckdb_wasm_circle.afdesign:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duckdb/duckdb-wasm/HEAD/misc/duckdb_wasm_circle.afdesign
--------------------------------------------------------------------------------
/misc/github_social_preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duckdb/duckdb-wasm/HEAD/misc/github_social_preview.png
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 |
3 | members = [
4 | "tools/dataprep",
5 | "packages/duckdb-wasm-shell/crate",
6 | ]
7 |
--------------------------------------------------------------------------------
/packages/benchmarks/types/wasm.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.wasm' {
2 | const value: any;
3 | export default value;
4 | }
5 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/types/wasm.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.wasm' {
2 | const value: any;
3 | export default value;
4 | }
5 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/types/crate.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*crate' {
2 | const value: any;
3 | export default value;
4 | }
5 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/types/csv.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.csv' {
2 | const value: any;
3 | export default value;
4 | }
5 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/types/html.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.html' {
2 | const value: any;
3 | export default value;
4 | }
5 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/types/png.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.png' {
2 | const value: any;
3 | export default value;
4 | }
5 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/types/sql.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.sql' {
2 | const value: any;
3 | export default value;
4 | }
5 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/types/svg.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.svg' {
2 | const value: any;
3 | export default value;
4 | }
5 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/types/tbl.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.tbl' {
2 | const value: any;
3 | export default value;
4 | }
5 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/types/wasm.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.wasm' {
2 | const value: any;
3 | export default value;
4 | }
5 |
--------------------------------------------------------------------------------
/lib/.clang-format:
--------------------------------------------------------------------------------
1 | BasedOnStyle: Google
2 | ColumnLimit: 120
3 | IndentWidth: 4
4 | AlwaysBreakTemplateDeclarations: MultiLine
5 |
6 |
--------------------------------------------------------------------------------
/packages/benchmarks/types/worker.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.worker.js' {
2 | const value: any;
3 | export default value;
4 | }
5 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/types/parquet.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.parquet' {
2 | const value: any;
3 | export default value;
4 | }
5 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/types/worker.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.worker.js' {
2 | const value: any;
3 | export default value;
4 | }
5 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './version';
2 | export * from './shell';
3 | export { getJsDelivrModule } from './platform';
4 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/favicons/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duckdb/duckdb-wasm/HEAD/packages/duckdb-wasm-app/static/favicons/favicon.ico
--------------------------------------------------------------------------------
/packages/benchmarks/src/internal/index.ts:
--------------------------------------------------------------------------------
1 | export * from './format_benchmark';
2 | export * from './iterator_benchmark';
3 | export * from './udf_benchmark';
4 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/fonts/Nunito-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duckdb/duckdb-wasm/HEAD/packages/duckdb-wasm-app/static/fonts/Nunito-Bold.ttf
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/fonts/Nunito-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duckdb/duckdb-wasm/HEAD/packages/duckdb-wasm-app/static/fonts/Nunito-Light.ttf
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/fonts/Nunito-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duckdb/duckdb-wasm/HEAD/packages/duckdb-wasm-app/static/fonts/Nunito-Regular.ttf
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/fonts/Nunito-SemiBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duckdb/duckdb-wasm/HEAD/packages/duckdb-wasm-app/static/fonts/Nunito-SemiBold.ttf
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/crate/src/comfy/utils/mod.rs:
--------------------------------------------------------------------------------
1 | pub mod arrangement;
2 | pub mod borders;
3 | mod column_display_info;
4 | pub mod format;
5 | mod split;
6 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/crate/src/xterm/mod.rs:
--------------------------------------------------------------------------------
1 | pub mod keys;
2 | pub use keys::*;
3 | pub mod xterm;
4 | pub use xterm::*;
5 | pub mod addons;
6 | pub mod sugar;
7 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/favicons/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duckdb/duckdb-wasm/HEAD/packages/duckdb-wasm-app/static/favicons/favicon-16x16.png
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/favicons/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duckdb/duckdb-wasm/HEAD/packages/duckdb-wasm-app/static/favicons/favicon-32x32.png
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/favicons/mstile-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duckdb/duckdb-wasm/HEAD/packages/duckdb-wasm-app/static/favicons/mstile-150x150.png
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/favicons/sharingduckdb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duckdb/duckdb-wasm/HEAD/packages/duckdb-wasm-app/static/favicons/sharingduckdb.jpg
--------------------------------------------------------------------------------
/packages/duckdb-wasm/.gitignore:
--------------------------------------------------------------------------------
1 | /*.parquet
2 | /*.csv
3 | /.nyc_output
4 | /coverage
5 | /node_modules
6 | /duckdb_webapi.*
7 | /dist
8 | /docs
9 | *.d.ts.map
10 |
--------------------------------------------------------------------------------
/examples/esbuild-browser/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/favicons/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duckdb/duckdb-wasm/HEAD/packages/duckdb-wasm-app/static/favicons/apple-touch-icon.png
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/types/css-modules.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.module.css' {
2 | const content: { [className: string]: string };
3 | export default content;
4 | }
5 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/types/editor-worker.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'monaco-editor/esm/vs/editor/editor.worker.js' {
2 | const content: any;
3 | export = content;
4 | }
5 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/favicons/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duckdb/duckdb-wasm/HEAD/packages/duckdb-wasm-app/static/favicons/android-chrome-192x192.png
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/favicons/android-chrome-384x384.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duckdb/duckdb-wasm/HEAD/packages/duckdb-wasm-app/static/favicons/android-chrome-384x384.png
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/favicons/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/duckdb/duckdb-wasm/HEAD/packages/duckdb-wasm-app/static/favicons/android-chrome-512x512.png
--------------------------------------------------------------------------------
/packages/react-duckdb/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './connection_provider';
2 | export * from './database_provider';
3 | export * from './platform_provider';
4 | export * from './resolvable';
5 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/src/pages/docs.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | position: relative;
3 | height: 100%;
4 | width: 100%;
5 | box-sizing: border-box;
6 | overflow: hidden;
7 | }
8 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/bindings/duckdb-coi.pthread.d.ts:
--------------------------------------------------------------------------------
1 | export const alert: any;
2 | export const onmessage: any;
3 | export function getModule(): any;
4 | export function setModule(m: any): void;
5 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "trailingComma": "all",
3 | "tabWidth": 4,
4 | "semi": true,
5 | "singleQuote": true,
6 | "arrowParens": "avoid",
7 | "printWidth": 120
8 | }
9 |
--------------------------------------------------------------------------------
/packages/benchmarks/types/web-worker.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'web-worker' {
2 | type ConstructorOf = { new (...args: any[]): C };
3 | const _default: ConstructorOf;
4 | export default _default;
5 | }
6 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/bindings/duckdb-coi.d.ts:
--------------------------------------------------------------------------------
1 | import { DuckDBModule } from './duckdb_module';
2 | export function DuckDB(moduleOverrides?: Partial): Promise;
3 | export default DuckDB;
4 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/bindings/duckdb-eh.d.ts:
--------------------------------------------------------------------------------
1 | import { DuckDBModule } from './duckdb_module';
2 | export function DuckDB(moduleOverrides?: Partial): Promise;
3 | export default DuckDB;
4 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/bindings/duckdb-mvp.d.ts:
--------------------------------------------------------------------------------
1 | import { DuckDBModule } from './duckdb_module';
2 | export function DuckDB(moduleOverrides?: Partial): Promise;
3 | export default DuckDB;
4 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/types/web-worker.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'web-worker' {
2 | type ConstructorOf = { new (...args: any[]): C };
3 | const _default: ConstructorOf;
4 | export default _default;
5 | }
6 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/crate/src/xterm/addons/mod.rs:
--------------------------------------------------------------------------------
1 | pub mod attach;
2 | pub mod fit;
3 | pub mod ligatures;
4 | pub mod search;
5 | pub mod serialize;
6 | pub mod unicode11;
7 | pub mod web_links;
8 | pub mod webgl;
9 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/karma/tests-debug.cjs:
--------------------------------------------------------------------------------
1 | const base = require('./karma.base.cjs');
2 |
3 | module.exports = function (config) {
4 | config.set({ ...base(config), singleRun: false, reporters: ['kjhtml'], browsers: [] });
5 | };
6 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/karma/tests-firefox.cjs:
--------------------------------------------------------------------------------
1 | const base = require('./karma.base.cjs');
2 |
3 | module.exports = function (config) {
4 | config.set({ ...base(config), browsers: ['FirefoxHeadless'], reporters: ['spec'] });
5 | };
6 |
--------------------------------------------------------------------------------
/packages/benchmarks/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../.eslintrc.base.json"],
3 | "parserOptions": {
4 | "project": "./tsconfig.json",
5 | "ecmaVersion": 2020,
6 | "sourceType": "module"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../.eslintrc.base.json"],
3 | "parserOptions": {
4 | "project": "./tsconfig.json",
5 | "ecmaVersion": 2020,
6 | "sourceType": "module"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../.eslintrc.base.json"],
3 | "parserOptions": {
4 | "project": "./tsconfig.json",
5 | "ecmaVersion": 2020,
6 | "sourceType": "module"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../.eslintrc.base.json"],
3 | "parserOptions": {
4 | "project": "./tsconfig.json",
5 | "ecmaVersion": 2020,
6 | "sourceType": "module"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './bindings';
2 | export * from './log';
3 | export * from './parallel';
4 | export * from './status';
5 | export * from './platform';
6 | export * from './version';
7 | export * from './worker';
8 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/parallel/index.ts:
--------------------------------------------------------------------------------
1 | export * from './async_connection';
2 | export * from './async_bindings_interface';
3 | export * from './async_bindings';
4 | export * from './worker_dispatcher';
5 | export * from './worker_request';
6 |
--------------------------------------------------------------------------------
/lib/src/extensions/json_extension.cc:
--------------------------------------------------------------------------------
1 | #include "duckdb/web/extensions/json_extension.h"
2 |
3 | #include "json_extension.hpp"
4 |
5 | extern "C" void duckdb_web_json_init(duckdb::DuckDB* db) { db->LoadStaticExtension(); }
6 |
--------------------------------------------------------------------------------
/packages/benchmarks/src/system/index.ts:
--------------------------------------------------------------------------------
1 | export * from './arquero_benchmarks';
2 | export * from './lovefield_benchmarks';
3 | export * from './sqljs_benchmarks';
4 | export * from './system_benchmark';
5 | export * from './duckdb_sync_benchmarks';
6 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/minus.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/lib/src/extensions/parquet_extension.cc:
--------------------------------------------------------------------------------
1 | #include "duckdb/web/extensions/parquet_extension.h"
2 |
3 | #include "parquet_extension.hpp"
4 |
5 | extern "C" void duckdb_web_parquet_init(duckdb::DuckDB* db) { db->LoadStaticExtension(); }
6 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/plus.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/crate/src/duckdb/mod.rs:
--------------------------------------------------------------------------------
1 | mod async_duckdb;
2 |
3 | pub mod file_stats;
4 | pub mod tokens;
5 | mod version;
6 | mod web_file;
7 |
8 | pub use async_duckdb::*;
9 | pub use file_stats::*;
10 | pub use version::*;
11 | pub use web_file::*;
12 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/warn.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/check.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/lib/include/duckdb/web/extensions/json_extension.h:
--------------------------------------------------------------------------------
1 | #ifndef INCLUDE_DUCKDB_WEB_EXTENSIONS_JSON_EXTENSION_H_
2 | #define INCLUDE_DUCKDB_WEB_EXTENSIONS_JSON_EXTENSION_H_
3 |
4 | #include "duckdb/main/database.hpp"
5 |
6 | extern "C" void duckdb_web_json_init(duckdb::DuckDB* db);
7 |
8 | #endif
9 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/src/model/model_context.ts:
--------------------------------------------------------------------------------
1 | export type Action = {
2 | readonly type: T;
3 | readonly data: P;
4 | };
5 |
6 | export type Dispatch = (action: ActionVariant) => void;
7 |
8 | export type ProviderProps = { children: React.ReactElement };
9 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/6.sql:
--------------------------------------------------------------------------------
1 | select
2 | sum(l_extendedprice * l_discount) as revenue
3 | from
4 | lineitem
5 | where
6 | l_shipdate >= '1994-01-01'
7 | and l_shipdate < '1995-01-01'
8 | and l_discount between 0.05
9 | and 0.07
10 | and l_quantity < 24;
11 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/crate/src/comfy/mod.rs:
--------------------------------------------------------------------------------
1 | mod cell;
2 | mod column;
3 | mod row;
4 | mod style;
5 | mod table;
6 | mod utils;
7 |
8 | pub use cell::{Cell, Cells};
9 | pub use column::Column;
10 | pub use row::Row;
11 | pub use style::*;
12 | pub use table::{ColumnCellIter, Table};
13 |
--------------------------------------------------------------------------------
/lib/include/duckdb/web/extensions/parquet_extension.h:
--------------------------------------------------------------------------------
1 | #ifndef INCLUDE_DUCKDB_WEB_EXTENSIONS_PARQUET_EXTENSION_H_
2 | #define INCLUDE_DUCKDB_WEB_EXTENSIONS_PARQUET_EXTENSION_H_
3 |
4 | #include "duckdb/main/database.hpp"
5 |
6 | extern "C" void duckdb_web_parquet_init(duckdb::DuckDB* db);
7 |
8 | #endif
9 |
--------------------------------------------------------------------------------
/lib/include/duckdb/web/utils/thread.h:
--------------------------------------------------------------------------------
1 | #ifndef INCLUDE_DUCKDB_WEB_UTILS_THREAD_H_
2 | #define INCLUDE_DUCKDB_WEB_UTILS_THREAD_H_
3 |
4 | #include
5 |
6 | namespace duckdb {
7 | namespace web {
8 |
9 | uint32_t GetThreadID();
10 |
11 | }
12 | } // namespace duckdb
13 |
14 | #endif
15 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/delete.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/view-list.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/karma/tests-all.cjs:
--------------------------------------------------------------------------------
1 | const base = require('./karma.base.cjs');
2 |
3 | module.exports = function (config) {
4 | config.set({
5 | ...base(config),
6 | browsers: ['FirefoxHeadless', 'ChromeHeadlessNoSandbox'],
7 | reporters: ['spec'],
8 | });
9 | };
10 |
--------------------------------------------------------------------------------
/examples/esbuild-node/bundle.mjs:
--------------------------------------------------------------------------------
1 | import esbuild from 'esbuild';
2 |
3 | esbuild.build({
4 | entryPoints: ['./index.ts'],
5 | outfile: 'index.mjs',
6 | platform: 'node',
7 | format: 'esm',
8 | target: 'esnext',
9 | bundle: false,
10 | minify: false,
11 | sourcemap: false,
12 | });
13 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/close.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/test/shell.test.ts:
--------------------------------------------------------------------------------
1 | export function testShell(): void {
2 | beforeAll(async () => {});
3 |
4 | beforeEach(async () => {});
5 |
6 | describe('Parser', () => {
7 | it('syntax error', async () => {
8 | expect(1).toEqual(1);
9 | });
10 | });
11 | }
12 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/minus-circle.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/tray_full.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/index_docs.ts:
--------------------------------------------------------------------------------
1 | import * as duckdb from './targets/duckdb';
2 | import * as blocking_browser from './targets/duckdb-browser-blocking';
3 | import * as blocking_node from './targets/duckdb-node-blocking';
4 |
5 | exports = {
6 | duckdb,
7 | blocking_browser,
8 | blocking_node,
9 | };
10 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/src/platform.ts:
--------------------------------------------------------------------------------
1 | import { PACKAGE_NAME, PACKAGE_VERSION } from './version';
2 |
3 | export function getJsDelivrModule(): URL {
4 | const jsdelivr_dist_url = `https://cdn.jsdelivr.net/npm/${PACKAGE_NAME}@${PACKAGE_VERSION}/dist/`;
5 | return new URL(`${jsdelivr_dist_url}dist/shell_bg.wasm`);
6 | }
7 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/add.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/delete-outline.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/bindings/tokens.ts:
--------------------------------------------------------------------------------
1 | export enum TokenType {
2 | IDENTIFIER = 0,
3 | NUMERIC_CONSTANT = 1,
4 | STRING_CONSTANT = 2,
5 | OPERATOR = 3,
6 | KEYWORD = 4,
7 | COMMENT = 5,
8 | }
9 |
10 | export interface ScriptTokens {
11 | offsets: number[];
12 | types: TokenType[];
13 | }
14 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/worker.ts:
--------------------------------------------------------------------------------
1 | import Worker from 'web-worker';
2 |
3 | export async function createWorker(url: string) {
4 | const request = new Request(url);
5 | const workerScript = await fetch(request);
6 | const workerURL = URL.createObjectURL(await workerScript.blob());
7 | return new Worker(workerURL);
8 | }
9 |
--------------------------------------------------------------------------------
/examples/esbuild-node/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "es2020",
5 | "moduleResolution": "node",
6 | "esModuleInterop": true,
7 | "forceConsistentCasingInFileNames": true,
8 | "strict": true,
9 | "skipLibCheck": true
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/favicons/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #000000
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/examples/esbuild-browser/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "es2020",
5 | "moduleResolution": "node",
6 | "esModuleInterop": true,
7 | "forceConsistentCasingInFileNames": true,
8 | "strict": true,
9 | "skipLibCheck": true
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/monitor.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/file-document-outline.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/table.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/file-chart.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/cloud.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/shell.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/bindings/progress.ts:
--------------------------------------------------------------------------------
1 | /** An instantiation progress */
2 | export interface InstantiationProgress {
3 | startedAt: Date;
4 | updatedAt: Date;
5 | bytesTotal: number;
6 | bytesLoaded: number;
7 | }
8 |
9 | /** An instantiation progress handler */
10 | export type InstantiationProgressHandler = (p: InstantiationProgress) => void;
11 |
--------------------------------------------------------------------------------
/misc/duckdb.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/examples/bare-node/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "@duckdb/duckdb-wasm-examples-bare-node",
4 | "version": "0.0.1",
5 | "main": "index.js",
6 | "license": "MIT",
7 | "dependencies": {
8 | "@duckdb/duckdb-wasm": "file:../../packages/duckdb-wasm"
9 | },
10 | "scripts": {
11 | "test": "node ./index.cjs"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/patches/rapidjson/cmake_minimum_required.patch:
--------------------------------------------------------------------------------
1 | diff --git a/CMakeLists.txt b/CMakeLists.txt
2 | index dd1f173..2351bad 100644
3 | --- a/CMakeLists.txt
4 | +++ b/CMakeLists.txt
5 | @@ -1,4 +1,4 @@
6 | -CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12)
7 | +CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12...3.29)
8 | if(POLICY CMP0025)
9 | # detect Apple's Clang
10 | cmake_policy(SET CMP0025 NEW)
11 |
--------------------------------------------------------------------------------
/examples/esbuild-browser/serve.json:
--------------------------------------------------------------------------------
1 | {
2 | "headers": [
3 | {
4 | "source": "*",
5 | "headers": [
6 | {
7 | "key": "Cross-Origin-Embedder-Policy",
8 | "value": "require-corp"
9 | },
10 | {
11 | "key": "Cross-Origin-Opener-Policy",
12 | "value": "same-origin"
13 | }
14 | ]
15 | }
16 | ]
17 | }
18 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/utils/binary_dump.ts:
--------------------------------------------------------------------------------
1 | export function dumpBuffer(src: Uint8Array): string {
2 | return [...src]
3 | .map(x => (x >= 32 && x <= 127 ? String.fromCharCode(x) : '.'))
4 | .reduce((acc: string, value: string, index: number) => {
5 | if (index % 20 == 0) acc += '\n';
6 | acc += value;
7 | return acc;
8 | }, '');
9 | }
10 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/version.ts:
--------------------------------------------------------------------------------
1 | import config from '../package.json';
2 |
3 | export const PACKAGE_NAME = config.name;
4 | export const PACKAGE_VERSION = config.version;
5 |
6 | const VERSION_PARTS = config.version.split('.');
7 | export const PACKAGE_VERSION_MAJOR = VERSION_PARTS[0];
8 | export const PACKAGE_VERSION_MINOR = VERSION_PARTS[1];
9 | export const PACKAGE_VERSION_PATCH = VERSION_PARTS[2];
10 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/file-table.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/utils/opfs_util.ts:
--------------------------------------------------------------------------------
1 | export const REGEX_OPFS_FILE = /'(opfs:\/\/\S*?)'/g;
2 | export const REGEX_OPFS_PROTOCOL = /(opfs:\/\/\S*?)/g;
3 |
4 | export function isOPFSProtocol(path: string): boolean {
5 | return path.search(REGEX_OPFS_PROTOCOL) > -1;
6 | }
7 |
8 | export function searchOPFSFiles(text: string) {
9 | return [...text.matchAll(REGEX_OPFS_FILE)].map(match => match[1]);
10 | }
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/src/version.ts:
--------------------------------------------------------------------------------
1 | import config from '../package.json';
2 |
3 | export const PACKAGE_NAME = config.name;
4 | export const PACKAGE_VERSION = config.version;
5 |
6 | const VERSION_PARTS = config.version.split('.');
7 | export const PACKAGE_VERSION_MAJOR = VERSION_PARTS[0];
8 | export const PACKAGE_VERSION_MINOR = VERSION_PARTS[1];
9 | export const PACKAGE_VERSION_PATCH = VERSION_PARTS[2];
10 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/bindings/index.ts:
--------------------------------------------------------------------------------
1 | export * from './bindings_interface';
2 | export * from './bindings_base';
3 | export * from './config';
4 | export * from './connection';
5 | export * from './duckdb_module';
6 | export * from './file_stats';
7 | export * from './runtime';
8 | export * from './insert_options';
9 | export * from './progress';
10 | export * from './tokens';
11 | export * from './web_file';
12 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/status.ts:
--------------------------------------------------------------------------------
1 | export enum StatusCode {
2 | SUCCESS = 0,
3 | MAX_ARROW_ERROR = 255,
4 | DUCKDB_WASM_RETRY = 256,
5 | }
6 |
7 | export function IsArrowBuffer(status: StatusCode): boolean {
8 | return status <= StatusCode.MAX_ARROW_ERROR;
9 | }
10 |
11 | export function IsDuckDBWasmRetry(status: StatusCode): boolean {
12 | return status === StatusCode.DUCKDB_WASM_RETRY;
13 | }
14 |
--------------------------------------------------------------------------------
/packages/benchmarks/src/utils/shuffle.ts:
--------------------------------------------------------------------------------
1 | export function shuffle(array: T[]): T[] {
2 | let currentIndex = array.length,
3 | randomIndex;
4 | while (currentIndex != 0) {
5 | randomIndex = Math.floor(Math.random() * currentIndex);
6 | currentIndex--;
7 | [array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]];
8 | }
9 | return array;
10 | }
11 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/src/pages/shell.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | position: relative;
3 | height: 100%;
4 | width: 100%;
5 | box-sizing: border-box;
6 | }
7 |
8 | .resizer {
9 | position: absolute;
10 | top: 0;
11 | left: 0;
12 | right: 0;
13 | bottom: 0;
14 | width: 100%;
15 | height: 100%;
16 | }
17 |
18 | .term_container {
19 | width: 100%;
20 | height: 100%;
21 | }
22 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/duckdb_logo.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/file-table-box.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/crate/src/comfy/style/modifiers.rs:
--------------------------------------------------------------------------------
1 | /// A modifier, that when applied will convert the outer corners to round corners.
2 | /// ```text
3 | /// ╭───────┬───────╮
4 | /// │ Hello │ there │
5 | /// ╞═══════╪═══════╡
6 | /// │ a ┆ b │
7 | /// ├╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┤
8 | /// │ c ┆ d │
9 | /// ╰───────┴───────╯
10 | /// ```
11 | pub const UTF8_ROUND_CORNERS: &str = " ╭╮╰╯";
12 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/targets/duckdb.ts:
--------------------------------------------------------------------------------
1 | export * from '../bindings/config';
2 | export * from '../bindings/tokens';
3 | export * from '../log';
4 | export * from '../status';
5 | export * from '../parallel';
6 | export * from '../platform';
7 | export * from '../version';
8 | export * from '../worker';
9 |
10 | export { InstantiationProgress, InstantiationProgressHandler, DuckDBDataProtocol, WebFile } from '../bindings';
11 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/typedoc.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "DuckDB-WASM",
3 | "entryPoints": [
4 | "src/index.ts",
5 | "src/targets/duckdb.ts",
6 | "src/targets/duckdb-browser-blocking.ts",
7 | "src/targets/duckdb-node-blocking.ts"
8 | ],
9 | "readme": "none",
10 | "out": "docs",
11 | "includeVersion": false,
12 | "excludeProtected": true,
13 | "theme": "default"
14 | }
15 |
--------------------------------------------------------------------------------
/tools/dataprep/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "dataprep"
3 | version = "0.1.0"
4 | authors = ["Andre Kohn "]
5 | edition = "2018"
6 |
7 | [dependencies]
8 | chrono = { version = "0.4.19", features = ["serde"] }
9 | serde = { version = "1.0.130", features = ["derive"] }
10 | serde_json = "1.0"
11 | parquet = "13.0.0"
12 | arrow = { version = "13.0.0", features = ["csv", "ipc"] }
13 | clap = "3.0.0-beta.2"
14 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/karma/tests-chrome.cjs:
--------------------------------------------------------------------------------
1 | const base = require('./karma.base.cjs');
2 |
3 | if (process.env.CHROME_BIN === 'undefined') {
4 | process.env.CHROME_BIN = require('puppeteer').executablePath();
5 | }
6 | console.log(`CHROME_BIN=${process.env.CHROME_BIN}`);
7 |
8 | module.exports = function (config) {
9 | config.set({ ...base(config), browsers: ['ChromeHeadlessNoSandbox'], reporters: ['spec'] });
10 | };
11 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/bindings/web_file.ts:
--------------------------------------------------------------------------------
1 | import { DuckDBDataProtocol } from './runtime';
2 |
3 | export interface WebFile {
4 | fileName: string;
5 | dataProtocol: DuckDBDataProtocol;
6 | fileId?: number;
7 | fileSize?: number;
8 | dataUrl?: string;
9 | dataNativeFd?: number;
10 | collectStatistics?: boolean;
11 | reliableHeadRequests?: boolean;
12 | allowFullHttpReads?: boolean;
13 | }
14 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/14.sql:
--------------------------------------------------------------------------------
1 | select
2 | 100.00 * sum(
3 | case
4 | when p_type like 'PROMO%' then l_extendedprice * (1 - l_discount)
5 | else 0
6 | end
7 | ) / sum(l_extendedprice * (1 - l_discount)) as promo_revenue
8 | from
9 | lineitem,
10 | part
11 | where
12 | l_partkey = p_partkey
13 | and l_shipdate >= '1995-09-01'
14 | and l_shipdate < '1995-10-01'
15 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/karma/tests-chrome-coverage.cjs:
--------------------------------------------------------------------------------
1 | const base = require('./karma.base.cjs');
2 |
3 | if (process.env.CHROME_BIN === 'undefined') {
4 | process.env.CHROME_BIN = require('puppeteer').executablePath();
5 | }
6 | console.log(`CHROME_BIN=${process.env.CHROME_BIN}`);
7 |
8 | module.exports = function (config) {
9 | config.set({ ...base(config), browsers: ['ChromeHeadlessNoSandbox'], reporters: ['coverage'] });
10 | };
11 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/17.sql:
--------------------------------------------------------------------------------
1 | select
2 | sum(l_extendedprice) / 7.0 as avg_yearly
3 | from
4 | lineitem,
5 | part
6 | where
7 | p_partkey = l_partkey
8 | and p_brand = 'Brand#23'
9 | and p_container = 'MED BOX'
10 | and l_quantity < (
11 | select
12 | 0.2 * avg(l_quantity)
13 | from
14 | lineitem
15 | where
16 | l_partkey = p_partkey
17 | );
18 |
--------------------------------------------------------------------------------
/scripts/npm_publish_react.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | PROJECT_ROOT="$(cd $(dirname "$BASH_SOURCE[0]") && cd .. && pwd)" &> /dev/null
4 |
5 | cd ${PROJECT_ROOT}/packages/react-duckdb
6 | mkdir -p ./dist/img
7 | cp ${PROJECT_ROOT}/misc/duckdb_wasm.svg ./dist/img/duckdb_wasm.svg
8 | ${PROJECT_ROOT}/scripts/build_duckdb_badge.sh > ./dist/img/duckdb_version_badge.svg
9 |
10 | npm login
11 | npm publish --ignore-scripts --access public --tag ${TAG}
12 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/src/components/minibar_chart.module.css:
--------------------------------------------------------------------------------
1 | .container {
2 | display: flex;
3 | align-items: center;
4 | justify-content: center;
5 | }
6 |
7 | .bar {
8 | flex: 1;
9 | height: 6px;
10 | border-radius: 3px;
11 | background: hsla(56, 100%, 30%, 0.4);
12 | overflow: hidden;
13 | }
14 |
15 | .bar_fill {
16 | height: 100%;
17 | background: hsl(56, 100%, 30%);
18 | border-radius: 3px;
19 | }
20 |
--------------------------------------------------------------------------------
/scripts/npm_publish_shell.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | PROJECT_ROOT="$(cd $(dirname "$BASH_SOURCE[0]") && cd .. && pwd)" &> /dev/null
4 |
5 | cd ${PROJECT_ROOT}/packages/duckdb-wasm-shell
6 | mkdir -p ./dist/img
7 | cp ${PROJECT_ROOT}/misc/duckdb_wasm.svg ./dist/img/duckdb_wasm.svg
8 | ${PROJECT_ROOT}/scripts/build_duckdb_badge.sh > ./dist/img/duckdb_version_badge.svg
9 |
10 | npm login
11 | npm publish --ignore-scripts --access public --tag ${TAG}
12 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/src/pages/blog.module.css:
--------------------------------------------------------------------------------
1 | .section_container {
2 | width: 100%;
3 | padding: 8px;
4 | display: flex;
5 | justify-content: center;
6 | align-items: center;
7 | }
8 |
9 | @media only screen and (min-width: 600px) {
10 | .section {
11 | width: 90%;
12 | max-width: 800px;
13 | }
14 | }
15 | @media only screen and (max-width: 600px) {
16 | .section {
17 | width: 100%;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/logo/duckdb.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/lib/include/duckdb/web/io/file_page_defaults.h:
--------------------------------------------------------------------------------
1 | #ifndef INCLUDE_DUCKDB_WEB_IO_FILE_PAGE_DEFAULTS_H
2 | #define INCLUDE_DUCKDB_WEB_IO_FILE_PAGE_DEFAULTS_H
3 |
4 | #include
5 |
6 | namespace duckdb {
7 | namespace web {
8 | namespace io {
9 |
10 | constexpr size_t DEFAULT_FILE_PAGE_CAPACITY = 10000;
11 | constexpr size_t DEFAULT_FILE_PAGE_SHIFT = 14; // 16KB pages
12 |
13 | } // namespace io
14 | } // namespace web
15 | } // namespace duckdb
16 |
17 | #endif
18 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/src/components/page_structure.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import styles from './page_structure.module.css';
3 |
4 | interface PageSectionProps {
5 | children: React.ReactChild | React.ReactChild[];
6 | }
7 |
8 | export const PageSection: React.FC = (props: PageSectionProps) => (
9 |
10 |
{props.children}
11 |
12 | );
13 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/timer.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/bindings/udf_function.ts:
--------------------------------------------------------------------------------
1 | import { SQLType } from '../json_typedef';
2 | import * as arrow from 'apache-arrow';
3 |
4 | export interface UDFFunctionDeclaration {
5 | functionId: number;
6 | name: string;
7 | returnType: SQLType;
8 | }
9 |
10 | export interface UDFFunction {
11 | functionId: number;
12 | connectionId: number;
13 | name: string;
14 | returnType: arrow.DataType;
15 | func: (...args: any[]) => any;
16 | }
17 |
--------------------------------------------------------------------------------
/.clang-format:
--------------------------------------------------------------------------------
1 | BasedOnStyle: LLVM
2 | IndentWidth: 4
3 | ColumnLimit: 200
4 | AllowShortFunctionsOnASingleLine: Empty
5 | IndentCaseLabels: true
6 | NamespaceIndentation: All
7 | IncludeCategories:
8 | - Regex: '<.*>'
9 | Priority: -1
10 | - Regex: '.*'
11 | Priority: 0
12 | DerivePointerAlignment: false
13 | PointerAlignment: Left
14 | AllowAllArgumentsOnNextLine: true
15 | SpaceAfterTemplateKeyword: false
16 | SpaceBeforeCtorInitializerColon: false
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3.0"
2 | services:
3 | duckdb-wasm-ci:
4 | image: duckdb/wasm-ci:0.75
5 | build:
6 | context: ./actions/image
7 | args:
8 | - GID=0
9 | - UID=0
10 | volumes:
11 | - .:/wd
12 | - ./.ccache:/mnt/ccache
13 | - ./.emscripten_cache:/mnt/emscripten_cache
14 | environment:
15 | - CCACHE_BASEDIR=/wd/lib
16 | - CCACHE_DIR=/mnt/ccache
17 | - EM_CACHE=/mnt/emscripten_cache/
18 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/src/components/page_structure.module.css:
--------------------------------------------------------------------------------
1 | .section_container {
2 | width: 100%;
3 | padding: 16px 8px 8px 8px;
4 | display: flex;
5 | justify-content: center;
6 | align-items: center;
7 | }
8 |
9 | @media only screen and (min-width: 600px) {
10 | .section {
11 | width: 90%;
12 | max-width: 800px;
13 | }
14 | }
15 | @media only screen and (max-width: 600px) {
16 | .section {
17 | width: 100%;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/patches/duckdb/preloaded_httpfs.patch:
--------------------------------------------------------------------------------
1 | diff --git a/src/include/duckdb/main/database.hpp b/src/include/duckdb/main/database.hpp
2 | index d3c5fb9bd5..adc2ac42e6 100644
3 | --- a/src/include/duckdb/main/database.hpp
4 | +++ b/src/include/duckdb/main/database.hpp
5 | @@ -17,6 +17,9 @@
6 | #include "duckdb/main/valid_checker.hpp"
7 |
8 | namespace duckdb {
9 | +
10 | +extern bool preloaded_httpfs;
11 | +
12 | class BufferManager;
13 | class DatabaseManager;
14 | class StorageManager;
15 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/pivot.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/bindings/duckdb_module.ts:
--------------------------------------------------------------------------------
1 | export interface PThread {
2 | unusedWorkers: Worker[];
3 | runningWorkers: Worker[];
4 | }
5 |
6 | export interface DuckDBModule extends EmscriptenModule {
7 | stackSave: typeof stackSave;
8 | stackAlloc: typeof stackAlloc;
9 | stackRestore: typeof stackRestore;
10 | lengthBytesUTF8: typeof lengthBytesUTF8;
11 | stringToUTF8: typeof stringToUTF8;
12 |
13 | ccall: typeof ccall;
14 | PThread: PThread;
15 | }
16 |
--------------------------------------------------------------------------------
/scripts/npm_publish_lib.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | PROJECT_ROOT="$(cd $(dirname "$BASH_SOURCE[0]") && cd .. && pwd)" &> /dev/null
4 |
5 | cd ${PROJECT_ROOT}/packages/duckdb-wasm
6 | mkdir -p ./dist/img
7 | cp ${PROJECT_ROOT}/misc/duckdb.svg ./dist/img/duckdb.svg
8 | cp ${PROJECT_ROOT}/misc/duckdb_wasm.svg ./dist/img/duckdb_wasm.svg
9 | ${PROJECT_ROOT}/scripts/build_duckdb_badge.sh > ./dist/img/duckdb_version_badge.svg
10 |
11 | npm publish --ignore-scripts --access public --tag ${TAG}
12 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/src/pages/docs.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import * as duckdb from '@duckdb/duckdb-wasm';
3 | import styles from './docs.module.css';
4 |
5 | export const Docs = (): React.ReactElement => (
6 | `,
10 | }}
11 | />
12 | );
13 |
14 | export default Docs;
15 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/data-matrix.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/patches/arrow/hashing_compile_in_emscripten.patch:
--------------------------------------------------------------------------------
1 | diff --git a/cpp/src/arrow/util/hashing.h b/cpp/src/arrow/util/hashing.h
2 | index 2de9f41532..1a7803d2d8 100644
3 | --- a/cpp/src/arrow/util/hashing.h
4 | +++ b/cpp/src/arrow/util/hashing.h
5 | @@ -31,6 +31,10 @@
6 | #include
7 | #include
8 |
9 | +#ifdef EMSCRIPTEN
10 | +#include
11 | +#endif
12 | +
13 | #include "arrow/array/builder_binary.h"
14 | #include "arrow/buffer_builder.h"
15 | #include "arrow/result.h"
16 |
--------------------------------------------------------------------------------
/examples/bare-browser/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "@duckdb/duckdb-wasm-examples-bare-browser",
4 | "version": "0.0.1",
5 | "main": "index.js",
6 | "license": "MIT",
7 | "dependencies": {
8 | "@duckdb/duckdb-wasm": "file:../../packages/duckdb-wasm"
9 | },
10 | "devDependencies": {
11 | "http-server": "^14.1.1"
12 | },
13 | "scripts": {
14 | "build": "node ./bundle.mjs",
15 | "server": "http-server"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/lib/include/duckdb/web/test/config.h:
--------------------------------------------------------------------------------
1 | #ifndef INCLUDE_DUCKDB_WEB_TEST_CONFIG_H_
2 | #define INCLUDE_DUCKDB_WEB_TEST_CONFIG_H_
3 |
4 | #include
5 |
6 | #include "duckdb.hpp"
7 |
8 | namespace duckdb {
9 | namespace web {
10 | namespace test {
11 |
12 | extern std::filesystem::path SOURCE_DIR;
13 |
14 | bool CHECK_COLUMN(MaterializedQueryResult &result, uint32_t column, vector values);
15 |
16 | } // namespace test
17 | } // namespace web
18 | } // namespace duckdb
19 |
20 | #endif
21 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/4.sql:
--------------------------------------------------------------------------------
1 | select
2 | o_orderpriority,
3 | count(*) as order_count
4 | from
5 | orders
6 | where
7 | o_orderdate >= '1993-07-01'
8 | and o_orderdate < '1993-10-01'
9 | and exists (
10 | select
11 | *
12 | from
13 | lineitem
14 | where
15 | l_orderkey = o_orderkey
16 | and l_commitdate < l_receiptdate
17 | )
18 | group by
19 | o_orderpriority
20 | order by
21 | o_orderpriority;
22 |
--------------------------------------------------------------------------------
/lib/include/duckdb/web/environment.h:
--------------------------------------------------------------------------------
1 | #ifndef INCLUDE_DUCKDB_WEB_UTILS_ENVIRONMENT_H_
2 | #define INCLUDE_DUCKDB_WEB_UTILS_ENVIRONMENT_H_
3 |
4 | namespace duckdb {
5 | namespace web {
6 |
7 | enum class Environment { WEB, NATIVE };
8 |
9 | #if EMSCRIPTEN
10 | constexpr auto ENVIRONMENT = Environment::WEB;
11 | #else
12 | constexpr auto ENVIRONMENT = Environment::NATIVE;
13 | #endif
14 |
15 | enum NativeTag { NATIVE };
16 | enum WebTag { WEB };
17 |
18 | } // namespace web
19 | } // namespace duckdb
20 |
21 | #endif
22 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 | contact_links:
3 | - name: Feature Request
4 | # manual template until discussion templates are GA
5 | url: https://github.com/duckdb/duckdb-wasm/discussions/new?category=ideas&title=Feature%20Request:%20...&labels=feature&body=Why%20do%20you%20want%20this%20feature%3F
6 | about: Submit feature requests here
7 | - name: Discussions
8 | url: https://github.com/duckdb/duckdb/discussions
9 | about: Please ask and answer general questions here.
10 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/server.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.tgz
2 | /.deploy
3 | /perf.data*
4 | /.cache
5 | /.pages
6 | /worktrees
7 | /.cache
8 | /.ccache
9 | .tmp
10 | /.flatc
11 | /.testfile*
12 | /artifacts
13 | /reports
14 | /packages/reports
15 | /build
16 | /.ccls-cache
17 | /.emscripten_cache
18 | .DS_Store
19 | compile_commands.json
20 |
21 | /target
22 |
23 | # Miscellaneous
24 | .DS_Store
25 | /node_modules
26 | .vscode
27 | !.vscode/settings.json
28 | data/tpch/**/*.parquet
29 | .idea
30 | lib/.idea
31 |
32 | check_duckdb
33 | wasm_setup
34 | loadable_extensions
35 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/13.sql:
--------------------------------------------------------------------------------
1 | select
2 | c_count,
3 | count(*) as custdist
4 | from
5 | (
6 | select
7 | c_custkey,
8 | count(o_orderkey) as c_count
9 | from
10 | customer
11 | left outer join orders on c_custkey = o_custkey
12 | and o_comment not like '%special%requests%'
13 | group by
14 | c_custkey
15 | ) as c_orders
16 | group by
17 | c_count
18 | order by
19 | custdist desc,
20 | c_count desc;
21 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2020",
4 | "module": "es2020",
5 | "moduleResolution": "node",
6 | "strict": true,
7 | "sourceMap": false,
8 | "noImplicitAny": true,
9 | "esModuleInterop": true,
10 | "downlevelIteration": true,
11 | "resolveJsonModule": true,
12 | "skipLibCheck": true,
13 | "jsx": "react",
14 |
15 | "types": ["emscripten", "node", "jasmine"],
16 | "lib": ["es6", "webworker", "dom"]
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/scripts/reset_pages_subtree.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -ex
4 |
5 | PROJECT_ROOT="$(cd $(dirname "$BASH_SOURCE[0]") && cd .. && pwd)" &> /dev/null
6 | PAGES_DIR=${PROJECT_ROOT}/worktrees/gh-pages
7 |
8 | mkdir -p ${PROJECT_ROOT}/worktrees
9 | if [ ! -d ${PAGES_DIR} ]; then
10 | echo "[ RUN ] Add worktree origin/gh-pages"
11 | git worktree add ${PAGES_DIR} origin/gh-pages
12 | fi
13 |
14 | DEFAULT_BRANCH="main"
15 | CURRENT_BRANCH=${1:-main}
16 |
17 | cd ${PAGES_DIR}
18 | git fetch origin gh-pages
19 | git reset --hard origin/gh-pages
20 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/favicons/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "name": "",
3 | "short_name": "",
4 | "icons": [
5 | {
6 | "src": "android-chrome-192x192.png",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | },
10 | {
11 | "src": "android-chrome-512x512.png",
12 | "sizes": "512x512",
13 | "type": "image/png"
14 | }
15 | ],
16 | "theme_color": "#ffffff",
17 | "background_color": "#ffffff",
18 | "display": "standalone"
19 | }
20 |
--------------------------------------------------------------------------------
/extension_config_wasm.cmake:
--------------------------------------------------------------------------------
1 | ################################################################################
2 | # DuckDB-Wasm extension base config
3 | ################################################################################
4 | #
5 |
6 | duckdb_extension_load(json DONT_LINK)
7 | duckdb_extension_load(parquet DONT_LINK)
8 | duckdb_extension_load(autocomplete DONT_LINK)
9 |
10 | duckdb_extension_load(icu DONT_LINK)
11 | duckdb_extension_load(tpcds DONT_LINK)
12 | duckdb_extension_load(tpch DONT_LINK)
13 |
14 | #duckdb_extension_load(httpfs DONT_LINK)
15 |
--------------------------------------------------------------------------------
/lib/src/utils/thread.cc:
--------------------------------------------------------------------------------
1 | #include "duckdb/web/utils/thread.h"
2 |
3 | #include
4 |
5 | namespace duckdb {
6 | namespace web {
7 |
8 | #if !EMSCRIPTEN || WEBDB_THREADS
9 | uint32_t GetThreadID() {
10 | static std::atomic NEXT_THREAD_ID = 1;
11 | static thread_local uint32_t THREAD_ID = 0;
12 | if (THREAD_ID == 0) {
13 | THREAD_ID = NEXT_THREAD_ID++;
14 | }
15 | return THREAD_ID - 1;
16 | };
17 | #else
18 | uint32_t GetThreadID() { return 0; }
19 | #endif
20 |
21 | } // namespace web
22 | } // namespace duckdb
23 |
--------------------------------------------------------------------------------
/tools/dataprep/src/error.rs:
--------------------------------------------------------------------------------
1 | use std::error;
2 | use std::fmt;
3 |
4 | #[derive(Debug)]
5 | pub struct Error {
6 | message: String,
7 | }
8 |
9 | impl Error {
10 | pub fn new(msg: String) -> Box {
11 | Box::new(Self { message: msg })
12 | }
13 | }
14 |
15 | impl fmt::Display for Error {
16 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
17 | write!(f, "{}", self.message)
18 | }
19 | }
20 |
21 | impl error::Error for Error {
22 | fn description(&self) -> &str {
23 | &self.message
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/data-matrix-scan.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/patches/duckdb/no_httpfs.patch:
--------------------------------------------------------------------------------
1 | diff --git a/src/main/database.cpp b/src/main/database.cpp
2 | index db6e1ed445..17f845c75e 100644
3 | --- a/src/main/database.cpp
4 | +++ b/src/main/database.cpp
5 | @@ -506,6 +528,7 @@ idx_t DuckDB::NumberOfThreads() {
6 | }
7 |
8 | bool DatabaseInstance::ExtensionIsLoaded(const std::string &name) {
9 | + if (name == "httpfs") return true;
10 | auto extension_name = ExtensionHelper::GetExtensionName(name);
11 | auto it = loaded_extensions_info.find(extension_name);
12 | return it != loaded_extensions_info.end() && it->second.is_loaded;
13 |
--------------------------------------------------------------------------------
/examples/esbuild-node/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "@duckdb/duckdb-wasm-examples-esbuild-node",
4 | "version": "0.0.1",
5 | "main": "index.js",
6 | "license": "MIT",
7 | "dependencies": {
8 | "@duckdb/duckdb-wasm": "file:../../packages/duckdb-wasm"
9 | },
10 | "devDependencies": {
11 | "esbuild": "^0.20.2",
12 | "typescript": "^5.3.3"
13 | },
14 | "type": "module",
15 | "scripts": {
16 | "build": "node ./bundle.mjs && tsc --noEmit",
17 | "test": "node ./index.mjs"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/3.sql:
--------------------------------------------------------------------------------
1 | select
2 | l_orderkey,
3 | sum(l_extendedprice * (1 - l_discount)) as revenue,
4 | o_orderdate,
5 | o_shippriority
6 | from
7 | customer,
8 | orders,
9 | lineitem
10 | where
11 | c_mktsegment = 'BUILDING'
12 | and c_custkey = o_custkey
13 | and l_orderkey = o_orderkey
14 | and o_orderdate < '1995-03-15'
15 | and l_shipdate > '1995-03-15'
16 | group by
17 | l_orderkey,
18 | o_orderdate,
19 | o_shippriority
20 | order by
21 | revenue desc,
22 | o_orderdate
23 | limit
24 | 10;
25 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/crate/src/shell_options.rs:
--------------------------------------------------------------------------------
1 | use wasm_bindgen::prelude::*;
2 |
3 | #[wasm_bindgen]
4 | extern "C" {
5 | #[wasm_bindgen(js_name = "ShellOptions")]
6 | pub type ShellOptions;
7 | #[wasm_bindgen(method, getter, js_name = "backgroundColor")]
8 | pub fn get_bg(this: &ShellOptions) -> String;
9 | #[wasm_bindgen(method, getter, js_name = "fontFamily")]
10 | pub fn get_font_family(this: &ShellOptions) -> String;
11 | #[wasm_bindgen(method, getter, js_name = "withWebGL")]
12 | pub fn with_webgl(this: &ShellOptions) -> bool;
13 | }
14 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/clockfast.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/scripts/npm_measure_lib.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | PROJECT_ROOT="$(cd $(dirname "$BASH_SOURCE[0]") && cd .. && pwd)" &> /dev/null
4 |
5 | cd ${PROJECT_ROOT}/packages/duckdb-wasm
6 | mkdir -p ./dist/img
7 | cp ${PROJECT_ROOT}/misc/duckdb.svg ./dist/img/duckdb.svg
8 | cp ${PROJECT_ROOT}/misc/duckdb_wasm.svg ./dist/img/duckdb_wasm.svg
9 | ${PROJECT_ROOT}/scripts/build_duckdb_badge.sh > ./dist/img/duckdb_version_badge.svg
10 |
11 | npm install -g pkg-size
12 | pkg-size . --sizes=size > output
13 | cat output
14 | tail -n2 output | grep " MB" | awk '{print ($1 < 150)}' | grep "1" || exit 1
15 |
--------------------------------------------------------------------------------
/scripts/generate_uni.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -euo pipefail
4 |
5 | trap exit SIGINT
6 |
7 | PROJECT_ROOT="$(cd $(dirname "$BASH_SOURCE[0]") && cd .. && pwd)" &> /dev/null
8 |
9 | UNI_DIR=${PROJECT_ROOT}/data/uni
10 | DATAPREP=${PROJECT_ROOT}/target/release/dataprep
11 |
12 | if [ ! -f ${DATAPREP} ]; then
13 | cargo build --manifest-path=${PROJECT_ROOT}/Cargo.toml --release -p dataprep
14 | fi
15 | echo "DATAPREP=${DATAPREP}"
16 |
17 | if [ ! -f "${UNI_DIR}/studenten.parquet" ]; then
18 | mkdir -p ${UNI_DIR}
19 | ${DATAPREP} uni -o ${UNI_DIR}
20 | fi
21 | echo "UNI_DIR=${UNI_DIR}"
22 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/5.sql:
--------------------------------------------------------------------------------
1 | select
2 | n_name,
3 | sum(l_extendedprice * (1 - l_discount)) as revenue
4 | from
5 | customer,
6 | orders,
7 | lineitem,
8 | supplier,
9 | nation,
10 | region
11 | where
12 | c_custkey = o_custkey
13 | and l_orderkey = o_orderkey
14 | and l_suppkey = s_suppkey
15 | and c_nationkey = s_nationkey
16 | and s_nationkey = n_nationkey
17 | and n_regionkey = r_regionkey
18 | and r_name = 'ASIA'
19 | and o_orderdate >= '1994-01-01'
20 | and o_orderdate < '1995-01-01'
21 | group by
22 | n_name
23 | order by
24 | revenue desc;
25 |
--------------------------------------------------------------------------------
/lib/include/duckdb/web/utils/spin_mutex.h:
--------------------------------------------------------------------------------
1 | #ifndef INCLUDE_DUCKDB_WEB_UTILS_SPIN_MUTEX_H_
2 | #define INCLUDE_DUCKDB_WEB_UTILS_SPIN_MUTEX_H_
3 |
4 | #include
5 |
6 | namespace duckdb {
7 | namespace web {
8 |
9 | /// A simple mutex as pure spin-lock that never leaves wasm.
10 | struct SpinMutex {
11 | std::atomic_flag flag{0};
12 | void lock() {
13 | while (flag.test_and_set(std::memory_order_acq_rel))
14 | ;
15 | }
16 | void unlock() { flag.clear(); }
17 | bool try_lock() { return flag.test_and_set(); }
18 | };
19 |
20 | } // namespace web
21 | } // namespace duckdb
22 |
23 | #endif
24 |
--------------------------------------------------------------------------------
/scripts/npm_restore.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | PROJECT_ROOT="$(cd $(dirname "$BASH_SOURCE[0]") && cd .. && pwd)" &> /dev/null
4 |
5 | NPM_VERSION=${1}
6 | echo "NPM_VERSION=${NPM_VERSION}"
7 |
8 | PKG_DIR="${PROJECT_ROOT}/packages/duckdb-wasm"
9 | PKG_TARBALL="duckdb-duckdb-wasm-${NPM_VERSION}.tgz"
10 | TMP_DIR="${PROJECT_ROOT}/.tmp/npm"
11 | echo "${NPM_VERSION}"
12 |
13 | set -x
14 |
15 | rm -rf ${TMP_DIR}
16 | mkdir -p ${TMP_DIR}
17 | cd ${TMP_DIR}
18 |
19 | npm pack "@duckdb/duckdb-wasm@${NPM_VERSION}"
20 | tar -xvzf ./duckdb-duckdb-wasm-*.tgz
21 |
22 | rm -rf "${PKG_DIR}/dist"
23 | cp -r "./package/dist" "${PKG_DIR}/dist"
24 |
--------------------------------------------------------------------------------
/scripts/build_duckdb_badge.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | PROJECT_ROOT="$(cd $(dirname "$BASH_SOURCE[0]") && cd .. && pwd)" &> /dev/null
4 | BADGEGEN=${PROJECT_ROOT}/node_modules/.bin/badge
5 |
6 | cd ${PROJECT_ROOT}/submodules/duckdb
7 | VERSION=`git describe --tags --abbrev=0 | tr -d "v"`
8 | DEV=`git describe --tags --long | cut -f2 -d-`
9 |
10 | BADGE_LABEL_COLOR="#555"
11 | BADGE_VALUE_COLOR="#007ec6"
12 |
13 | if [[ "${DEV}" = "0" ]] ; then
14 | ${BADGEGEN} duckdb "v${VERSION}" ${BADGE_VALUE_COLOR} ${BADGE_LABEL_COLOR}
15 | else
16 | ${BADGEGEN} duckdb "v${VERSION}-dev${DEV}" ${BADGE_VALUE_COLOR} ${BADGE_LABEL_COLOR}
17 | fi
18 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/crate/src/xterm/addons/ligatures.rs:
--------------------------------------------------------------------------------
1 | use crate::xterm::{Terminal, TerminalAddon};
2 | use wasm_bindgen::prelude::*;
3 |
4 | #[wasm_bindgen(module = "xterm-addon-ligatures")]
5 | extern "C" {
6 |
7 | #[wasm_bindgen(extends = TerminalAddon)]
8 | pub type LigaturesAddon;
9 |
10 | #[wasm_bindgen(constructor)]
11 | pub fn new() -> LigaturesAddon;
12 |
13 | #[wasm_bindgen(method, method, js_name = "activate")]
14 | pub fn activate(this: &LigaturesAddon, terminal: &Terminal);
15 |
16 | #[wasm_bindgen(method, method, js_name = "dispose")]
17 | pub fn dispose(this: &LigaturesAddon);
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/crate/src/xterm/addons/unicode11.rs:
--------------------------------------------------------------------------------
1 | use crate::xterm::{Terminal, TerminalAddon};
2 | use wasm_bindgen::prelude::*;
3 |
4 | #[wasm_bindgen(module = "xterm-addon-unicode11")]
5 | extern "C" {
6 |
7 | #[wasm_bindgen(extends = TerminalAddon)]
8 | pub type Unicode11Addon;
9 |
10 | #[wasm_bindgen(constructor)]
11 | pub fn new() -> Unicode11Addon;
12 |
13 | #[wasm_bindgen(method, method, js_name = "activate")]
14 | pub fn activate(this: &Unicode11Addon, terminal: Terminal);
15 |
16 | #[wasm_bindgen(method, method, js_name = "dispose")]
17 | pub fn dispose(this: &Unicode11Addon);
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/1.sql:
--------------------------------------------------------------------------------
1 | select
2 | l_returnflag,
3 | l_linestatus,
4 | sum(l_quantity) as sum_qty,
5 | sum(l_extendedprice) as sum_base_price,
6 | sum(l_extendedprice * (1 - l_discount)) as sum_disc_price,
7 | sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge,
8 | avg(l_quantity) as avg_qty,
9 | avg(l_extendedprice) as avg_price,
10 | avg(l_discount) as avg_disc,
11 | count(*) as count_order
12 | from
13 | lineitem
14 | where
15 | l_shipdate <= '1998-09-02'
16 | group by
17 | l_returnflag,
18 | l_linestatus
19 | order by
20 | l_returnflag,
21 | l_linestatus;
22 |
--------------------------------------------------------------------------------
/patches/duckdb/fix_config_size_t.patch:
--------------------------------------------------------------------------------
1 | diff --git a/src/main/config.cpp b/src/main/config.cpp
2 | index d6147d0ac0..7d81469356 100644
3 | --- a/src/main/config.cpp
4 | +++ b/src/main/config.cpp
5 | @@ -301,7 +301,7 @@ LogicalType DBConfig::ParseLogicalType(const string &type) {
6 | if (StringUtil::EndsWith(type, "]")) {
7 | // array - recurse
8 | auto bracket_open_idx = type.rfind('[');
9 | - if (bracket_open_idx == DConstants::INVALID_INDEX || bracket_open_idx == 0) {
10 | + if (bracket_open_idx == string::npos || bracket_open_idx == 0) {
11 | throw InternalException("Ill formatted type: '%s'", type);
12 | }
13 | idx_t array_size = 0;
14 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: npm
4 | directory: '/'
5 | schedule:
6 | interval: weekly
7 | time: '07:00'
8 | timezone: 'Europe/Berlin'
9 | commit-message:
10 | prefix: fix
11 | prefix-development: chore
12 | include: scope
13 | - package-ecosystem: github-actions
14 | directory: '/'
15 | schedule:
16 | interval: weekly
17 | time: '07:00'
18 | timezone: 'Europe/Berlin'
19 | commit-message:
20 | prefix: fix
21 | prefix-development: chore
22 | include: scope
23 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/16.sql:
--------------------------------------------------------------------------------
1 | select
2 | p_brand,
3 | p_type,
4 | p_size,
5 | count(distinct ps_suppkey) as supplier_cnt
6 | from
7 | partsupp,
8 | part
9 | where
10 | p_partkey = ps_partkey
11 | and p_brand <> 'Brand#45'
12 | and p_type not like 'MEDIUM POLISHED%'
13 | and p_size in (49, 14, 23, 45, 19, 3, 36, 9)
14 | and ps_suppkey not in (
15 | select
16 | s_suppkey
17 | from
18 | supplier
19 | where
20 | s_comment like '%Customer%Complaints%'
21 | )
22 | group by
23 | p_brand,
24 | p_type,
25 | p_size
26 | order by
27 | supplier_cnt desc,
28 | p_brand,
29 | p_type,
30 | p_size;
31 |
--------------------------------------------------------------------------------
/examples/esbuild-browser/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "@duckdb/duckdb-wasm-examples-esbuild-browser",
4 | "version": "0.0.1",
5 | "main": "index.js",
6 | "license": "MIT",
7 | "dependencies": {
8 | "@duckdb/duckdb-wasm": "file:../../packages/duckdb-wasm"
9 | },
10 | "devDependencies": {
11 | "esbuild": "^0.20.2",
12 | "http-server": "^14.1.1",
13 | "serve": "^14.2.1",
14 | "typescript": "^5.3.3"
15 | },
16 | "scripts": {
17 | "build": "node ./bundle.mjs && tsc --noEmit",
18 | "server": "http-server",
19 | "server-coi": "serve"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/18.sql:
--------------------------------------------------------------------------------
1 | select
2 | c_name,
3 | c_custkey,
4 | o_orderkey,
5 | o_orderdate,
6 | o_totalprice,
7 | sum(l_quantity)
8 | from
9 | customer,
10 | orders,
11 | lineitem
12 | where
13 | o_orderkey in (
14 | select
15 | l_orderkey
16 | from
17 | lineitem
18 | group by
19 | l_orderkey
20 | having
21 | sum(l_quantity) > 300
22 | )
23 | and c_custkey = o_custkey
24 | and o_orderkey = l_orderkey
25 | group by
26 | c_name,
27 | c_custkey,
28 | o_orderkey,
29 | o_orderdate,
30 | o_totalprice
31 | order by
32 | o_totalprice desc,
33 | o_orderdate
34 | limit
35 | 100;
36 |
--------------------------------------------------------------------------------
/actions/runner/ufw_before_rules.txt:
--------------------------------------------------------------------------------
1 | # Isolate the VMs
2 | #
3 | # We certainly want GitHub actions at some point but this will do for the private repo.
4 | #
5 | # Find the bridge used by multipass `brctl show`.
6 | # If you run multipass with libvirt (see multipass.sh), the default bridge will be virbr0.
7 | # Get you standard gateway (192.168.178.1/32, here)
8 | #
9 | # Adjust /etc/ufw/before.rules after L17
10 | # Accept all packets from the multipass vm that target the standard gateway.
11 | # Drop all packets from the multipass vm that target any other host.
12 |
13 | -I FORWARD 1 -d 192.168.178.1/32 -i virbr0 -j ACCEPT
14 | -I FORWARD 2 -d 192.168.0.0/16 -i virbr0 -j DROP
15 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/webpack.release.js:
--------------------------------------------------------------------------------
1 | import { configure } from './webpack.common.js';
2 | import { fileURLToPath } from 'url';
3 | import path from 'path';
4 |
5 | const __dirname = path.dirname(fileURLToPath(import.meta.url));
6 |
7 | const base = configure({
8 | buildDir: path.resolve(__dirname, './build/release'),
9 | tsLoaderOptions: {
10 | compilerOptions: {
11 | configFile: './tsconfig.json',
12 | sourceMap: false,
13 | },
14 | },
15 | extractCss: true,
16 | cssIdentifier: '[hash:base64]',
17 | });
18 |
19 | export default {
20 | ...base,
21 | mode: 'production',
22 | devtool: false,
23 | };
24 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/crate/src/comfy/style/cell.rs:
--------------------------------------------------------------------------------
1 | /// This can be set on [columns](crate::Column::set_cell_alignment) and [cells](crate::Cell::set_alignment).
2 | ///
3 | /// Determines how content of cells should be aligned.
4 | ///
5 | /// ```text
6 | /// +----------------------+
7 | /// | Header1 |
8 | /// +======================+
9 | /// | Left |
10 | /// |----------------------+
11 | /// | center |
12 | /// |----------------------+
13 | /// | right |
14 | /// +----------------------+
15 | /// ```
16 | #[derive(Copy, Clone, Debug)]
17 | pub enum CellAlignment {
18 | Left,
19 | Right,
20 | Center,
21 | }
22 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/crate/src/duckdb/version.rs:
--------------------------------------------------------------------------------
1 | use wasm_bindgen::prelude::*;
2 |
3 | #[wasm_bindgen(module = "@duckdb/duckdb-wasm")]
4 | extern "C" {
5 | #[wasm_bindgen(js_name = "PACKAGE_NAME")]
6 | pub static PACKAGE_NAME: String;
7 |
8 | #[wasm_bindgen(js_name = "PACKAGE_VERSION")]
9 | pub static PACKAGE_VERSION: String;
10 | #[wasm_bindgen(js_name = "PACKAGE_VERSION_MAJOR")]
11 | pub static PACKAGE_VERSION_MAJOR: String;
12 | #[wasm_bindgen(js_name = "PACKAGE_VERSION_MINOR")]
13 | pub static PACKAGE_VERSION_MINOR: String;
14 | #[wasm_bindgen(js_name = "PACKAGE_VERSION_PATCH")]
15 | pub static PACKAGE_VERSION_PATCH: String;
16 | }
17 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/crate/src/lib.rs:
--------------------------------------------------------------------------------
1 | pub mod arrow_printer;
2 | pub mod arrow_reader;
3 | pub mod comfy;
4 | pub mod console;
5 | pub mod duckdb;
6 | pub mod error;
7 | pub mod key_event;
8 | pub mod platform;
9 | pub mod prompt_buffer;
10 | pub mod shell;
11 | pub mod shell_api;
12 | pub mod shell_options;
13 | pub mod shell_runtime;
14 | pub mod utils;
15 | pub mod vt100;
16 | pub mod xterm;
17 |
18 | use wasm_bindgen::prelude::*;
19 |
20 | use console::DEFAULT_LOGGER;
21 |
22 | #[wasm_bindgen(start)]
23 | pub fn main() {
24 | console_error_panic_hook::set_once();
25 | log::set_logger(&DEFAULT_LOGGER).unwrap();
26 | log::set_max_level(log::LevelFilter::Info);
27 | }
28 |
--------------------------------------------------------------------------------
/scripts/build_loadable.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -euo pipefail
4 |
5 | trap exit SIGINT
6 |
7 | MODE=$1
8 | FEATURE=$2
9 | INPUT_PATH=./build/${MODE}/${FEATURE}/
10 | OUTPUT_PATH=loadable_extensions/${MODE}/${FEATURE}/
11 |
12 | mkdir -p "${OUTPUT_PATH}"
13 | shopt -s nullglob
14 |
15 | for ext_path in $(find "${INPUT_PATH}" -name '*.duckdb_extension.wasm.lib')
16 | do
17 | ext_name=$(basename "$ext_path" .duckdb_extension.wasm.lib)
18 | echo "Building '$ext_name'..."
19 | emcc "$ext_path" -sSIDE_MODULE=2 -sEXPORTED_FUNCTIONS="_""$ext_name""_init,_""$ext_name""_version" -o "${INPUT_PATH}/$ext_name.duckdb_extension.wasm" -O3 -sSHARED_MEMORY=1 -pthread
20 | done
21 |
--------------------------------------------------------------------------------
/lib/include/duckdb/web/insert_options.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "arrow/ipc/reader.h"
4 | #include "arrow/type.h"
5 | #include "arrow/type_fwd.h"
6 | #include "duckdb/web/arrow_stream_buffer.h"
7 | #include "rapidjson/document.h"
8 |
9 | namespace duckdb {
10 | namespace web {
11 |
12 | /// Get a type name
13 | std::string_view GetTypeName(rapidjson::Type type);
14 | /// Require a boolean field
15 | arrow::Status RequireBoolField(const rapidjson::Value& value, std::string_view name);
16 | /// Require a certain field type
17 | arrow::Status RequireFieldType(const rapidjson::Value& value, rapidjson::Type type, std::string_view field);
18 |
19 | } // namespace web
20 | } // namespace duckdb
21 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/svg/icons/book.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/favicons/safari-pinned-tab.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/src/components/minibar_chart.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import cn from 'classnames';
3 |
4 | import styles from './minibar_chart.module.css';
5 |
6 | interface Props {
7 | className?: string;
8 | value: number;
9 | }
10 |
11 | export const MiniBarChart: React.FC = (props: Props): React.ReactElement => (
12 |
22 | );
23 |
--------------------------------------------------------------------------------
/patches/duckdb/bind_copy_direct_io.patch:
--------------------------------------------------------------------------------
1 | diff --git a/src/planner/binder/statement/bind_copy.cpp b/src/planner/binder/statement/bind_copy.cpp
2 | index ce2f93ad86..140af5ba36 100644
3 | --- a/src/planner/binder/statement/bind_copy.cpp
4 | +++ b/src/planner/binder/statement/bind_copy.cpp
5 | @@ -152,7 +152,9 @@ BoundStatement Binder::BindCopyTo(CopyStatement &stmt, CopyToType copy_to_type)
6 | }
7 | }
8 | bool is_remote_file = FileSystem::IsRemoteFile(stmt.info->file_path);
9 | - if (is_remote_file) {
10 | + if ( is_remote_file ) {
11 | + use_tmp_file = false;
12 | + } else if( context.db->config.options.use_direct_io ) {
13 | use_tmp_file = false;
14 | } else {
15 | auto &fs = FileSystem::GetFileSystem(context);
16 |
--------------------------------------------------------------------------------
/lib/README.md:
--------------------------------------------------------------------------------
1 | # Building and Testing
2 |
3 | Below is a minimal script for building and running the unit tests of the project.
4 |
5 | ```bash
6 | mkdir -p build
7 | cd build
8 | cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug ../lib
9 | cmake --build .
10 |
11 | cd ..
12 | ./scripts/generate_tpch_tbl.sh 0.01
13 | ./scripts/generate_tpch_arrow.sh 0.01
14 | ./scripts/generate_uni.sh
15 |
16 | (cd build && ./tester)
17 | ```
18 |
19 | A standard C++ debugger can be attached to the `tester` program (e.g. `lldb -- ./tester`).
20 |
21 | # Formatting
22 | The following script can be run to format the code.
23 |
24 | ```bash
25 | python3 ./scripts/run_clang_format.py --exclude ./lib/build --exclude ./lib/third_party -r ./lib/ -i
26 | ```
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/10.sql:
--------------------------------------------------------------------------------
1 | select
2 | c_custkey,
3 | c_name,
4 | sum(l_extendedprice * (1 - l_discount)) as revenue,
5 | c_acctbal,
6 | n_name,
7 | c_address,
8 | c_phone,
9 | c_comment
10 | from
11 | customer,
12 | orders,
13 | lineitem,
14 | nation
15 | where
16 | c_custkey = o_custkey
17 | and l_orderkey = o_orderkey
18 | and o_orderdate >= '1993-10-01'
19 | and o_orderdate < '1994-01-01'
20 | and l_returnflag = 'R'
21 | and c_nationkey = n_nationkey
22 | group by
23 | c_custkey,
24 | c_name,
25 | c_acctbal,
26 | c_phone,
27 | n_name,
28 | c_address,
29 | c_comment
30 | order by
31 | revenue desc
32 | limit
33 | 20;
34 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/11.sql:
--------------------------------------------------------------------------------
1 | select
2 | ps_partkey,
3 | sum(ps_supplycost * ps_availqty) as value
4 | from
5 | partsupp,
6 | supplier,
7 | nation
8 | where
9 | ps_suppkey = s_suppkey
10 | and s_nationkey = n_nationkey
11 | and n_name = 'GERMANY'
12 | group by
13 | ps_partkey
14 | having
15 | sum(ps_supplycost * ps_availqty) > (
16 | select
17 | sum(ps_supplycost * ps_availqty) * 0.0001
18 | from
19 | partsupp,
20 | supplier,
21 | nation
22 | where
23 | ps_suppkey = s_suppkey
24 | and s_nationkey = n_nationkey
25 | and n_name = 'GERMANY'
26 | )
27 | order by
28 | value desc;
29 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/test/json.test.ts:
--------------------------------------------------------------------------------
1 | import * as duckdb from '../src/';
2 |
3 | export function testJSON(db: () => duckdb.DuckDBBindings): void {
4 | let conn: duckdb.DuckDBConnection;
5 | beforeEach(() => {
6 | conn = db().connect();
7 | });
8 |
9 | afterEach(() => {
10 | conn.close();
11 | db().flushFiles();
12 | db().dropFiles();
13 | });
14 |
15 | describe('JSON', () => {
16 | it('sample', async () => {
17 | expect(conn.query('select to_json({n: 42})').getChildAt(0)?.toArray()).toEqual(['{"n":42}']);
18 | expect(conn.query("select json_object('duck', 42)").getChildAt(0)?.toArray()).toEqual(['{"duck":42}']);
19 | });
20 | });
21 | }
22 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/test/regression/index.ts:
--------------------------------------------------------------------------------
1 | import * as duckdb from '../../src/';
2 | import { test332 } from './github_332.test';
3 | import { test334 } from './github_334.test';
4 | import { test393 } from './github_393.test';
5 | import { test448 } from './github_448.test';
6 | import { test470 } from './github_470.test';
7 | import { test477 } from './github_477.test';
8 | import { test1467 } from './github_1467.test';
9 | import { test1833 } from './github_1833.test';
10 |
11 | export function testRegressionAsync(adb: () => duckdb.AsyncDuckDB): void {
12 | test332(adb);
13 | test334(adb);
14 | test393(adb);
15 | test448(adb);
16 | test470(adb);
17 | test477(adb);
18 | test1467(adb);
19 | test1833(adb);
20 | }
21 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/src/utils/platform.ts:
--------------------------------------------------------------------------------
1 | // Platform check taken from here:
2 | // https://github.com/xtermjs/xterm.js/blob/master/src/common/Platform.ts#L21
3 |
4 | interface INavigator {
5 | userAgent: string;
6 | language: string;
7 | platform: string;
8 | }
9 |
10 | // We're declaring a navigator global here as we expect it in all runtimes (node and browser), but
11 | // we want this module to live in common.
12 | declare const navigator: INavigator;
13 |
14 | const isNode = typeof navigator === 'undefined' ? true : false;
15 | const userAgent = isNode ? 'node' : navigator.userAgent;
16 |
17 | export const isFirefox = userAgent.includes('Firefox');
18 | export const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);
19 |
--------------------------------------------------------------------------------
/packages/react-duckdb/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@duckdb/react-duckdb",
3 | "version": "1.11.0",
4 | "description": "React components for DuckDB-Wasm",
5 | "license": "MIT",
6 | "repository": {
7 | "type": "git",
8 | "url": "https://github.com/duckdb/duckdb-wasm.git"
9 | },
10 | "keywords": [
11 | "sql",
12 | "duckdb",
13 | "relational",
14 | "database",
15 | "data",
16 | "query",
17 | "wasm",
18 | "analytics",
19 | "olap",
20 | "arrow",
21 | "parquet",
22 | "json",
23 | "csv"
24 | ],
25 | "files": [
26 | "src"
27 | ],
28 | "main": "src/index.ts",
29 | "types": "src/index.ts"
30 | }
31 |
--------------------------------------------------------------------------------
/actions/runner/multipass.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Configure multipass to use the libvirt driver:
4 | #
5 | # sudo apt install libvirt-daemon-system
6 | # sudo snap connect multipass:libvirt
7 | # sudo multipass set local.driver=libvirt
8 | #
9 | # Let the cloud-init setup your vm, afterwards do the following steps:
10 | # * Su actions and register the runner in /home/actions/runner
11 | # * Install the action runner as root via /home/actions/runner/svc.sh install actions
12 | # * Providing the user actions to svc.sh install is crucial since the service needs the correct permissions!
13 |
14 |
15 | multipass launch \
16 | --cpus 8 \
17 | --disk 100G \
18 | --mem 6G \
19 | --name github-duckdb-wasm-ci \
20 | --cloud-init ./cloud-init.yaml
21 |
22 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/src/pages/table.tsx:
--------------------------------------------------------------------------------
1 | import * as rd from '@duckdb/react-duckdb';
2 | import React from 'react';
3 |
4 | import styles from './table.module.css';
5 |
6 | interface Props {
7 | className?: string;
8 | }
9 |
10 | export const TableViewer: React.FC = (props: Props) => {
11 | const db = rd.useDuckDB();
12 | const resolveDB = rd.useDuckDBResolver();
13 | React.useEffect(() => {
14 | if (!db.resolving()) {
15 | resolveDB();
16 | }
17 | }, [db]);
18 |
19 | if (db == null) {
20 | return (
21 |
24 | );
25 | }
26 | return todo
;
27 | };
28 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/webpack.debug.corp.js:
--------------------------------------------------------------------------------
1 | import config from './webpack.debug.js';
2 |
3 | export default {
4 | ...config,
5 | devServer: {
6 | ...config.devServer,
7 | headers: {
8 | 'Access-Control-Allow-Origin': '*',
9 | 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
10 | 'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization',
11 |
12 | // This will enable SharedArrayBuffers in Firefox but will block most requests to third-party sites.
13 | 'Cross-Origin-Resource-Policy': 'cross-origin',
14 | 'Cross-Origin-Embedder-Policy': 'require-corp',
15 | 'Cross-Origin-Opener-Policy': 'same-origin',
16 | },
17 | },
18 | };
19 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/crate/src/xterm/addons/serialize.rs:
--------------------------------------------------------------------------------
1 | use crate::xterm::{Terminal, TerminalAddon};
2 | use wasm_bindgen::prelude::*;
3 |
4 | #[wasm_bindgen(module = "xterm-addon-serialize")]
5 | extern "C" {
6 |
7 | #[wasm_bindgen(extends = TerminalAddon)]
8 | pub type SerializeAddon;
9 |
10 | #[wasm_bindgen(constructor)]
11 | pub fn new() -> SerializeAddon;
12 |
13 | #[wasm_bindgen(method, method, js_name = "activate")]
14 | pub fn activate(this: &SerializeAddon, terminal: Terminal);
15 |
16 | #[wasm_bindgen(method, method, js_name = "serialize")]
17 | pub fn serialize(this: &SerializeAddon, rows: Option) -> String;
18 |
19 | #[wasm_bindgen(method, method, js_name = "dispose")]
20 | pub fn dispose(this: &SerializeAddon);
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/test/string_test_helper.ts:
--------------------------------------------------------------------------------
1 | export function generateLongQueryString(): string {
2 | const aaa = repeatCharacter('A', 512);
3 | const ccc = repeatCharacter('C', 256);
4 | const ddd = repeatCharacter('D', 512);
5 | const eee = repeatCharacter('E', 256);
6 | const ggg = repeatCharacter('G', 128);
7 |
8 | return (
9 | `test=inline` +
10 | `&Test-Security-Token=${aaa}` +
11 | `&Test-Algorithm=${ccc}` +
12 | `&Test-Date=${ddd}` +
13 | `&Test-SignedHeaders=host` +
14 | `&Test-Expires=43200` +
15 | `&Test-Credential=${eee}` +
16 | `&Test-Signature=${ggg}`
17 | );
18 | }
19 |
20 | export function repeatCharacter(char: string, length: number): string {
21 | return char.repeat(length);
22 | }
23 |
--------------------------------------------------------------------------------
/lib/include/duckdb/web/arrow_type_mapping.h:
--------------------------------------------------------------------------------
1 | #ifndef INCLUDE_DUCKDB_WEB_ARROW_TYPE_MAPPING_H_
2 | #define INCLUDE_DUCKDB_WEB_ARROW_TYPE_MAPPING_H_
3 |
4 | #include
5 |
6 | #include "arrow/array/array_base.h"
7 | #include "arrow/type_fwd.h"
8 | #include "duckdb/common/types.hpp"
9 |
10 | namespace duckdb {
11 | namespace web {
12 |
13 | /// Map arrow type
14 | arrow::Result mapArrowTypeToDuckDB(const arrow::DataType& type);
15 | /// Map duckdb type to arrow
16 | arrow::Result> mapDuckDBTypeToArrow(const duckdb::LogicalType& type);
17 | /// Convert an arrow array to a DuckDB vector
18 | arrow::Status convertArrowArrayToDuckDBVector(arrow::Array& in, duckdb::Vector& out);
19 |
20 | } // namespace web
21 | } // namespace duckdb
22 |
23 | #endif
24 |
--------------------------------------------------------------------------------
/scripts/npm_version.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | PROJECT_ROOT="$(cd $(dirname "$BASH_SOURCE[0]") && cd .. && pwd)" &> /dev/null
4 |
5 | # Prerelease everything else
6 | git describe --tags --long
7 | export VERSION=`git describe --tags --abbrev=0 | tr -d "v"`
8 | export DEV=`git describe --tags --long | cut -f2 -d-`
9 | echo "VERSION=${VERSION}"
10 | echo "DEV=${DEV}"
11 |
12 | # Is release?
13 | if [[ "${DEV}" = "0" ]] ; then
14 | for PKG in ${PROJECT_ROOT}/packages/* ; do
15 | cd ${PKG}
16 | npm version ${VERSION}
17 | done
18 | else
19 | for PKG in ${PROJECT_ROOT}/packages/* ; do
20 | cd ${PKG}
21 | npm version ${VERSION}
22 | npm version prerelease --preid="dev"${DEV}
23 | done
24 | fi
25 | echo "TAG=${TAG}"
26 |
27 | cd ${PROJECT_ROOT}
28 | node ${PROJECT_ROOT}/scripts/sync_versions.mjs
29 |
--------------------------------------------------------------------------------
/lib/include/duckdb/web/udf.h:
--------------------------------------------------------------------------------
1 | #ifndef INCLUDE_DUCKDB_WEB_UDF_H_
2 | #define INCLUDE_DUCKDB_WEB_UDF_H_
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #include "arrow/type_fwd.h"
10 | #include "rapidjson/document.h"
11 |
12 | namespace duckdb {
13 | namespace web {
14 |
15 | struct UDFFunctionDeclaration {
16 | /// The name
17 | std::string name = "";
18 | /// The function id
19 | size_t function_id = 0;
20 | /// The argument count
21 | size_t argument_count = 0;
22 | /// The return type
23 | std::shared_ptr return_type = {};
24 |
25 | /// Read from a document
26 | arrow::Status ReadFrom(const rapidjson::Document& doc);
27 | };
28 |
29 | } // namespace web
30 | } // namespace duckdb
31 |
32 | #endif
33 |
--------------------------------------------------------------------------------
/lib/include/duckdb/web/arrow_insert_options.h:
--------------------------------------------------------------------------------
1 | #ifndef INCLUDE_DUCKDB_WEB_ARROW_INSERT_OPTIONS_H_
2 | #define INCLUDE_DUCKDB_WEB_ARROW_INSERT_OPTIONS_H_
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #include "arrow/type_fwd.h"
10 | #include "rapidjson/document.h"
11 |
12 | namespace duckdb {
13 | namespace web {
14 |
15 | /// Get the CSV reader options
16 | struct ArrowInsertOptions {
17 | /// The schema name
18 | std::string schema_name = "";
19 | /// The table name
20 | std::string table_name = "";
21 | /// Create a new table?
22 | bool create_new = true;
23 |
24 | /// Read from input stream
25 | arrow::Status ReadFrom(const rapidjson::Document& doc);
26 | };
27 |
28 | } // namespace web
29 | } // namespace duckdb
30 |
31 | #endif
32 |
--------------------------------------------------------------------------------
/scripts/deploy_benchmarks.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -ex
4 |
5 | PROJECT_ROOT="$(cd $(dirname "$BASH_SOURCE[0]") && cd .. && pwd)" &> /dev/null
6 | PAGES=${PROJECT_ROOT}/worktrees/gh-pages
7 |
8 | mkdir -p ${PROJECT_ROOT}/worktrees
9 | if [ ! -d ${PAGES} ]; then
10 | echo "[ RUN ] Add worktree origin/gh-pages"
11 | git worktree add ${PAGES} origin/gh-pages
12 | fi
13 |
14 | cd ${PAGES}
15 | git fetch origin gh-pages
16 | git reset --hard origin/gh-pages
17 |
18 | mkdir -p data
19 | cp -r ${PROJECT_ROOT}/reports/benchmarks.arrow ./data/benchmarks.arrow
20 | cp -r ${PROJECT_ROOT}/duckdb/benchmarks.json ./data/benchmarks.json
21 | cp -r ${PROJECT_ROOT}/duckdb/benchmarks.csv ./data/benchmarks.csv
22 |
23 | git add ./data/*
24 | git commit --amend -m "Update benchmarks"
25 | git push origin HEAD:gh-pages --force
26 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/20.sql:
--------------------------------------------------------------------------------
1 | select
2 | s_name,
3 | s_address
4 | from
5 | supplier,
6 | nation
7 | where
8 | s_suppkey in (
9 | select
10 | ps_suppkey
11 | from
12 | partsupp
13 | where
14 | ps_partkey in (
15 | select
16 | p_partkey
17 | from
18 | part
19 | where
20 | p_name like 'forest%'
21 | )
22 | and ps_availqty > (
23 | select
24 | 0.5 * sum(l_quantity)
25 | from
26 | lineitem
27 | where
28 | l_partkey = ps_partkey
29 | and l_suppkey = ps_suppkey
30 | and l_shipdate >= '1994-01-01'
31 | and l_shipdate < '1995-01-01'
32 | )
33 | )
34 | and s_nationkey = n_nationkey
35 | and n_name = 'CANADA'
36 | order by
37 | s_name;
38 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/crate/src/xterm/addons/webgl.rs:
--------------------------------------------------------------------------------
1 | use crate::xterm::{Terminal, TerminalAddon};
2 | use wasm_bindgen::prelude::*;
3 | use web_sys::HtmlCanvasElement;
4 |
5 | #[wasm_bindgen(module = "xterm-addon-webgl")]
6 | extern "C" {
7 |
8 | #[wasm_bindgen(extends = TerminalAddon)]
9 | pub type WebglAddon;
10 |
11 | #[wasm_bindgen(method, setter, js_name = "textureAtlas")]
12 | pub fn set_texture_atlas(this: &WebglAddon, val: &HtmlCanvasElement);
13 |
14 | #[wasm_bindgen(constructor)]
15 | pub fn new(preserve_drawing_buffer: Option) -> WebglAddon;
16 |
17 | #[wasm_bindgen(method, method, js_name = "activate")]
18 | pub fn activate(this: &WebglAddon, terminal: Terminal);
19 |
20 | #[wasm_bindgen(method, method, js_name = "dispose")]
21 | pub fn dispose(this: &WebglAddon);
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "repository": {
3 | "type": "git",
4 | "url": "https://github.com/duckdb/duckdb-wasm.git"
5 | },
6 | "private": true,
7 | "workspaces": [
8 | "packages/*",
9 | "examples/*"
10 | ],
11 | "scripts": {
12 | "lint:fix": "yarn workspace @duckdb/duckdb-wasm lint --fix && yarn workspace @duckdb/benchmarks lint --fix && yarn workspace @duckdb/duckdb-wasm-shell lint --fix",
13 | "docs": "yarn workspace @duckdb/duckdb-wasm docs",
14 | "benchmarks:build:browser": "yarn workspace @duckdb/benchmarks build:browser",
15 | "benchmarks:build:node": "yarn workspace @duckdb/benchmarks build:node",
16 | "benchmarks:build": "yarn workspace @duckdb/benchmarks build"
17 | },
18 | "devDependencies": {
19 | "badge-maker": "^3.3.1"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/examples/bare-browser/bundle.mjs:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 | import path from 'path';
3 | import { createRequire } from 'module';
4 |
5 | const require = createRequire(import.meta.url);
6 | const DUCKDB_DIST = path.dirname(require.resolve('@duckdb/duckdb-wasm'));
7 |
8 | function printErr(err) {
9 | if (err) return console.log(err);
10 | }
11 |
12 | fs.copyFile(path.resolve(DUCKDB_DIST, 'duckdb-browser.mjs'), './duckdb-browser.mjs', printErr);
13 | fs.copyFile(path.resolve(DUCKDB_DIST, 'duckdb-mvp.wasm'), './duckdb-mvp.wasm', printErr);
14 | fs.copyFile(path.resolve(DUCKDB_DIST, 'duckdb-eh.wasm'), './duckdb-eh.wasm', printErr);
15 | fs.copyFile(path.resolve(DUCKDB_DIST, 'duckdb-browser-mvp.worker.js'), './duckdb-browser-mvp.worker.js', printErr);
16 | fs.copyFile(path.resolve(DUCKDB_DIST, 'duckdb-browser-eh.worker.js'), './duckdb-browser-eh.worker.js', printErr);
17 |
--------------------------------------------------------------------------------
/packages/benchmarks/src/utils/format.ts:
--------------------------------------------------------------------------------
1 | export enum ByteFormat {
2 | SI = 0,
3 | IEC = 1,
4 | }
5 |
6 | export function formatBytes(value: number, format: ByteFormat = ByteFormat.SI): string {
7 | const [multiple, k, suffix] = format === ByteFormat.SI ? [1000, 'k', 'B'] : [1024, 'K', 'iB'];
8 | const exp = (Math.log(value) / Math.log(multiple)) | 0;
9 | const size = Number((value / Math.pow(multiple, exp)).toFixed(2));
10 | return `${size} ${exp ? `${k}MGTPEZY`[exp - 1] + suffix : `byte${size !== 1 ? 's' : ''}`}`;
11 | }
12 |
13 | export function formatThousands(value: number): string {
14 | const [multiple, k] = [1000, 'k'];
15 | const exp = (Math.log(value) / Math.log(multiple)) | 0;
16 | const size = Number((value / Math.pow(multiple, exp)).toFixed(2));
17 | return size + (exp ? ` ${`${k}MGTPEZY`[exp - 1]}` : '');
18 | }
19 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/crate/src/xterm/addons/web_links.rs:
--------------------------------------------------------------------------------
1 | use crate::xterm::{LinkMatcherOptions, Terminal, TerminalAddon};
2 | use js_sys::Function;
3 | use wasm_bindgen::prelude::*;
4 |
5 | #[wasm_bindgen(module = "xterm-addon-web-links")]
6 | extern "C" {
7 |
8 | #[wasm_bindgen(extends = TerminalAddon)]
9 | pub type WebLinksAddon;
10 |
11 | #[wasm_bindgen(constructor)]
12 | pub fn new(
13 | handler: Option<&Function>, // (event: MouseEvent, uri: &str) => void
14 | options: Option<&LinkMatcherOptions>,
15 | useLinkProvider: Option,
16 | ) -> WebLinksAddon;
17 |
18 | #[wasm_bindgen(method, method, js_name = "activate")]
19 | pub fn activate(this: &WebLinksAddon, terminal: &Terminal);
20 |
21 | #[wasm_bindgen(method, method, js_name = "dispose")]
22 | pub fn dispose(this: &WebLinksAddon);
23 | }
24 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/22-sqlite.sql:
--------------------------------------------------------------------------------
1 | select
2 | cntrycode,
3 | count(*) as numcust,
4 | sum(c_acctbal) as totacctbal
5 | from
6 | (
7 | select
8 | substring(c_phone, 1, 2) as cntrycode,
9 | c_acctbal
10 | from
11 | customer
12 | where
13 | substring(c_phone, 1, 2) in ('13', '31', '23', '29', '30', '18', '17')
14 | and c_acctbal > (
15 | select
16 | avg(c_acctbal)
17 | from
18 | customer
19 | where
20 | c_acctbal > 0.00
21 | and substring(c_phone, 1, 2) in ('13', '31', '23', '29', '30', '18', '17')
22 | )
23 | and not exists (
24 | select
25 | *
26 | from
27 | orders
28 | where
29 | o_custkey = c_custkey
30 | )
31 | ) as custsale
32 | group by
33 | cntrycode
34 | order by
35 | cntrycode;
36 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "./dist/",
4 | "target": "es2020",
5 | "module": "es2020",
6 | "moduleResolution": "node",
7 | "strict": true,
8 | "sourceMap": false,
9 | "declaration": true,
10 | "declarationMap": false,
11 | "declarationDir": "./dist/types/",
12 | "noImplicitAny": true,
13 | "esModuleInterop": true,
14 | "downlevelIteration": true,
15 | "resolveJsonModule": true,
16 | "skipLibCheck": true,
17 |
18 | "types": ["emscripten", "node", "jasmine"],
19 | "typeRoots": ["./types", "./node_modules/@types", "../../node_modules/@types"],
20 | "lib": ["es6", "webworker", "dom"]
21 | },
22 | "exclude": ["./node_modules"],
23 | "include": ["./src/**/*", "./test/**/*", "./types/*.d.ts"]
24 | }
25 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/static/fonts/fonts.module.css:
--------------------------------------------------------------------------------
1 | /* -------------------------------------------------------------------- */
2 |
3 | @font-face {
4 | font-family: 'Nunito';
5 | font-style: normal;
6 | font-weight: 300;
7 | src: url(./Nunito-Light.ttf) format('truetype');
8 | }
9 |
10 | @font-face {
11 | font-family: 'Nunito';
12 | font-style: normal;
13 | font-weight: 400;
14 | src: url(./Nunito-Regular.ttf) format('truetype');
15 | }
16 |
17 | @font-face {
18 | font-family: 'Nunito';
19 | font-style: normal;
20 | font-weight: 500;
21 | src: url(./Nunito-SemiBold.ttf) format('truetype');
22 | }
23 |
24 | @font-face {
25 | font-family: 'Nunito';
26 | font-style: normal;
27 | font-weight: 700;
28 | src: url(./Nunito-Bold.ttf) format('truetype');
29 | }
30 |
31 | /* -------------------------------------------------------------------- */
32 |
--------------------------------------------------------------------------------
/lib/test/tester.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "duckdb/web/test/config.h"
5 | #include "gflags/gflags.h"
6 | #include "gtest/gtest.h"
7 |
8 | using namespace duckdb::web::test;
9 |
10 | DEFINE_string(source_dir, "", "Source directory");
11 |
12 | namespace duckdb {
13 | namespace web {
14 | namespace test {
15 |
16 | std::filesystem::path SOURCE_DIR;
17 |
18 | }
19 | } // namespace web
20 | } // namespace duckdb
21 |
22 | int main(int argc, char* argv[]) {
23 | gflags::AllowCommandLineReparsing();
24 | gflags::SetUsageMessage("Usage: ./tester --source_dir ");
25 | gflags::ParseCommandLineFlags(&argc, &argv, false);
26 |
27 | if (std::filesystem::exists(FLAGS_source_dir)) {
28 | SOURCE_DIR = std::filesystem::path{FLAGS_source_dir};
29 | }
30 |
31 | testing::InitGoogleTest(&argc, argv);
32 | return RUN_ALL_TESTS();
33 | }
34 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": "./src",
4 | "outDir": "./build/ts/",
5 | "target": "es5",
6 | "module": "es2020",
7 | // TODO(ankoh): Upgrade node resolution to node12 for exports once typescript 4.6.0 is out
8 | // https://www.typescriptlang.org/docs/handbook/esm-node.html
9 | "moduleResolution": "node",
10 | "sourceMap": true,
11 | "noImplicitAny": true,
12 | "esModuleInterop": true,
13 | "downlevelIteration": true,
14 | "strict": true,
15 | "jsx": "react",
16 | "types": ["emscripten", "node", "jasmine"],
17 | "plugins": [{ "name": "typescript-plugin-css-modules" }],
18 | "lib": ["es6", "es2020", "dom"]
19 | },
20 | "exclude": ["./node_modules"],
21 | "include": ["./src/**/*", "./test/**/*", "./types/*.d.ts"]
22 | }
23 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "./dist/",
4 | "target": "es2020",
5 | "module": "es2020",
6 | "moduleResolution": "node",
7 | "strict": true,
8 | "sourceMap": false,
9 | "declaration": true,
10 | "declarationMap": false,
11 | "declarationDir": "./dist/types/",
12 | "noImplicitAny": true,
13 | "esModuleInterop": true,
14 | "downlevelIteration": true,
15 | "resolveJsonModule": true,
16 | "skipLibCheck": true,
17 |
18 | "types": ["emscripten", "node", "jasmine"],
19 | "typeRoots": ["./types", "./node_modules/@types", "../../node_modules/@types"],
20 | "lib": ["es6", "webworker", "dom"]
21 | },
22 | "include": [".eslintrc.js", "./src/**/*", "./types/*.d.ts", "./test/**/*"],
23 | "exclude": ["./test/node/**/*"]
24 | }
25 |
--------------------------------------------------------------------------------
/scripts/format.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -euo pipefail
3 |
4 | PROJECT_ROOT="$(cd $(dirname "$BASH_SOURCE[0]") && cd .. && pwd)" &> /dev/null
5 |
6 | PRETTIER_WRITE_MODE="--check"
7 | CLANG_FORMAT_WRITE_MODE="--dry-run -Werror"
8 |
9 | if [ -z "${1:-}" ] || [ ! "$1" = "check" ]; then
10 | PRETTIER_WRITE_MODE="--write"
11 | CLANG_FORMAT_WRITE_MODE="-i"
12 | fi
13 |
14 | npx prettier \
15 | $PRETTIER_WRITE_MODE \
16 | "$PROJECT_ROOT/**/*.{js,json,ts,tsx,d.ts,css}" \
17 | --config "$PROJECT_ROOT/.prettierrc" \
18 | --ignore-path "$PROJECT_ROOT/.prettierignore"
19 |
20 | find -E $PROJECT_ROOT \
21 | -regex '.*/(\..*|submodules|node_modules|install|build)/.*' -prune -o \
22 | -regex "$PROJECT_ROOT/proto/.*" -prune -o \
23 | -regex '.*\.(cc|h)' \
24 | -exec echo clang-format $CLANG_FORMAT_WRITE_MODE {} \; \
25 | -exec clang-format $CLANG_FORMAT_WRITE_MODE {} \;
26 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/21.sql:
--------------------------------------------------------------------------------
1 | select
2 | s_name,
3 | count(*) as numwait
4 | from
5 | supplier,
6 | lineitem l1,
7 | orders,
8 | nation
9 | where
10 | s_suppkey = l1.l_suppkey
11 | and o_orderkey = l1.l_orderkey
12 | and o_orderstatus = 'F'
13 | and l1.l_receiptdate > l1.l_commitdate
14 | and exists (
15 | select
16 | *
17 | from
18 | lineitem l2
19 | where
20 | l2.l_orderkey = l1.l_orderkey
21 | and l2.l_suppkey <> l1.l_suppkey
22 | )
23 | and not exists (
24 | select
25 | *
26 | from
27 | lineitem l3
28 | where
29 | l3.l_orderkey = l1.l_orderkey
30 | and l3.l_suppkey <> l1.l_suppkey
31 | and l3.l_receiptdate > l3.l_commitdate
32 | )
33 | and s_nationkey = n_nationkey
34 | and n_name = 'SAUDI ARABIA'
35 | group by
36 | s_name
37 | order by
38 | numwait desc,
39 | s_name
40 | limit
41 | 100;
42 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/webpack.tests.js:
--------------------------------------------------------------------------------
1 | import { configure } from './webpack.common.js';
2 | import { fileURLToPath } from 'url';
3 | import path from 'path';
4 |
5 | const __dirname = path.dirname(fileURLToPath(import.meta.url));
6 | const buildDir = path.resolve(__dirname, './build/tests');
7 |
8 | const base = configure({
9 | buildDir: buildDir,
10 | extractCss: false,
11 | cssIdentifier: '[hash:base64]',
12 | });
13 |
14 | export default {
15 | ...base,
16 | entry: {
17 | tests: ['./test/index.ts'],
18 | },
19 | output: {
20 | path: buildDir,
21 | filename: '[name].js',
22 | chunkFilename: 'static/js/[name].[contenthash].js',
23 | assetModuleFilename: 'static/assets/[name].[contenthash].[ext]',
24 | webassemblyModuleFilename: 'static/wasm/[hash].wasm',
25 | clean: true,
26 | },
27 | mode: 'development',
28 | devtool: false,
29 | };
30 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/9-sqlite.sql:
--------------------------------------------------------------------------------
1 | select
2 | nation,
3 | o_year,
4 | sum(amount) as sum_profit
5 | from
6 | (
7 | select
8 | n_name as nation,
9 | strftime('%Y', o_orderdate) as o_year,
10 | l_extendedprice * (1 - l_discount) - ps_supplycost * l_quantity as amount
11 | from
12 | part,
13 | supplier,
14 | lineitem,
15 | partsupp,
16 | orders,
17 | nation
18 | where
19 | s_suppkey = l_suppkey
20 | and ps_suppkey = l_suppkey
21 | and ps_partkey = l_partkey
22 | and p_partkey = l_partkey
23 | and o_orderkey = l_orderkey
24 | and s_nationkey = n_nationkey
25 | and p_name like '%green%'
26 | ) as profit
27 | group by
28 | nation,
29 | o_year
30 | order by
31 | nation,
32 | o_year desc;
33 |
--------------------------------------------------------------------------------
/lib/test/bugs_test.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "duckdb/common/types/date.hpp"
5 | #include "duckdb/common/types/timestamp.hpp"
6 | #include "duckdb/web/environment.h"
7 | #include "duckdb/web/io/ifstream.h"
8 | #include "duckdb/web/io/memory_filesystem.h"
9 | #include "duckdb/web/test/config.h"
10 | #include "duckdb/web/webdb.h"
11 | #include "gtest/gtest.h"
12 |
13 | using namespace duckdb::web;
14 | using namespace std;
15 |
16 | namespace {
17 |
18 | // https://github.com/duckdb/duckdb-wasm/issues/234
19 | TEST(Bugs, DISABLED_Decimals) {
20 | auto db = make_shared(NATIVE);
21 | WebDB::Connection conn{*db};
22 | auto buffer = conn.RunQuery("SELECT 1::DECIMAL(2,1);");
23 | ASSERT_TRUE(buffer.ok()) << buffer.status().message();
24 | buffer = conn.RunQuery("SELECT 1::DECIMAL(2,0);");
25 | ASSERT_TRUE(buffer.ok()) << buffer.status().message();
26 | }
27 |
28 | } // namespace
29 |
--------------------------------------------------------------------------------
/misc/duckdb_wasm.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/12.sql:
--------------------------------------------------------------------------------
1 | select
2 | l_shipmode,
3 | cast(
4 | sum(
5 | case
6 | when o_orderpriority = '1-URGENT'
7 | or o_orderpriority = '2-HIGH' then 1
8 | else 0
9 | end
10 | ) as integer
11 | ) as high_line_count,
12 | cast(
13 | sum(
14 | case
15 | when o_orderpriority <> '1-URGENT'
16 | and o_orderpriority <> '2-HIGH' then 1
17 | else 0
18 | end
19 | ) as integer
20 | ) as low_line_count
21 | from
22 | orders,
23 | lineitem
24 | where
25 | o_orderkey = l_orderkey
26 | and l_shipmode in ('MAIL', 'SHIP')
27 | and l_commitdate < l_receiptdate
28 | and l_shipdate < l_commitdate
29 | and l_receiptdate >= '1994-01-01'
30 | and l_receiptdate < '1995-01-01'
31 | group by
32 | l_shipmode
33 | order by
34 | l_shipmode;
35 |
--------------------------------------------------------------------------------
/lib/include/duckdb/web/json_dataview.h:
--------------------------------------------------------------------------------
1 | #define RAPIDJSON_HAS_STDSTRING 1
2 |
3 | #ifndef INCLUDE_DUCKDB_WEB_JSON_DATAVIEW_H_
4 | #define INCLUDE_DUCKDB_WEB_JSON_DATAVIEW_H_
5 |
6 | #include
7 | #include
8 | #include
9 |
10 | #include "arrow/type.h"
11 | #include "arrow/type_fwd.h"
12 | #include "duckdb/web/json_analyzer.h"
13 | #include "duckdb/web/json_parser.h"
14 | #include "rapidjson/document.h"
15 |
16 | namespace duckdb {
17 | namespace web {
18 | namespace json {
19 |
20 | typedef vector> additional_buffers_t;
21 |
22 | /// Serialize a DuckDB Vector as JSON data view
23 | arrow::Result CreateDataView(rapidjson::Document& doc, duckdb::DataChunk& chunk,
24 | std::vector& data_ptrs, additional_buffers_t& buffers);
25 |
26 | } // namespace json
27 | } // namespace web
28 | } // namespace duckdb
29 |
30 | #endif
31 |
--------------------------------------------------------------------------------
/misc/duckdb_wasm_light.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/15.sql:
--------------------------------------------------------------------------------
1 | SELECT
2 | s_suppkey,
3 | s_name,
4 | s_address,
5 | s_phone,
6 | total_revenue
7 | FROM
8 | supplier,
9 | (
10 | SELECT
11 | l_suppkey AS supplier_no,
12 | sum(l_extendedprice * (1 - l_discount)) AS total_revenue
13 | FROM
14 | lineitem
15 | WHERE
16 | l_shipdate >= '1996-01-01'
17 | AND l_shipdate < '1996-04-01'
18 | GROUP BY
19 | supplier_no
20 | ) revenue0
21 | WHERE
22 | s_suppkey = supplier_no
23 | AND total_revenue = (
24 | SELECT
25 | max(total_revenue)
26 | FROM
27 | (
28 | SELECT
29 | l_suppkey AS supplier_no,
30 | sum(l_extendedprice * (1 - l_discount)) AS total_revenue
31 | FROM
32 | lineitem
33 | WHERE
34 | l_shipdate >= '1996-01-01'
35 | AND l_shipdate < '1996-04-01'
36 | GROUP BY
37 | supplier_no
38 | ) revenue1
39 | )
40 | ORDER BY
41 | s_suppkey;
42 |
--------------------------------------------------------------------------------
/packages/benchmarks/src/suite_internal.ts:
--------------------------------------------------------------------------------
1 | import { benchmarkUDF, benchmarkFormat, benchmarkIterator, benchmarkIteratorAsync } from './internal';
2 | import { runBenchmarks } from './suite';
3 | import { Benchmark } from 'buffalo-bench';
4 | import { setupDuckDBAsync, setupDuckDBSync, writeReport } from './setup';
5 |
6 | async function main() {
7 | const duckdbSync = await setupDuckDBSync();
8 | const duckdbAsync = await setupDuckDBAsync();
9 |
10 | let suite: Benchmark[] = [];
11 | suite = suite.concat(benchmarkUDF(() => duckdbSync!));
12 | suite = suite.concat(benchmarkFormat(() => duckdbSync!));
13 | suite = suite.concat(benchmarkFormat(() => duckdbSync!));
14 | suite = suite.concat(benchmarkIterator(() => duckdbSync!));
15 | suite = suite.concat(benchmarkIteratorAsync(() => duckdbAsync!));
16 | const results = await runBenchmarks(suite);
17 | console.log(results);
18 | await writeReport(results, './benchmark_internal.json');
19 | }
20 |
21 | main();
22 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/9.sql:
--------------------------------------------------------------------------------
1 | select
2 | nation,
3 | o_year,
4 | sum(amount) as sum_profit
5 | from
6 | (
7 | select
8 | n_name as nation,
9 | extract(
10 | year
11 | from
12 | o_orderdate
13 | ) as o_year,
14 | l_extendedprice * (1 - l_discount) - ps_supplycost * l_quantity as amount
15 | from
16 | part,
17 | supplier,
18 | lineitem,
19 | partsupp,
20 | orders,
21 | nation
22 | where
23 | s_suppkey = l_suppkey
24 | and ps_suppkey = l_suppkey
25 | and ps_partkey = l_partkey
26 | and p_partkey = l_partkey
27 | and o_orderkey = l_orderkey
28 | and s_nationkey = n_nationkey
29 | and p_name like '%green%'
30 | ) as profit
31 | group by
32 | nation,
33 | o_year
34 | order by
35 | nation,
36 | o_year desc;
37 |
--------------------------------------------------------------------------------
/lib/include/duckdb/web/utils/shared_mutex.h:
--------------------------------------------------------------------------------
1 | #ifndef INCLUDE_DUCKDB_WEB_UTILS_SHARED_MUTEX_H_
2 | #define INCLUDE_DUCKDB_WEB_UTILS_SHARED_MUTEX_H_
3 |
4 | #include
5 |
6 | namespace duckdb {
7 | namespace web {
8 |
9 | class SharedMutex {
10 | protected:
11 | /// The lock data
12 | std::atomic data;
13 | /// Tries to mark the lock as waiting either as reader or writer
14 | bool tryMarkAsWaiting(bool writer);
15 |
16 | public:
17 | /// Constructor
18 | SharedMutex() : data{0} {}
19 | /// Deleted copy constructor
20 | SharedMutex(const SharedMutex&) = delete;
21 |
22 | /// Try to lock shared
23 | bool try_lock_shared();
24 | /// Try to lock exclusively
25 | bool try_lock();
26 | /// Lock
27 | void lock();
28 | /// Lock shared
29 | void lock_shared();
30 | /// Unlock
31 | void unlock();
32 | /// Unlock shared
33 | void unlock_shared();
34 | };
35 |
36 | } // namespace web
37 | } // namespace duckdb
38 |
39 | #endif
40 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/src/pages/versus.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | width: 100%;
3 | height: 100%;
4 | background-color: rgb(230, 230, 230);
5 |
6 | overflow-y: auto;
7 | }
8 |
9 | .root_spinner {
10 | width: 100%;
11 | height: 100%;
12 | background-color: rgb(230, 230, 230);
13 |
14 | display: grid;
15 | align-items: center;
16 | justify-content: center;
17 | }
18 |
19 | .content {
20 | padding: 8px 0px;
21 | }
22 |
23 | .tldr {
24 | font-style: italic;
25 | text-align: justify;
26 | padding: 4px 4px;
27 | }
28 |
29 | .header2 {
30 | margin-bottom: 16px;
31 | }
32 |
33 | .link {
34 | margin-left: 4px;
35 | margin-right: 4px;
36 | }
37 |
38 | .section_text {
39 | padding: 0px 4px;
40 | text-align: justify;
41 | margin-bottom: 8px !important;
42 | }
43 |
44 | .feature_table {
45 | margin: 24px 0px 32px 0px;
46 | }
47 |
48 | .tpch_table {
49 | margin: 16px 0px;
50 | }
51 |
52 | .micro_table {
53 | margin: 24px 0px 24px 0px;
54 | }
55 |
--------------------------------------------------------------------------------
/lib/include/duckdb/web/io/glob.h:
--------------------------------------------------------------------------------
1 | #ifndef INCLUDE_DUCKDB_WEB_GLOB_H_
2 | #define INCLUDE_DUCKDB_WEB_GLOB_H_
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | namespace duckdb {
9 | namespace web {
10 | namespace io {
11 |
12 | struct GlobToRegexOptions {
13 | /// Enables "extended" globs (like bash) which
14 | /// supports single character matching, matching ranges of characters,
15 | /// group matching, etc.
16 | bool extended = false;
17 | /// glob_star determines whether a star should match trailing paths
18 | /// '/foo/*' => '^\/foo\/.*$' vs. '^\/foo\/[^/]*$'
19 | /// true false
20 | bool glob_star = false;
21 | /// Case insensitive matching
22 | bool case_insensitive = false;
23 | /// Match anywhere in the string?
24 | bool global = false;
25 | };
26 |
27 | std::regex glob_to_regex(std::string_view glob, GlobToRegexOptions options = {});
28 |
29 | } // namespace io
30 | } // namespace web
31 | } // namespace duckdb
32 |
33 | #endif
34 |
--------------------------------------------------------------------------------
/lib/test/ifstream_test.cc:
--------------------------------------------------------------------------------
1 | #include "duckdb/web/io/ifstream.h"
2 |
3 | #include
4 |
5 | #include "duckdb/web/test/config.h"
6 | #include "gtest/gtest.h"
7 |
8 | using namespace duckdb::web;
9 | using namespace std;
10 |
11 | namespace {
12 |
13 | TEST(InputStreamBuffer, istreambuf_iterator) {
14 | auto fs = duckdb::FileSystem::CreateLocal();
15 | auto file_page_buffer = std::make_shared(std::move(fs));
16 | auto path = duckdb::web::test::SOURCE_DIR / ".." / "data" / "test.json";
17 | std::string expected;
18 | std::string have;
19 | {
20 | std::ifstream ifs{path};
21 | expected = {std::istreambuf_iterator{ifs}, std::istreambuf_iterator{}};
22 | }
23 | auto input = std::make_shared(file_page_buffer, path.c_str());
24 | {
25 | std::istream ifs{input.get()};
26 | have = {std::istreambuf_iterator{ifs}, std::istreambuf_iterator{}};
27 | }
28 | ASSERT_EQ(expected, have);
29 | }
30 |
31 | } // namespace
32 |
--------------------------------------------------------------------------------
/lib/include/duckdb/web/utils/parallel.h:
--------------------------------------------------------------------------------
1 | #ifndef INCLUDE_DUCKDB_WEB_UTILS_MUTEX_H_
2 | #define INCLUDE_DUCKDB_WEB_UTILS_MUTEX_H_
3 |
4 | #ifdef DUCKDB_NO_THREADS
5 |
6 | namespace duckdb {
7 | namespace web {
8 |
9 | // A pseudo mutex that does nothing.
10 | // We use this for single-threaded versions of duckdb-wasm.
11 | struct PseudoMutex {
12 | void lock() {}
13 | void lock_shared() {}
14 | void unlock() {}
15 | void unlock_shared() {}
16 | bool try_lock() { return true; }
17 | bool try_lock_shared() { return true; }
18 | };
19 | using SharedMutex = PseudoMutex;
20 | using LightMutex = PseudoMutex;
21 |
22 | } // namespace web
23 | } // namespace duckdb
24 |
25 | #else
26 |
27 | // #include "duckdb/web/utils/shared_mutex.h"
28 | #include
29 |
30 | #include "duckdb/web/utils/spin_mutex.h"
31 |
32 | namespace duckdb {
33 | namespace web {
34 |
35 | using SharedMutex = std::shared_mutex;
36 | using LightMutex = SpinMutex;
37 |
38 | } // namespace web
39 | } // namespace duckdb
40 |
41 | #endif
42 |
43 | #endif
44 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/22.sql:
--------------------------------------------------------------------------------
1 | select
2 | cntrycode,
3 | count(*) as numcust,
4 | sum(c_acctbal) as totacctbal
5 | from
6 | (
7 | select
8 | substring(
9 | c_phone
10 | from
11 | 1 for 2
12 | ) as cntrycode,
13 | c_acctbal
14 | from
15 | customer
16 | where
17 | substring(
18 | c_phone
19 | from
20 | 1 for 2
21 | ) in ('13', '31', '23', '29', '30', '18', '17')
22 | and c_acctbal > (
23 | select
24 | avg(c_acctbal)
25 | from
26 | customer
27 | where
28 | c_acctbal > 0.00
29 | and substring(
30 | c_phone
31 | from
32 | 1 for 2
33 | ) in ('13', '31', '23', '29', '30', '18', '17')
34 | )
35 | and not exists (
36 | select
37 | *
38 | from
39 | orders
40 | where
41 | o_custkey = c_custkey
42 | )
43 | ) as custsale
44 | group by
45 | cntrycode
46 | order by
47 | cntrycode;
48 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/bindings/bindings_browser_mvp.ts:
--------------------------------------------------------------------------------
1 | import DuckDBWasm from './duckdb-mvp.js';
2 | import { DuckDBBrowserBindings } from './bindings_browser_base';
3 | import { DuckDBModule } from './duckdb_module';
4 | import { DuckDBRuntime } from './runtime';
5 | import { Logger } from '../log';
6 |
7 | /** DuckDB bindings for the browser */
8 | export class DuckDB extends DuckDBBrowserBindings {
9 | /** Constructor */
10 | public constructor(
11 | logger: Logger,
12 | runtime: DuckDBRuntime,
13 | mainModuleURL: string,
14 | pthreadWorkerURL: string | null = null,
15 | ) {
16 | super(logger, runtime, mainModuleURL, pthreadWorkerURL);
17 | }
18 |
19 | /** Instantiate the bindings */
20 | protected instantiateImpl(moduleOverrides: Partial): Promise {
21 | return DuckDBWasm({
22 | ...moduleOverrides,
23 | instantiateWasm: this.instantiateWasm.bind(this),
24 | locateFile: this.locateFile.bind(this),
25 | });
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2018-2025 Stichting DuckDB Foundation
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/2.sql:
--------------------------------------------------------------------------------
1 | select
2 | s_acctbal,
3 | s_name,
4 | n_name,
5 | p_partkey,
6 | p_mfgr,
7 | s_address,
8 | s_phone,
9 | s_comment
10 | from
11 | part,
12 | supplier,
13 | partsupp,
14 | nation,
15 | region
16 | where
17 | p_partkey = ps_partkey
18 | and s_suppkey = ps_suppkey
19 | and p_size = 15
20 | and p_type like '%BRASS'
21 | and s_nationkey = n_nationkey
22 | and n_regionkey = r_regionkey
23 | and r_name = 'EUROPE'
24 | and ps_supplycost = (
25 | select
26 | min(ps_supplycost)
27 | from
28 | partsupp,
29 | supplier,
30 | nation,
31 | region
32 | where
33 | p_partkey = ps_partkey
34 | and s_suppkey = ps_suppkey
35 | and s_nationkey = n_nationkey
36 | and n_regionkey = r_regionkey
37 | and r_name = 'EUROPE'
38 | )
39 | order by
40 | s_acctbal desc,
41 | n_name,
42 | s_name,
43 | p_partkey
44 | limit
45 | 100;
46 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/crate/src/duckdb/web_file.rs:
--------------------------------------------------------------------------------
1 | use serde::{Deserialize, Serialize};
2 |
3 | #[derive(Serialize, Deserialize, Debug)]
4 | #[repr(u8)]
5 | pub enum DataProtocol {
6 | Buffer = 0,
7 | Native = 1,
8 | Http = 2,
9 | }
10 |
11 | #[derive(Serialize, Deserialize, Debug, Default)]
12 | pub struct WebFile {
13 | #[serde(rename = "fileName")]
14 | pub file_name: String,
15 | #[serde(rename = "fileId")]
16 | pub file_id: Option,
17 | #[serde(rename = "fileSize")]
18 | pub file_size: Option,
19 | #[serde(rename = "dataProtocol")]
20 | pub data_protocol: Option,
21 | #[serde(rename = "dataUrl")]
22 | pub data_url: Option,
23 | #[serde(rename = "dataNativeFd")]
24 | pub data_native_fd: Option,
25 | #[serde(rename = "reliableHeadRequests")]
26 | pub reliable_head_requests: Option,
27 | #[serde(rename = "allowFullHttpReads")]
28 | pub allow_full_http_reads: Option,
29 | #[serde(rename = "collectStatistics")]
30 | pub collect_statistics: Option,
31 | }
32 |
--------------------------------------------------------------------------------
/scripts/generate_tpch_duckdb.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -euo pipefail
4 |
5 | trap exit SIGINT
6 |
7 | PROJECT_ROOT="$(cd $(dirname "$BASH_SOURCE[0]") && cd .. && pwd)" &> /dev/null
8 | DUCKDB_DIR="${PROJECT_ROOT}/submodules/duckdb/"
9 | DUCKDB_BUILD_DIR="${DUCKDB_DIR}/build/Release"
10 | DUCKDB_SHELL="duckdb"
11 | SCALE_FACTOR=${1:-0.01}
12 | SCALE_FACTOR_DIR=${SCALE_FACTOR/./_}
13 | TPCH_DIR=${PROJECT_ROOT}/data/tpch
14 | TPCH_SF_OUT=${TPCH_DIR}/${SCALE_FACTOR_DIR}
15 | TPCH_SF_OUT_DUCKDB=${TPCH_SF_OUT}/duckdb
16 | TPCH_SF_OUT_DUCKDB_DB=${TPCH_SF_OUT_DUCKDB}/db
17 | DUCKDB_SCRIPT_FILE=${TPCH_SF_OUT_DUCKDB}/script.sql
18 |
19 | chmod +x ${DUCKDB_SHELL}
20 | mkdir -p ${TPCH_SF_OUT_DUCKDB}
21 | rm -r ${TPCH_SF_OUT_DUCKDB}
22 | mkdir -p ${TPCH_SF_OUT_DUCKDB}
23 |
24 | cat << END >${DUCKDB_SCRIPT_FILE}
25 | .open ${TPCH_SF_OUT_DUCKDB_DB}
26 | install tpch;
27 | load tpch;
28 | call dbgen(sf = ${SCALE_FACTOR});
29 | checkpoint;
30 | .databases
31 | .tables
32 | END
33 | ${DUCKDB_BUILD_DIR}/duckdb --echo < ${DUCKDB_SCRIPT_FILE}
34 | echo "TPCH_SF_OUT_DUCKDB=${TPCH_SF_OUT_DUCKDB}/db"
35 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | [](https://github.com/duckdb/duckdb-wasm/actions/workflows/main.yml)
4 | [](https://github.com/duckdb/duckdb-wasm/actions/workflows/benchmarks.yml)
5 | [](https://github.com/duckdb/duckdb)
6 | [](https://www.npmjs.com/package/@duckdb/duckdb-wasm-shell/v/latest)
7 | [](https://www.jsdelivr.com/package/npm/@duckdb/duckdb-wasm-shell)
8 |
9 | **DuckDB-Wasm Shell**
10 |
11 | This library contains an embeddable standalone web shell for **@duckdb/duckdb-wasm**. Try it out at [shell.duckdb.org](https://shell.duckdb.org).
12 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/bindings/bindings_node_eh.ts:
--------------------------------------------------------------------------------
1 | import DuckDBWasm from './duckdb-eh.js';
2 | import { DuckDBModule } from './duckdb_module';
3 | import { DuckDBNodeBindings } from './bindings_node_base.js';
4 | import { DuckDBRuntime } from './runtime';
5 | import { Logger } from '../log';
6 |
7 | /** DuckDB bindings for node.js */
8 | export class DuckDB extends DuckDBNodeBindings {
9 | /** Constructor */
10 | public constructor(
11 | logger: Logger,
12 | runtime: DuckDBRuntime,
13 | mainModulePath: string,
14 | pthreadWorkerPath: string | null = null,
15 | ) {
16 | super(logger, runtime, mainModulePath, pthreadWorkerPath);
17 | }
18 |
19 | /** Instantiate the bindings */
20 | protected instantiateImpl(moduleOverrides: Partial): Promise {
21 | return DuckDBWasm({
22 | ...moduleOverrides,
23 | instantiateWasm: this.instantiateWasm.bind(this),
24 | locateFile: this.locateFile.bind(this),
25 | });
26 | }
27 | }
28 |
29 | export default DuckDB;
30 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/bindings/bindings_node_mvp.ts:
--------------------------------------------------------------------------------
1 | import DuckDBWasm from './duckdb-mvp.js';
2 | import { DuckDBNodeBindings } from './bindings_node_base.js';
3 | import { Logger } from '../log.js';
4 | import { DuckDBModule } from './duckdb_module';
5 | import { DuckDBRuntime } from './runtime';
6 |
7 | /** DuckDB bindings for node.js */
8 | export class DuckDB extends DuckDBNodeBindings {
9 | /** Constructor */
10 | public constructor(
11 | logger: Logger,
12 | runtime: DuckDBRuntime,
13 | mainModulePath: string,
14 | pthreadWorkerPath: string | null = null,
15 | ) {
16 | super(logger, runtime, mainModulePath, pthreadWorkerPath);
17 | }
18 |
19 | /** Instantiate the bindings */
20 | protected instantiateImpl(moduleOverrides: Partial): Promise {
21 | return DuckDBWasm({
22 | ...moduleOverrides,
23 | instantiateWasm: this.instantiateWasm.bind(this),
24 | locateFile: this.locateFile.bind(this),
25 | });
26 | }
27 | }
28 |
29 | export default DuckDB;
30 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/bindings/bindings_browser_coi.ts:
--------------------------------------------------------------------------------
1 | import DuckDBWasm from './duckdb-coi.js';
2 | import { DuckDBBrowserBindings } from './bindings_browser_base';
3 | import { DuckDBModule } from './duckdb_module';
4 | import { DuckDBRuntime } from './runtime';
5 | import { Logger } from '../log';
6 |
7 | /** DuckDB bindings for the browser */
8 | export class DuckDB extends DuckDBBrowserBindings {
9 | /** Constructor */
10 | public constructor(
11 | logger: Logger,
12 | runtime: DuckDBRuntime,
13 | mainModuleURL: string,
14 | pthreadWorkerURL: string | null = null,
15 | ) {
16 | super(logger, runtime, mainModuleURL, pthreadWorkerURL);
17 | }
18 |
19 | /** Instantiate the bindings */
20 | protected instantiateImpl(moduleOverrides: Partial): Promise {
21 | return DuckDBWasm({
22 | ...moduleOverrides,
23 | instantiateWasm: this.instantiateWasm.bind(this),
24 | locateFile: this.locateFile.bind(this),
25 | });
26 | }
27 | }
28 |
29 | export default DuckDB;
30 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/bindings/bindings_browser_eh.ts:
--------------------------------------------------------------------------------
1 | import DuckDBWasm from './duckdb-eh.js';
2 | import { DuckDBBrowserBindings } from './bindings_browser_base';
3 | import { DuckDBModule } from './duckdb_module';
4 | import { DuckDBRuntime } from './runtime';
5 | import { Logger } from '../log';
6 |
7 | /** DuckDB bindings for the browser */
8 | export class DuckDB extends DuckDBBrowserBindings {
9 | /** Constructor */
10 | public constructor(
11 | logger: Logger,
12 | runtime: DuckDBRuntime,
13 | mainModuleURL: string,
14 | pthreadWorkerURL: string | null = null,
15 | ) {
16 | super(logger, runtime, mainModuleURL, pthreadWorkerURL);
17 | }
18 |
19 | /** Instantiate the bindings */
20 | protected instantiateImpl(moduleOverrides: Partial): Promise {
21 | return DuckDBWasm({
22 | ...moduleOverrides,
23 | instantiateWasm: this.instantiateWasm.bind(this),
24 | locateFile: this.locateFile.bind(this),
25 | });
26 | }
27 | }
28 |
29 | export default DuckDB;
30 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/test/table_test.ts:
--------------------------------------------------------------------------------
1 | import * as arrow from 'apache-arrow';
2 |
3 | export interface Column {
4 | name: string;
5 | values: any[];
6 | }
7 |
8 | export function compareTable(table: arrow.Table, expected: Column[]): void {
9 | // Check column count
10 | const colCount = expected.length;
11 | expect(table.numCols).toEqual(colCount);
12 | if (colCount == 0) return;
13 |
14 | // Check columns
15 | const rowCount = expected[0].values.length;
16 | for (let i = 0; i < colCount; ++i) {
17 | expect(expected[i].values.length).toEqual(rowCount);
18 | expect(table.getChildAt(i)?.length).toEqual(rowCount);
19 | expect(table.schema.fields[i]?.name).toEqual(expected[i].name);
20 | }
21 |
22 | // Compare the actual values
23 | for (let i = 0; i < colCount; ++i) {
24 | const col = table.getChildAt(i)!;
25 | const have = [];
26 | for (let j = 0; j < rowCount; ++j) {
27 | have.push(col.get(j));
28 | }
29 | expect(Number(have)).toEqual(Number(expected[i].values));
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/packages/benchmarks/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "./dist/build/",
4 | "target": "ES2020",
5 | "module": "ES2020",
6 | // TODO(ankoh): Upgrade node resolution to node12 for exports once typescript 4.6.0 is out
7 | // https://www.typescriptlang.org/docs/handbook/esm-node.html
8 | "moduleResolution": "node",
9 | "strict": true,
10 | "sourceMap": true,
11 | "noImplicitAny": true,
12 | "esModuleInterop": true,
13 | "downlevelIteration": true,
14 | "allowJs": true,
15 | "allowSyntheticDefaultImports": true,
16 | "resolveJsonModule": true,
17 |
18 | // Insanity mode due to:
19 | // https://issues.apache.org/jira/browse/ARROW-10794
20 | "skipLibCheck": true,
21 |
22 | "lib": ["ESNext.Array", "DOM", "DOM.Iterable", "es6", "webworker"],
23 | "types": ["emscripten", "node"],
24 | "baseUrl": "."
25 | },
26 | "include": ["./src/**/*.ts", "./types/**/*.ts"],
27 | "exclude": ["./node_modules/*", "../../node_modules/*"]
28 | }
29 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/bindings/insert_options.ts:
--------------------------------------------------------------------------------
1 | import * as arrow from 'apache-arrow';
2 | import { SQLField } from '../json_typedef';
3 |
4 | export enum JSONTableShape {
5 | ROW_ARRAY = 'row-array',
6 | COLUMN_OBJECT = 'column-object',
7 | }
8 |
9 | export interface JSONInsertOptions {
10 | name: string;
11 | schema?: string;
12 | create?: boolean;
13 | shape?: JSONTableShape;
14 | columns?: {
15 | [key: string]: arrow.DataType;
16 | };
17 | columnsFlat?: SQLField[];
18 | }
19 |
20 | export interface CSVInsertOptions {
21 | name: string;
22 | schema?: string;
23 | create?: boolean;
24 | header?: boolean;
25 | delimiter?: string;
26 | quote?: string;
27 | escape?: string;
28 | skip?: number;
29 | detect?: boolean;
30 | dateFormat?: string;
31 | timestampFormat?: string;
32 | columns?: {
33 | [key: string]: arrow.DataType;
34 | };
35 | columnsFlat?: SQLField[];
36 | }
37 |
38 | export interface ArrowInsertOptions {
39 | name: string;
40 | schema?: string;
41 | create?: boolean;
42 | }
43 |
--------------------------------------------------------------------------------
/lib/include/duckdb/web/functions/table_function_relation.h:
--------------------------------------------------------------------------------
1 | #include "duckdb/common/unordered_map.hpp"
2 | #include "duckdb/main/relation.hpp"
3 | #include "unordered_map"
4 |
5 | namespace duckdb {
6 | namespace web {
7 |
8 | class TableFunctionRelation : public Relation {
9 | public:
10 | TableFunctionRelation(const duckdb::shared_ptr &context, string name,
11 | vector unnamed_parameters, unordered_map named_parameters,
12 | shared_ptr input_relation_p = nullptr);
13 |
14 | string name;
15 | vector unnamed_parameters;
16 | unordered_map named_parameters;
17 | vector columns;
18 | shared_ptr input_relation;
19 |
20 | public:
21 | unique_ptr GetQueryNode() override;
22 | unique_ptr GetTableRef() override;
23 |
24 | const vector &Columns() override;
25 | string ToString(idx_t depth) override;
26 | string GetAlias() override;
27 | };
28 |
29 | } // namespace web
30 | } // namespace duckdb
31 |
--------------------------------------------------------------------------------
/lib/include/duckdb/web/utils/debug.h:
--------------------------------------------------------------------------------
1 | #ifndef INCLUDE_DUCKDB_WEB_UTILS_DEBUG_H_
2 | #define INCLUDE_DUCKDB_WEB_UTILS_DEBUG_H_
3 |
4 | #include
5 | #include
6 |
7 | #include "duckdb/web/utils/scope_guard.h"
8 |
9 | namespace duckdb {
10 | namespace web {
11 |
12 | #define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
13 |
14 | #define MANUAL_DEBUG_TRACE() \
15 | auto FILE_NAME_ = __FILENAME__; \
16 | auto FUNC_NAME_ = __FUNCTION__; \
17 | std::cout << "[ ENTER ] " << FILE_NAME_ << " " << FUNC_NAME_ << std::endl; \
18 | auto leave_func = sg::make_scope_guard( \
19 | [FILE_NAME_, FUNC_NAME_]() { std::cout << "[ EXIT ] " << FILE_NAME_ << " " << FUNC_NAME_ << std::endl; });
20 |
21 | #ifdef WITH_DEBUG_TRACE
22 | #define DEBUG_TRACE() MANUAL_DEBUG_TRACE();
23 | #else
24 | #define DEBUG_TRACE()
25 | #endif
26 |
27 | } // namespace web
28 | } // namespace duckdb
29 |
30 | #endif
31 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/src/pages/table.module.css:
--------------------------------------------------------------------------------
1 | .table_page {
2 | background-color: #333;
3 | width: 100%;
4 | height: 100%;
5 | display: flex;
6 | justify-content: center;
7 | align-items: center;
8 | }
9 |
10 | .selector_container {
11 | width: 90%;
12 | max-width: 800px;
13 | background-color: rgb(200, 200, 200);
14 | min-height: 300px;
15 | border-radius: var(--border_radius);
16 |
17 | display: grid;
18 | grid-template-rows: max-content auto;
19 | grid-template-columns: auto;
20 | }
21 |
22 | .selector_header {
23 | background-color: black;
24 | border-radius: var(--border_radius) var(--border_radius) 0 0;
25 | color: white;
26 | width: 100%;
27 | padding: 8px 12px;
28 | }
29 |
30 | .grid_container {
31 | background-color: red;
32 | min-height: 300px;
33 | }
34 |
35 | @media only screen and (min-width: 600px) {
36 | .grid_container {
37 | width: 90%;
38 | max-width: 800px;
39 | }
40 | }
41 | @media only screen and (max-width: 600px) {
42 | .grid_container {
43 | width: 100%;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/karma/s3rver/s3rver.js:
--------------------------------------------------------------------------------
1 | const S3rver = require('s3rver');
2 |
3 | const CORS_CONFIG =
4 | '\n' +
5 | ' \n' +
6 | ' *\n' +
7 | ' PUT\n' +
8 | ' GET\n' +
9 | ' HEAD\n' +
10 | ' *\n' +
11 | ' Content-Range\n' +
12 | ' \n' +
13 | '';
14 |
15 | var createS3rver = function (args, config, logger) {
16 | const log = logger.create('S3-test-server');
17 | log.info('Starting S3 test server on port ' + config.s3rver.port);
18 | let instance = new S3rver({
19 | port: config.s3rver.port,
20 | address: 'localhost',
21 | silent: config.s3rver.silent,
22 | directory: './../../.tmp/s3rver',
23 | configureBuckets: [{ name: 'test-bucket', configs: [CORS_CONFIG] }],
24 | }).run();
25 | };
26 |
27 | module.exports = {
28 | 'framework:s3rver': ['factory', createS3rver],
29 | };
30 |
--------------------------------------------------------------------------------
/lib/include/duckdb/web/utils/parking_lot.h:
--------------------------------------------------------------------------------
1 | #ifndef INCLUDE_DUCKDB_WEB_UTILS_PARKING_LOT_H_
2 | #define INCLUDE_DUCKDB_WEB_UTILS_PARKING_LOT_H_
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | namespace duckdb {
9 | namespace web {
10 |
11 | /// A parking lot.
12 | /// https://github.com/WebKit/webkit/blob/main/Source/WTF/wtf/ParkingLot.h
13 | class ParkingLot {
14 | public:
15 | /// Park a thread
16 | static void Park(const void* addr, std::function check,
17 | std::chrono::nanoseconds timeout = std::chrono::nanoseconds{0});
18 | /// Park a thread with spinning
19 | static void ParkWithSpinning(const void* addr, std::function check);
20 | /// Unpark threads
21 | static void UnparkThreads(const void* addr, bool unpark_all);
22 | /// Unpark one thread
23 | static void UnparkOne(const void* addr) { return UnparkThreads(addr, false); }
24 | /// Unpark all threads
25 | static void UnparkAll(const void* addr) { return UnparkThreads(addr, true); }
26 | };
27 |
28 | } // namespace web
29 | } // namespace duckdb
30 |
31 | #endif
32 |
--------------------------------------------------------------------------------
/patches/duckdb/fix_load_database.patch:
--------------------------------------------------------------------------------
1 | diff --git a/src/storage/storage_manager.cpp b/src/storage/storage_manager.cpp
2 | index 45d42174f1..10b3ce47b1 100644
3 | --- a/src/storage/storage_manager.cpp
4 | +++ b/src/storage/storage_manager.cpp
5 | @@ -162,9 +162,15 @@ void SingleFileStorageManager::LoadDatabase(StorageOptions storage_options) {
6 | row_group_size, STANDARD_VECTOR_SIZE);
7 | }
8 | }
9 | - // Check if the database file already exists.
10 | - // Note: a file can also exist if there was a ROLLBACK on a previous transaction creating that file.
11 | - if (!read_only && !fs.FileExists(path)) {
12 | + bool is_empty_file = true;
13 | + auto db_file_handle = fs.OpenFile(path, FileFlags::FILE_FLAGS_READ | FileFlags::FILE_FLAGS_NULL_IF_NOT_EXISTS);
14 | + if (db_file_handle && db_file_handle->GetFileSize() != 0) {
15 | + is_empty_file = false;
16 | + db_file_handle.reset();
17 | + }
18 | +
19 | + // first check if the database exists
20 | + if (!read_only && (!fs.FileExists(path) || (options.use_direct_io && is_empty_file))) {
21 | // file does not exist and we are in read-write mode
22 | // create a new file
23 |
24 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "submodules/duckdb"]
2 | path = submodules/duckdb
3 | url = https://github.com/duckdb/duckdb
4 | update = rebase
5 | [submodule "submodules/arrow"]
6 | path = submodules/arrow
7 | url = https://github.com/apache/arrow
8 | shallow = true
9 | ignore = dirty
10 | [submodule "submodules/gflags"]
11 | path = submodules/gflags
12 | url = https://github.com/gflags/gflags.git
13 | shallow = true
14 | [submodule "submodules/benchmark"]
15 | path = submodules/benchmark
16 | url = https://github.com/google/benchmark
17 | shallow = true
18 | [submodule "submodules/googletest"]
19 | path = submodules/googletest
20 | url = https://github.com/google/googletest
21 | shallow = true
22 | [submodule "submodules/spdlog"]
23 | path = submodules/spdlog
24 | url = https://github.com/gabime/spdlog
25 | shallow = true
26 | [submodule "submodules/rapidjson"]
27 | path = submodules/rapidjson
28 | url = https://github.com/Tencent/rapidjson
29 | shallow = true
30 | [submodule "submodules/tpch-dbgen"]
31 | path = submodules/tpch-dbgen
32 | url = https://github.com/gregrahn/tpch-kit.git
33 | ignore = dirty
34 | shallow = true
35 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/8-sqlite.sql:
--------------------------------------------------------------------------------
1 | select
2 | o_year,
3 | sum(
4 | case
5 | when nation = 'BRAZIL' then volume
6 | else 0
7 | end
8 | ) / sum(volume) as mkt_share
9 | from
10 | (
11 | select
12 | strftime('%Y', o_orderdate) as o_year,
13 | l_extendedprice * (1 - l_discount) as volume,
14 | n2.n_name as nation
15 | from
16 | part,
17 | supplier,
18 | lineitem,
19 | orders,
20 | customer,
21 | nation n1,
22 | nation n2,
23 | region
24 | where
25 | p_partkey = l_partkey
26 | and s_suppkey = l_suppkey
27 | and l_orderkey = o_orderkey
28 | and o_custkey = c_custkey
29 | and c_nationkey = n1.n_nationkey
30 | and n1.n_regionkey = r_regionkey
31 | and r_name = 'AMERICA'
32 | and s_nationkey = n2.n_nationkey
33 | and o_orderdate between '1995-01-01'
34 | and '1996-12-31'
35 | ) as all_nations
36 | group by
37 | o_year
38 | order by
39 | o_year;
40 |
--------------------------------------------------------------------------------
/.github/workflows/npm_tags.yml:
--------------------------------------------------------------------------------
1 | name: 'NPM tag'
2 | on:
3 | workflow_call:
4 | inputs:
5 | version:
6 | type: string
7 | tag:
8 | type: string
9 | workflow_dispatch:
10 | inputs:
11 | version:
12 | type: string
13 | tag:
14 | type: string
15 |
16 | jobs:
17 | change_tags:
18 | name: Change tags
19 | runs-on: ubuntu-latest
20 | steps:
21 | - uses: actions/checkout@v4
22 | with:
23 | submodules: 'recursive'
24 | fetch-depth: 0
25 |
26 | - uses: actions/setup-node@v4
27 | with:
28 | node-version: '18.x'
29 | registry-url: 'https://registry.npmjs.org'
30 |
31 | - name: Change tags
32 | env:
33 | TAG: ${{ inputs.tag }}
34 | VERSION: ${{ inputs.version }}
35 | run: |
36 | npm dist-tag ls @duckdb/duckdb-wasm@"${VERSION}"
37 | npm dist-tag add @duckdb/duckdb-wasm@"${VERSION}" "${TAG}"
38 | npm dist-tag ls @duckdb/duckdb-wasm@"${VERSION}"
39 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/targets/duckdb-browser-blocking.ts:
--------------------------------------------------------------------------------
1 | export * from '../bindings';
2 | export * from '../log';
3 | export * from '../platform';
4 | export * from '../status';
5 | export * from '../version';
6 | export { DuckDBDataProtocol } from '../bindings/runtime';
7 | export { DEFAULT_RUNTIME } from '../bindings/runtime';
8 | export { BROWSER_RUNTIME } from '../bindings/runtime_browser';
9 |
10 | import { Logger } from '../log';
11 | import { DuckDBRuntime, DuckDBBindings } from '../bindings';
12 | import { DuckDBBundles, getPlatformFeatures } from '../platform';
13 | import { DuckDB as DuckDBMVP } from '../bindings/bindings_browser_mvp';
14 | import { DuckDB as DuckDBNext } from '../bindings/bindings_browser_eh';
15 |
16 | export async function createDuckDB(
17 | bundles: DuckDBBundles,
18 | logger: Logger,
19 | runtime: DuckDBRuntime,
20 | ): Promise {
21 | const platform = await getPlatformFeatures();
22 | if (platform.wasmExceptions) {
23 | if (bundles.eh) {
24 | return new DuckDBNext(logger, runtime, bundles.eh!.mainModule);
25 | }
26 | }
27 | return new DuckDBMVP(logger, runtime, bundles.mvp.mainModule);
28 | }
29 |
--------------------------------------------------------------------------------
/scripts/generate_tpch_tbl.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -euo pipefail
4 |
5 | trap exit SIGINT
6 |
7 | PROJECT_ROOT="$(cd $(dirname "$BASH_SOURCE[0]") && cd .. && pwd)" &> /dev/null
8 | TPCH_DBGEN_DIR="${PROJECT_ROOT}/submodules/tpch-dbgen/dbgen"
9 | TPCH_DBGEN=${TPCH_DBGEN_DIR}/dbgen
10 | SCALE_FACTOR=${1:-0.01}
11 | SCALE_FACTOR_DIR=${SCALE_FACTOR/./_}
12 | TPCH_DIR=${PROJECT_ROOT}/data/tpch
13 | TPCH_SF_OUT=${TPCH_DIR}/${SCALE_FACTOR_DIR}
14 | TPCH_SF_OUT_TBL=${TPCH_SF_OUT}/tbl
15 |
16 | echo "SCALE_FACTOR=${SCALE_FACTOR}"
17 |
18 | if [ ! -f ${TPCH_DBGEN} ]; then
19 | cd ${TPCH_DBGEN_DIR}
20 | case "$(uname)" in
21 | 'Linux');;
22 | 'Darwin')
23 | echo "Patch Makefile"
24 | sed -i '.bak' -e "s/LINUX/MACOS/g" ./Makefile
25 | ;;
26 | esac
27 | make -C ${TPCH_DBGEN_DIR} dbgen
28 | fi
29 | chmod +x ${TPCH_DBGEN}
30 | echo "TPCH_DBGEN=${TPCH_DBGEN}"
31 |
32 | mkdir -p ${TPCH_SF_OUT_TBL}
33 | TBL_COUNT=$(find ${TPCH_SF_OUT_TBL} -name "*.tbl" | wc -l)
34 | if [[ ${TBL_COUNT} -ne 8 ]]; then
35 | cd ${TPCH_DBGEN_DIR}
36 | DSS_PATH=${TPCH_SF_OUT_TBL} ./dbgen -vf -s ${SCALE_FACTOR}
37 | fi
38 | echo "TPCH_SF_OUT_TBL=${TPCH_SF_OUT_TBL}"
39 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/19.sql:
--------------------------------------------------------------------------------
1 | select
2 | sum(l_extendedprice * (1 - l_discount)) as revenue
3 | from
4 | lineitem,
5 | part
6 | where
7 | (
8 | p_partkey = l_partkey
9 | and p_brand = 'Brand#12'
10 | and p_container in ('SM CASE', 'SM BOX', 'SM PACK', 'SM PKG')
11 | and l_quantity >= 1
12 | and l_quantity <= 1 + 10
13 | and p_size between 1
14 | and 5
15 | and l_shipmode in ('AIR', 'AIR REG')
16 | and l_shipinstruct = 'DELIVER IN PERSON'
17 | )
18 | or (
19 | p_partkey = l_partkey
20 | and p_brand = 'Brand#23'
21 | and p_container in ('MED BAG', 'MED BOX', 'MED PKG', 'MED PACK')
22 | and l_quantity >= 10
23 | and l_quantity <= 10 + 10
24 | and p_size between 1
25 | and 10
26 | and l_shipmode in ('AIR', 'AIR REG')
27 | and l_shipinstruct = 'DELIVER IN PERSON'
28 | )
29 | or (
30 | p_partkey = l_partkey
31 | and p_brand = 'Brand#34'
32 | and p_container in ('LG CASE', 'LG BOX', 'LG PACK', 'LG PKG')
33 | and l_quantity >= 20
34 | and l_quantity <= 20 + 10
35 | and p_size between 1
36 | and 15
37 | and l_shipmode in ('AIR', 'AIR REG')
38 | and l_shipinstruct = 'DELIVER IN PERSON'
39 | );
40 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/targets/duckdb-node-blocking.ts:
--------------------------------------------------------------------------------
1 | export * from '../bindings';
2 | export * from '../log';
3 | export * from '../platform';
4 | export * from '../status';
5 | export * from '../version';
6 | export { DuckDBDataProtocol } from '../bindings/runtime';
7 | export { DEFAULT_RUNTIME } from '../bindings/runtime';
8 | export { NODE_RUNTIME } from '../bindings/runtime_node';
9 |
10 | import { Logger } from '../log';
11 | import { DuckDBRuntime } from '../bindings';
12 | import { DuckDBNodeBindings } from '../bindings/bindings_node_base';
13 | import { DuckDBBundles, getPlatformFeatures } from '../platform';
14 | import { DuckDB as DuckDBMVP } from '../bindings/bindings_node_mvp';
15 | import { DuckDB as DuckDBNext } from '../bindings/bindings_node_eh';
16 |
17 | export async function createDuckDB(
18 | bundles: DuckDBBundles,
19 | logger: Logger,
20 | runtime: DuckDBRuntime,
21 | ): Promise {
22 | const platform = await getPlatformFeatures();
23 | if (platform.wasmExceptions) {
24 | if (bundles.eh) {
25 | return new DuckDBNext(logger, runtime, bundles.eh!.mainModule);
26 | }
27 | }
28 | return new DuckDBMVP(logger, runtime, bundles.mvp.mainModule);
29 | }
30 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/8.sql:
--------------------------------------------------------------------------------
1 | select
2 | o_year,
3 | sum(
4 | case
5 | when nation = 'BRAZIL' then volume
6 | else 0
7 | end
8 | ) / sum(volume) as mkt_share
9 | from
10 | (
11 | select
12 | extract(
13 | year
14 | from
15 | o_orderdate
16 | ) as o_year,
17 | l_extendedprice * (1 - l_discount) as volume,
18 | n2.n_name as nation
19 | from
20 | part,
21 | supplier,
22 | lineitem,
23 | orders,
24 | customer,
25 | nation n1,
26 | nation n2,
27 | region
28 | where
29 | p_partkey = l_partkey
30 | and s_suppkey = l_suppkey
31 | and l_orderkey = o_orderkey
32 | and o_custkey = c_custkey
33 | and c_nationkey = n1.n_nationkey
34 | and n1.n_regionkey = r_regionkey
35 | and r_name = 'AMERICA'
36 | and s_nationkey = n2.n_nationkey
37 | and o_orderdate between '1995-01-01'
38 | and '1996-12-31'
39 | ) as all_nations
40 | group by
41 | o_year
42 | order by
43 | o_year;
44 |
--------------------------------------------------------------------------------
/packages/benchmarks/src/suite_system_tpch_arquero.ts:
--------------------------------------------------------------------------------
1 | import { writeReport } from './setup';
2 | import { SystemBenchmarkContext, SystemBenchmark, ArqueroTPCHBenchmark } from './system';
3 | import { runSystemBenchmarks } from './suite';
4 | import * as path from 'path';
5 |
6 | async function main() {
7 | const args = process.argv.slice(2);
8 | if (args.length < 1) {
9 | console.error('usage: node suite-system-tpch.js ');
10 | process.exit(-1);
11 | }
12 | const sf = parseFloat(args[0]);
13 | console.log(`Scale Factor ${sf}`);
14 |
15 | const baseDir = path.resolve(__dirname, '../../../');
16 | const benchmarks: SystemBenchmark[] = [];
17 | for (let i = 1; i <= 22; ++i) {
18 | if (sf >= 0.1 && (i == 9 || i == 21)) {
19 | continue;
20 | }
21 | benchmarks.push(new ArqueroTPCHBenchmark(sf, i));
22 | }
23 | const ctx: SystemBenchmarkContext = {
24 | projectRootPath: baseDir,
25 | seed: Math.random(),
26 | };
27 | const results = await runSystemBenchmarks(ctx, benchmarks);
28 | console.log(results);
29 | await writeReport(results, `./benchmark_system_tpch_${sf.toString().replace('.', '')}_arquero.json`);
30 | }
31 |
32 | main();
33 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/test/long_queries.test.ts:
--------------------------------------------------------------------------------
1 | import * as duckdb from '../src';
2 |
3 | // https://github.com/duckdb/duckdb-wasm/issues/393
4 | export function longQueries(db: () => duckdb.AsyncDuckDB): void {
5 | let conn: duckdb.AsyncDuckDBConnection | null = null;
6 | beforeEach(async () => {
7 | await db().flushFiles();
8 | });
9 | afterEach(async () => {
10 | if (conn) {
11 | await conn.close();
12 | conn = null;
13 | }
14 | await db().flushFiles();
15 | await db().dropFiles();
16 | });
17 | describe('Very long queries', () => {
18 | it('1e6', async () => {
19 | await db().open({
20 | path: ':memory:',
21 | query: {
22 | castTimestampToDate: false,
23 | },
24 | });
25 | conn = await db().connect();
26 |
27 | let str = `with big_expr as ( select `;
28 | let i = 1;
29 | while (str.length < 1e6) {
30 | str += ` ` + i + ` as col_` + i + `,`;
31 | i++;
32 | }
33 | str += ` NULL as col_NULL) select 99;`;
34 |
35 | await conn.query(str);
36 | });
37 | });
38 | }
39 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/test/regression/github_1467.test.ts:
--------------------------------------------------------------------------------
1 | import * as duckdb from '../../src';
2 |
3 | // https://github.com/duckdb/duckdb-wasm/issues/477
4 | // Note that when ArrowJS supports negative decimals, castDecimalToDouble should probably be deprecated.
5 | export function test1467(db: () => duckdb.AsyncDuckDB): void {
6 | let conn: duckdb.AsyncDuckDBConnection | null = null;
7 | beforeEach(async () => {
8 | await db().flushFiles();
9 | });
10 | afterEach(async () => {
11 | if (conn) {
12 | await conn.close();
13 | conn = null;
14 | }
15 | await db().flushFiles();
16 | await db().dropFiles();
17 | });
18 | describe('GitHub issues', () => {
19 | it('1467', async () => {
20 | // Baseline without cast: we expect decimal values to not handle fractional parts correctly
21 | await db().open({
22 | path: ':memory:',
23 | query: {},
24 | });
25 | conn = await db().connect();
26 | const resultWithoutCast = await conn.query(`select substring('🦆🦆🦆' from 3) AS result;`);
27 | expect(resultWithoutCast.toArray()[0]?.result).toEqual('🦆');
28 | });
29 | });
30 | }
31 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/coverage.mjs:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 | import path from 'path';
3 | import mkdir from 'make-dir';
4 | import rimraf from 'rimraf';
5 | import { spawnSync } from 'child_process';
6 | import { fileURLToPath } from 'url';
7 |
8 | const __dirname = path.dirname(fileURLToPath(import.meta.url));
9 |
10 | const cov = path.resolve(__dirname, 'coverage');
11 | const cov_chrome = path.resolve(cov, 'chrome', 'coverage-final.json');
12 | //const cov_firefox = path.resolve(cov, 'firefox', 'coverage-final.json');
13 | const cov_node = path.resolve(cov, 'node', 'coverage-final.json');
14 | const cov_all = path.resolve(cov, 'all');
15 | const cov_out = path.resolve(cov, 'coverage.json');
16 | const nyc = '../../node_modules/nyc/bin/nyc.js';
17 |
18 | rimraf.sync(cov_all);
19 | mkdir.sync(cov_all);
20 | fs.copyFileSync(cov_chrome, path.resolve(cov_all, 'chrome.json'));
21 | //fs.copyFileSync(cov_firefox, path.resolve(cov_all, 'firefox.json'));
22 | fs.copyFileSync(cov_node, path.resolve(cov_all, 'node.json'));
23 |
24 | const out = spawnSync(nyc, ['merge', cov_all, cov_out], {
25 | encoding: 'utf8',
26 | shell: true,
27 | cov,
28 | });
29 | console.log(out.stdout);
30 | if (out.status !== 0) {
31 | console.error(out.stderr);
32 | process.exit(out.status);
33 | }
34 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/test/tokenizer.test.ts:
--------------------------------------------------------------------------------
1 | import * as duckdb from '../src/';
2 |
3 | export function testTokenization(db: () => duckdb.DuckDBBindings): void {
4 | describe('Tokenizer', () => {
5 | it('SELECT 1', async () => {
6 | expect(db().tokenize('SELECT 1')).toEqual({
7 | offsets: [0, 7],
8 | types: [4, 1],
9 | });
10 | });
11 | it('SELECT * FROM region', async () => {
12 | expect(db().tokenize('SELECT * FROM region')).toEqual({
13 | offsets: [0, 7, 9, 14],
14 | types: [4, 3, 4, 0],
15 | });
16 | });
17 | });
18 | }
19 |
20 | export function testTokenizationAsync(db: () => duckdb.AsyncDuckDB): void {
21 | describe('Tokenizer', () => {
22 | it('SELECT 1', async () => {
23 | expect(await db().tokenize('SELECT 1')).toEqual({
24 | offsets: [0, 7],
25 | types: [4, 1],
26 | });
27 | });
28 | it('SELECT * FROM region', async () => {
29 | expect(await db().tokenize('SELECT * FROM region')).toEqual({
30 | offsets: [0, 7, 9, 14],
31 | types: [4, 3, 4, 0],
32 | });
33 | });
34 | });
35 | }
36 |
--------------------------------------------------------------------------------
/packages/benchmarks/src/suite_system_sum_csv.ts:
--------------------------------------------------------------------------------
1 | import { setupDuckDBSync, writeReport } from './setup';
2 | import { ArqueroCSVSumBenchmark, DuckDBSyncCSVSumBenchmark, SystemBenchmark, SystemBenchmarkContext } from './system';
3 | import { runSystemBenchmarks } from './suite';
4 | import * as path from 'path';
5 |
6 | async function main() {
7 | const baseDir = path.resolve(__dirname, '../../../');
8 | const duckdbSync = await setupDuckDBSync();
9 | const suite: SystemBenchmark[] = [
10 | new ArqueroCSVSumBenchmark(1000, 10),
11 | new ArqueroCSVSumBenchmark(10000, 100),
12 | new ArqueroCSVSumBenchmark(100000, 1000),
13 | new ArqueroCSVSumBenchmark(1000000, 10000),
14 | new DuckDBSyncCSVSumBenchmark(duckdbSync, 1000, 10),
15 | new DuckDBSyncCSVSumBenchmark(duckdbSync, 10000, 100),
16 | new DuckDBSyncCSVSumBenchmark(duckdbSync, 100000, 1000),
17 | new DuckDBSyncCSVSumBenchmark(duckdbSync, 1000000, 10000),
18 | ];
19 | const ctx: SystemBenchmarkContext = {
20 | projectRootPath: baseDir,
21 | seed: Math.random(),
22 | };
23 | const results = await runSystemBenchmarks(ctx, suite);
24 | console.log(results);
25 | await writeReport(results, './benchmark_system_sum_csv.json');
26 | }
27 |
28 | main();
29 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/crate/src/xterm/addons/attach.rs:
--------------------------------------------------------------------------------
1 | use crate::xterm::{Terminal, TerminalAddon};
2 | use wasm_bindgen::prelude::*;
3 | use wasm_bindgen::JsCast;
4 | use web_sys::WebSocket;
5 |
6 | #[wasm_bindgen(module = "xterm-addon-attach")]
7 | extern "C" {
8 |
9 | #[wasm_bindgen(js_name = "IAttachOptions")]
10 | pub type AttachOptions;
11 |
12 | #[wasm_bindgen(method, setter, js_name = "bidirectional")]
13 | fn set_bidirectional(this: &AttachOptions, val: bool);
14 |
15 | // ========================================================================
16 |
17 | #[wasm_bindgen(extends = TerminalAddon)]
18 | pub type AttachAddon;
19 |
20 | #[wasm_bindgen(constructor)]
21 | pub fn new(socket: WebSocket, options: Option) -> AttachAddon;
22 |
23 | #[wasm_bindgen(method, method, js_name = "activate")]
24 | pub fn activate(this: &AttachOptions, terminal: Terminal);
25 |
26 | #[wasm_bindgen(method, method, js_name = "dispose")]
27 | pub fn dispose(this: &AttachOptions);
28 | }
29 |
30 | impl AttachOptions {
31 | pub fn new() -> Self {
32 | js_sys::Object::new().unchecked_into()
33 | }
34 |
35 | pub fn with_bidirectional(&self, val: bool) -> &Self {
36 | self.set_bidirectional(val);
37 | self
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/examples/esbuild-node/index.mjs:
--------------------------------------------------------------------------------
1 | import * as duckdb from "@duckdb/duckdb-wasm";
2 | import path from "path";
3 | import Worker from "web-worker";
4 | import { createRequire } from "module";
5 | const require2 = createRequire(import.meta.url);
6 | const DUCKDB_DIST = path.dirname(require2.resolve("@duckdb/duckdb-wasm"));
7 | (async () => {
8 | try {
9 | const DUCKDB_CONFIG = await duckdb.selectBundle({
10 | mvp: {
11 | mainModule: path.resolve(DUCKDB_DIST, "./duckdb-mvp.wasm"),
12 | mainWorker: path.resolve(DUCKDB_DIST, "./duckdb-node-mvp.worker.cjs")
13 | },
14 | eh: {
15 | mainModule: path.resolve(DUCKDB_DIST, "./duckdb-eh.wasm"),
16 | mainWorker: path.resolve(DUCKDB_DIST, "./duckdb-node-eh.worker.cjs")
17 | }
18 | });
19 | const logger = new duckdb.ConsoleLogger();
20 | const worker = new Worker(DUCKDB_CONFIG.mainWorker);
21 | const db = new duckdb.AsyncDuckDB(logger, worker);
22 | await db.instantiate(DUCKDB_CONFIG.mainModule, DUCKDB_CONFIG.pthreadWorker);
23 | const conn = await db.connect();
24 | await conn.query(`SELECT count(*)::INTEGER as v FROM generate_series(0, 100) t(v)`);
25 | await conn.close();
26 | await db.terminate();
27 | await worker.terminate();
28 | } catch (e) {
29 | console.error(e);
30 | }
31 | })();
32 |
--------------------------------------------------------------------------------
/lib/include/duckdb/web/json_typedef.h:
--------------------------------------------------------------------------------
1 | #ifndef INCLUDE_DUCKDB_WEB_JSON_TYPEDEF_H_
2 | #define INCLUDE_DUCKDB_WEB_JSON_TYPEDEF_H_
3 |
4 | #include
5 | #include
6 |
7 | #include "arrow/type.h"
8 | #include "arrow/type_fwd.h"
9 | #include "duckdb/web/json_analyzer.h"
10 | #include "duckdb/web/json_parser.h"
11 | #include "rapidjson/document.h"
12 |
13 | namespace duckdb {
14 | namespace web {
15 | namespace json {
16 |
17 | /// Read a type
18 | arrow::Result> SQLToArrowType(const rapidjson::Value::ConstObject& obj);
19 | /// Read field from a json object
20 | arrow::Result> SQLToArrowField(const rapidjson::Value& obj);
21 | /// Read fields from a json array
22 | arrow::Result>> SQLToArrowFields(const rapidjson::Value::ConstArray& fields);
23 | /// Serialize a SQL type as string
24 | arrow::Result WriteSQLType(rapidjson::Document& doc, const duckdb::LogicalType& type);
25 | /// Serialize a SQL type as string
26 | arrow::Result WriteSQLField(rapidjson::Document& doc, std::string_view name,
27 | const duckdb::LogicalType& type, bool nullable);
28 |
29 | } // namespace json
30 | } // namespace web
31 | } // namespace duckdb
32 |
33 | #endif
34 |
--------------------------------------------------------------------------------
/scripts/sync_versions.mjs:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2020 The DashQL Authors
2 |
3 | import fs from 'fs';
4 |
5 | const pkgPaths = [
6 | './packages/duckdb-wasm-app/package.json',
7 | './packages/duckdb-wasm-shell/package.json',
8 | './packages/duckdb-wasm/package.json',
9 | './packages/react-duckdb/package.json',
10 | './packages/benchmarks/package.json',
11 | './examples/esbuild-browser/package.json',
12 | './examples/esbuild-node/package.json',
13 | './examples/bare-node/package.json',
14 | './examples/bare-browser/package.json',
15 | ];
16 | const pkgs = [];
17 |
18 | // Read all packages
19 | for (const pkgPath of pkgPaths) {
20 | const j = JSON.parse(fs.readFileSync(pkgPath));
21 | console.log(`${j.name}:${j.version}`);
22 | pkgs.push({
23 | path: pkgPath,
24 | name: j.name,
25 | version: j.version,
26 | config: j,
27 | });
28 | }
29 |
30 | // Do a naive n*n sync
31 | for (const pkg of pkgs) {
32 | for (const otherPkg of pkgs) {
33 | if (pkg.name == otherPkg.name) continue;
34 | if (pkg.config.dependencies && pkg.config.dependencies[otherPkg.name] !== undefined) {
35 | pkg.config.dependencies[otherPkg.name] = `^${otherPkg.config.version}`;
36 | }
37 | }
38 | fs.writeFileSync(pkg.path, JSON.stringify(pkg.config, null, 4) + '\n');
39 | }
40 |
--------------------------------------------------------------------------------
/examples/bare-node/index.cjs:
--------------------------------------------------------------------------------
1 | const duckdb = require('@duckdb/duckdb-wasm');
2 | const path = require('path');
3 | const Worker = require('web-worker');
4 | const DUCKDB_DIST = path.dirname(require.resolve('@duckdb/duckdb-wasm'));
5 |
6 | (async () => {
7 | try {
8 | const DUCKDB_CONFIG = await duckdb.selectBundle({
9 | mvp: {
10 | mainModule: path.resolve(DUCKDB_DIST, './duckdb-mvp.wasm'),
11 | mainWorker: path.resolve(DUCKDB_DIST, './duckdb-node-mvp.worker.cjs'),
12 | },
13 | eh: {
14 | mainModule: path.resolve(DUCKDB_DIST, './duckdb-eh.wasm'),
15 | mainWorker: path.resolve(DUCKDB_DIST, './duckdb-node-eh.worker.cjs'),
16 | },
17 | });
18 |
19 | const logger = new duckdb.ConsoleLogger();
20 | const worker = new Worker(DUCKDB_CONFIG.mainWorker);
21 | const db = new duckdb.AsyncDuckDB(logger, worker);
22 | await db.instantiate(DUCKDB_CONFIG.mainModule, DUCKDB_CONFIG.pthreadWorker);
23 |
24 | const conn = await db.connect();
25 | await conn.query(`SELECT count(*)::INTEGER as v FROM generate_series(0, 100) t(v)`);
26 |
27 | await conn.close();
28 | await db.terminate();
29 | await worker.terminate();
30 | } catch (e) {
31 | console.error(e);
32 | }
33 | })();
34 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/7-sqlite.sql:
--------------------------------------------------------------------------------
1 | select
2 | supp_nation,
3 | cust_nation,
4 | l_year,
5 | sum(volume) as revenue
6 | from
7 | (
8 | select
9 | n1.n_name as supp_nation,
10 | n2.n_name as cust_nation,
11 | strftime('%Y', l_shipdate) as l_year,
12 | l_extendedprice * (1 - l_discount) as volume
13 | from
14 | supplier,
15 | lineitem,
16 | orders,
17 | customer,
18 | nation n1,
19 | nation n2
20 | where
21 | s_suppkey = l_suppkey
22 | and o_orderkey = l_orderkey
23 | and c_custkey = o_custkey
24 | and s_nationkey = n1.n_nationkey
25 | and c_nationkey = n2.n_nationkey
26 | and (
27 | (
28 | n1.n_name = 'FRANCE'
29 | and n2.n_name = 'GERMANY'
30 | )
31 | or (
32 | n1.n_name = 'GERMANY'
33 | and n2.n_name = 'FRANCE'
34 | )
35 | )
36 | and l_shipdate between '1995-01-01'
37 | and '1996-12-31'
38 | ) as shipping
39 | group by
40 | supp_nation,
41 | cust_nation,
42 | l_year
43 | order by
44 | supp_nation,
45 | cust_nation,
46 | l_year;
47 |
--------------------------------------------------------------------------------
/lib/cmake/gflags.cmake:
--------------------------------------------------------------------------------
1 | include(ExternalProject)
2 | find_package(Git REQUIRED)
3 |
4 | # Get gflags
5 | ExternalProject_Add(
6 | gflags_src
7 | SOURCE_DIR "${CMAKE_SOURCE_DIR}/../submodules/gflags"
8 | PREFIX "${CMAKE_BINARY_DIR}/third_party/gflags"
9 | INSTALL_DIR "${CMAKE_BINARY_DIR}/third_party/gflags/install"
10 | CMAKE_ARGS
11 | -G${CMAKE_GENERATOR}
12 | -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/third_party/gflags/install
13 | -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
14 | -DCMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER}
15 | -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
16 | -DCMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER}
17 | -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
18 | DOWNLOAD_COMMAND ""
19 | UPDATE_COMMAND ""
20 | BUILD_BYPRODUCTS /lib/libgflags.a)
21 |
22 | # Prepare gflags
23 | ExternalProject_Get_Property(gflags_src install_dir)
24 | set(GFLAGS_INCLUDE_DIR ${install_dir}/include)
25 | set(GFLAGS_LIBRARY_PATH ${install_dir}/lib/libgflags.a)
26 | file(MAKE_DIRECTORY ${GFLAGS_INCLUDE_DIR})
27 | add_library(gflags STATIC IMPORTED)
28 | set_property(TARGET gflags PROPERTY IMPORTED_LOCATION ${GFLAGS_LIBRARY_PATH})
29 | set_property(
30 | TARGET gflags
31 | APPEND
32 | PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${GFLAGS_INCLUDE_DIR})
33 |
34 | # Dependencies
35 | add_dependencies(gflags gflags_src)
36 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/crate/src/comfy/style/column.rs:
--------------------------------------------------------------------------------
1 | /// Constraints can be added to [columns](crate::Column).
2 | ///
3 | /// They allow some control over the dynamic content arrangement process.
4 | #[derive(Copy, Clone, Debug, PartialEq)]
5 | pub enum ColumnConstraint {
6 | /// This will completely hide a column.
7 | Hidden,
8 | /// Force the column to be as long as it's content.
9 | /// Use with caution! This can easily break your table, if the column's content is overly long.
10 | ContentWidth,
11 | /// Enforce a fix width for a column.
12 | Width(u16),
13 | /// Specify a min amount of characters per line for a column.
14 | MinWidth(u16),
15 | /// Specify a max amount of allowed characters per line for a column.
16 | MaxWidth(u16),
17 | /// Set a fixed percentage in respect to table_width for this column.
18 | /// **Warning:** This option will be ignored, if the width cannot be determined!
19 | Percentage(u16),
20 | /// Set a a minimum percentage in respect to table_width for this column.
21 | /// **Warning:** This option will be ignored, if the width cannot be determined!
22 | MinPercentage(u16),
23 | /// Set a a maximum percentage in respect to table_width for this column.
24 | /// **Warning:** This option will be ignored, if the width cannot be determined!
25 | MaxPercentage(u16),
26 | }
27 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/src/utils/format.ts:
--------------------------------------------------------------------------------
1 | export enum ByteFormat {
2 | SI = 0,
3 | IEC = 1,
4 | }
5 |
6 | export function formatBytes(value: number, format: ByteFormat = ByteFormat.SI): string {
7 | const [multiple, k, suffix] = format === ByteFormat.SI ? [1000, 'k', 'B'] : [1024, 'K', 'iB'];
8 | const exp = (Math.log(value) / Math.log(multiple)) | 0;
9 | const size = Number((value / Math.pow(multiple, exp)).toFixed(2));
10 | return `${size} ${exp ? `${k}MGTPEZY`[exp - 1] + suffix : `byte${size !== 1 ? 's' : ''}`}`;
11 | }
12 |
13 | export function formatThousands(value: number): string {
14 | const [multiple, k] = [1000, 'k'];
15 | const exp = (Math.log(value) / Math.log(multiple)) | 0;
16 | const size = Number((value / Math.pow(multiple, exp)).toFixed(2));
17 | return size + (exp ? ` ${`${k}MGTPEZY`[exp - 1]}` : '');
18 | }
19 |
20 | export function formatMs(value: number): string {
21 | const MS_SECONDS = 1000;
22 | const MS_MINUTES = MS_SECONDS * 60;
23 | if (value >= MS_MINUTES) {
24 | return `${Math.floor(value / MS_MINUTES)}:${Math.floor((value % MS_MINUTES) / MS_SECONDS)}.${(
25 | value % MS_SECONDS
26 | )
27 | .toString()
28 | .padStart(4, '0')}`;
29 | }
30 | return `${Math.floor(value / MS_SECONDS)}.${(value % MS_SECONDS).toFixed(0).padStart(3, '0')}`;
31 | }
32 |
--------------------------------------------------------------------------------
/actions/runner/cloud-init.yaml:
--------------------------------------------------------------------------------
1 | #cloud-config
2 |
3 | package_upgrade: true
4 |
5 | packages:
6 | - apt-transport-https
7 | - ca-certificates
8 | - gnupg-agent
9 | - software-properties-common
10 | - git
11 | - curl
12 | - jq
13 |
14 | groups:
15 | - docker
16 |
17 | users:
18 | - name: actions
19 | groups: docker
20 | homedir: /home/actions
21 | lock_passwd: true
22 | sudo: False
23 |
24 | runcmd:
25 | # Install docker
26 | - curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
27 | - add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
28 | - apt-get update -y
29 | - apt-get install -y docker-ce docker-ce-cli containerd.io
30 | - systemctl start docker
31 | - systemctl enable docker
32 |
33 | # Install actions
34 | - cd /home/actions
35 | - mkdir runner
36 | - cd ./runner
37 | - curl -o runner.tgz -L https://github.com/actions/runner/releases/download/v2.278.0/actions-runner-linux-x64-2.278.0.tar.gz
38 | - tar -xzf ./runner.tgz
39 | - chown -R actions:actions .
40 | - ./installdependencies.sh
41 | - rm ./runner.tgz
42 |
43 | # Cache directories
44 | - mkdir -p /home/actions/.emscripten_cache /home/actions/.yarn_cache /home/actions/.ccache
45 | - chown -R actions:actions /home/actions/.emscripten_cache /home/actions/.yarn_cache /home/actions/.ccache
46 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/test/regression/github_1833.test.ts:
--------------------------------------------------------------------------------
1 | import * as duckdb from '../../src';
2 |
3 | // https://github.com/duckdb/duckdb-wasm/issues/1833
4 | export function test1833(db: () => duckdb.AsyncDuckDB): void {
5 | let conn: duckdb.AsyncDuckDBConnection;
6 | beforeEach(async () => {
7 | await db().flushFiles();
8 | conn = await db().connect();
9 | });
10 | afterEach(async () => {
11 | await conn.close();
12 | await db().flushFiles();
13 | await db().dropFiles();
14 | });
15 | describe('GitHub issues', () => {
16 | it('1833', async () => {
17 | await conn.query(`
18 | CREATE TABLE "Test" (value VARCHAR)
19 | `);
20 | const stmt = await conn.prepare(`
21 | INSERT INTO "Test" (value)
22 | VALUES (?)
23 | `);
24 | await stmt.query('🦆🦆🦆🦆🦆');
25 | await stmt.query('goo␀se');
26 | await stmt.query('goo\u0000se');
27 | const result = await conn.query(`
28 | SELECT * FROM "Test"
29 | `);
30 | expect(result.schema.fields.length).toBe(1);
31 | expect(result.schema.fields[0].name).toBe('value');
32 | expect(result.toArray().length).toEqual(3);
33 | expect(result.toArray()[2].value.length).toEqual(6);
34 | });
35 | });
36 | }
37 |
--------------------------------------------------------------------------------
/scripts/generate_benchmark_data.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -euo pipefail
4 |
5 | PROJECT_ROOT="$(cd $(dirname "$BASH_SOURCE[0]") && cd .. && pwd)" &> /dev/null
6 | cd ${PROJECT_ROOT}
7 |
8 | # Raw CSVs
9 | ${PROJECT_ROOT}/scripts/generate_tpch_tbl.sh 0.01
10 | ${PROJECT_ROOT}/scripts/generate_tpch_tbl.sh 0.1
11 | ${PROJECT_ROOT}/scripts/generate_tpch_tbl.sh 0.25
12 | ${PROJECT_ROOT}/scripts/generate_tpch_tbl.sh 0.5
13 | ${PROJECT_ROOT}/scripts/generate_tpch_tbl.sh 1
14 |
15 | # Arrow & Parquet
16 | ${PROJECT_ROOT}/scripts/generate_tpch_arrow.sh 0.01
17 | ${PROJECT_ROOT}/scripts/generate_tpch_arrow.sh 0.1
18 | ${PROJECT_ROOT}/scripts/generate_tpch_arrow.sh 0.25
19 | ${PROJECT_ROOT}/scripts/generate_tpch_arrow.sh 0.5
20 | ${PROJECT_ROOT}/scripts/generate_tpch_arrow.sh 1
21 |
22 | # SQLite databases
23 | ${PROJECT_ROOT}/scripts/generate_tpch_sqlite.sh 0.01
24 | ${PROJECT_ROOT}/scripts/generate_tpch_sqlite.sh 0.1
25 | ${PROJECT_ROOT}/scripts/generate_tpch_sqlite.sh 0.25
26 | ${PROJECT_ROOT}/scripts/generate_tpch_sqlite.sh 0.5
27 | ${PROJECT_ROOT}/scripts/generate_tpch_sqlite.sh 1
28 |
29 | # DuckDB databases
30 | ${PROJECT_ROOT}/scripts/generate_tpch_duckdb.sh 0.01
31 | ${PROJECT_ROOT}/scripts/generate_tpch_duckdb.sh 0.1
32 | ${PROJECT_ROOT}/scripts/generate_tpch_duckdb.sh 0.25
33 | ${PROJECT_ROOT}/scripts/generate_tpch_duckdb.sh 0.5
34 | ${PROJECT_ROOT}/scripts/generate_tpch_duckdb.sh 1
35 |
--------------------------------------------------------------------------------
/packages/benchmarks/src/suite_system_tpch_duckdb.ts:
--------------------------------------------------------------------------------
1 | import { writeReport, setupDuckDBSync } from './setup';
2 | import { SystemBenchmarkContext, SystemBenchmark, DuckDBSyncLoadedTPCHBenchmark } from './system';
3 | import { runSystemBenchmarks } from './suite';
4 | import * as path from 'path';
5 |
6 | async function main() {
7 | const args = process.argv.slice(2);
8 | if (args.length < 1) {
9 | console.error('usage: node suite-system-tpch.js ');
10 | process.exit(-1);
11 | }
12 | const sf = parseFloat(args[0]);
13 | console.log(`Scale Factor ${sf}`);
14 |
15 | const baseDir = path.resolve(__dirname, '../../../');
16 | const duckdbSync = await setupDuckDBSync();
17 | const benchmarks: SystemBenchmark[] = [];
18 | for (let i = 1; i <= 22; ++i) {
19 | benchmarks.push(new DuckDBSyncLoadedTPCHBenchmark(duckdbSync, sf, i));
20 | }
21 | const ctx: SystemBenchmarkContext = {
22 | projectRootPath: baseDir,
23 | seed: Math.random(),
24 | };
25 | await DuckDBSyncLoadedTPCHBenchmark.beforeGroup(duckdbSync, ctx, sf);
26 | const results = await runSystemBenchmarks(ctx, benchmarks);
27 | await DuckDBSyncLoadedTPCHBenchmark.afterGroup(duckdbSync);
28 |
29 | console.log(results);
30 | await writeReport(results, `./benchmark_system_tpch_${sf.toString().replace('.', '')}_duckdb.json`);
31 | }
32 |
33 | main();
34 |
--------------------------------------------------------------------------------
/packages/benchmarks/src/suite_system_tpch_lovefield.ts:
--------------------------------------------------------------------------------
1 | import { writeReport } from './setup';
2 | import { SystemBenchmarkContext, SystemBenchmark, LovefieldTPCHBenchmark } from './system';
3 | import { runSystemBenchmarks } from './suite';
4 | import * as path from 'path';
5 |
6 | async function main() {
7 | const args = process.argv.slice(2);
8 | if (args.length < 1) {
9 | console.error('usage: node suite-system-tpch.js ');
10 | process.exit(-1);
11 | }
12 | const sf = parseFloat(args[0]);
13 | console.log(`Scale Factor ${sf}`);
14 |
15 | const baseDir = path.resolve(__dirname, '../../../');
16 | const benchmarks: SystemBenchmark[] = [];
17 | for (const q of [1, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 16, 19]) {
18 | if (sf >= 0.25 && q == 9) {
19 | continue;
20 | }
21 | benchmarks.push(new LovefieldTPCHBenchmark(sf, q));
22 | }
23 | const ctx: SystemBenchmarkContext = {
24 | projectRootPath: baseDir,
25 | seed: Math.random(),
26 | };
27 |
28 | await LovefieldTPCHBenchmark.beforeGroup(ctx, sf);
29 | const results = await runSystemBenchmarks(ctx, benchmarks);
30 | await LovefieldTPCHBenchmark.afterGroup(ctx);
31 |
32 | console.log(results);
33 | await writeReport(results, `./benchmark_system_tpch_${sf.toString().replace('.', '')}_lovefield.json`);
34 | }
35 |
36 | main();
37 |
--------------------------------------------------------------------------------
/examples/esbuild-browser/index.ts:
--------------------------------------------------------------------------------
1 | import * as duckdb from '@duckdb/duckdb-wasm';
2 | import * as arrow from 'apache-arrow';
3 |
4 | (async () => {
5 | try {
6 | const DUCKDB_CONFIG = await duckdb.selectBundle({
7 | mvp: {
8 | mainModule: './duckdb-mvp.wasm',
9 | mainWorker: './duckdb-browser-mvp.worker.js',
10 | },
11 | eh: {
12 | mainModule: './duckdb-eh.wasm',
13 | mainWorker: './duckdb-browser-eh.worker.js',
14 | },
15 | coi: {
16 | mainModule: './duckdb-coi.wasm',
17 | mainWorker: './duckdb-browser-coi.worker.js',
18 | pthreadWorker: './duckdb-browser-coi.pthread.worker.js',
19 | },
20 | });
21 |
22 | const logger = new duckdb.ConsoleLogger();
23 | const worker = new Worker(DUCKDB_CONFIG.mainWorker!);
24 | const db = new duckdb.AsyncDuckDB(logger, worker);
25 | await db.instantiate(DUCKDB_CONFIG.mainModule, DUCKDB_CONFIG.pthreadWorker);
26 |
27 | const conn = await db.connect();
28 | await conn.query<{ v: arrow.Int }>(`SELECT count(*)::INTEGER as v FROM generate_series(0, 100) t(v)`);
29 |
30 | await conn.close();
31 | await db.terminate();
32 | await worker.terminate();
33 | } catch (e) {
34 | console.error(e);
35 | }
36 | })();
37 |
--------------------------------------------------------------------------------
/packages/benchmarks/src/suite_system_tpch_sqljs.ts:
--------------------------------------------------------------------------------
1 | import { writeReport, setupSqljs } from './setup';
2 | import { SystemBenchmarkContext, SystemBenchmark, SqljsTPCHBenchmark } from './system';
3 | import { runSystemBenchmarks } from './suite';
4 | import * as path from 'path';
5 |
6 | async function main() {
7 | const args = process.argv.slice(2);
8 | if (args.length < 1) {
9 | console.error('usage: node suite-system-tpch.js ');
10 | process.exit(-1);
11 | }
12 | const sf = parseFloat(args[0]);
13 | console.log(`Scale Factor ${sf}`);
14 |
15 | const baseDir = path.resolve(__dirname, '../../../');
16 | const sqljsDB = await setupSqljs();
17 | const benchmarks: SystemBenchmark[] = [];
18 | for (let i = 1; i <= 22; ++i) {
19 | if (sf >= 0.25 && (i == 17 || i == 20 || i == 22)) {
20 | continue;
21 | }
22 | benchmarks.push(new SqljsTPCHBenchmark(sf, i));
23 | }
24 | const ctx: SystemBenchmarkContext = {
25 | projectRootPath: baseDir,
26 | seed: Math.random(),
27 | };
28 | await SqljsTPCHBenchmark.beforeGroup(sqljsDB, ctx, sf);
29 | const results = await runSystemBenchmarks(ctx, benchmarks);
30 | await SqljsTPCHBenchmark.afterGroup();
31 |
32 | console.log(results);
33 | await writeReport(results, `./benchmark_system_tpch_${sf.toString().replace('.', '')}_sqljs.json`);
34 | }
35 |
36 | main();
37 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/targets/duckdb-node-eh.worker.ts:
--------------------------------------------------------------------------------
1 | import { AsyncDuckDBDispatcher, WorkerResponseVariant, WorkerRequestVariant } from '../parallel/';
2 | import { DuckDBBindings } from '../bindings';
3 | import { DuckDB } from '../bindings/bindings_node_eh';
4 | import { NODE_RUNTIME } from '../bindings/runtime_node';
5 | import { InstantiationProgress } from '../bindings/progress';
6 |
7 | /** The duckdb worker API for node.js workers */
8 | class NodeWorker extends AsyncDuckDBDispatcher {
9 | /** Post a response back to the main thread */
10 | protected postMessage(response: WorkerResponseVariant, transfer: ArrayBuffer[]) {
11 | globalThis.postMessage(response, transfer);
12 | }
13 |
14 | /** Instantiate the wasm module */
15 | protected async instantiate(
16 | mainModulePath: string,
17 | pthreadWorkerPath: string | null,
18 | progress: (p: InstantiationProgress) => void,
19 | ): Promise {
20 | const bindings = new DuckDB(this, NODE_RUNTIME, mainModulePath, pthreadWorkerPath);
21 | return await bindings.instantiate(progress);
22 | }
23 | }
24 |
25 | /** Register the worker */
26 | export function registerWorker(): void {
27 | const api = new NodeWorker();
28 | globalThis.onmessage = async (event: MessageEvent) => {
29 | await api.onMessage(event.data);
30 | };
31 | }
32 |
33 | registerWorker();
34 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/targets/duckdb-browser-coi.worker.ts:
--------------------------------------------------------------------------------
1 | import { AsyncDuckDBDispatcher, WorkerResponseVariant, WorkerRequestVariant } from '../parallel';
2 | import { DuckDB } from '../bindings/bindings_browser_coi';
3 | import { DuckDBBindings } from '../bindings';
4 | import { BROWSER_RUNTIME } from '../bindings/runtime_browser';
5 | import { InstantiationProgress } from '../bindings/progress';
6 |
7 | /** The duckdb worker API for web workers */
8 | class WebWorker extends AsyncDuckDBDispatcher {
9 | /** Post a response back to the main thread */
10 | protected postMessage(response: WorkerResponseVariant, transfer: ArrayBuffer[]) {
11 | globalThis.postMessage(response, transfer);
12 | }
13 |
14 | /** Instantiate the wasm module */
15 | protected async instantiate(
16 | mainModuleURL: string,
17 | pthreadWorkerURL: string | null,
18 | progress: (p: InstantiationProgress) => void,
19 | ): Promise {
20 | const bindings = new DuckDB(this, BROWSER_RUNTIME, mainModuleURL, pthreadWorkerURL);
21 | return await bindings.instantiate(progress);
22 | }
23 | }
24 |
25 | /** Register the worker */
26 | export function registerWorker(): void {
27 | const api = new WebWorker();
28 | globalThis.onmessage = async (event: MessageEvent) => {
29 | await api.onMessage(event.data);
30 | };
31 | }
32 |
33 | registerWorker();
34 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/targets/duckdb-browser-eh.worker.ts:
--------------------------------------------------------------------------------
1 | import { AsyncDuckDBDispatcher, WorkerResponseVariant, WorkerRequestVariant } from '../parallel';
2 | import { DuckDB } from '../bindings/bindings_browser_eh';
3 | import { DuckDBBindings } from '../bindings';
4 | import { BROWSER_RUNTIME } from '../bindings/runtime_browser';
5 | import { InstantiationProgress } from '../bindings/progress';
6 |
7 | /** The duckdb worker API for web workers */
8 | class WebWorker extends AsyncDuckDBDispatcher {
9 | /** Post a response back to the main thread */
10 | protected postMessage(response: WorkerResponseVariant, transfer: ArrayBuffer[]) {
11 | globalThis.postMessage(response, transfer);
12 | }
13 |
14 | /** Instantiate the wasm module */
15 | protected async instantiate(
16 | mainModuleURL: string,
17 | pthreadWorkerURL: string | null,
18 | progress: (p: InstantiationProgress) => void,
19 | ): Promise {
20 | const bindings = new DuckDB(this, BROWSER_RUNTIME, mainModuleURL, pthreadWorkerURL);
21 | return await bindings.instantiate(progress);
22 | }
23 | }
24 |
25 | /** Register the worker */
26 | export function registerWorker(): void {
27 | const api = new WebWorker();
28 | globalThis.onmessage = async (event: MessageEvent) => {
29 | await api.onMessage(event.data);
30 | };
31 | }
32 |
33 | registerWorker();
34 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/targets/duckdb-browser-mvp.worker.ts:
--------------------------------------------------------------------------------
1 | import { AsyncDuckDBDispatcher, WorkerResponseVariant, WorkerRequestVariant } from '../parallel';
2 | import { DuckDB } from '../bindings/bindings_browser_mvp';
3 | import { DuckDBBindings } from '../bindings';
4 | import { BROWSER_RUNTIME } from '../bindings/runtime_browser';
5 | import { InstantiationProgress } from '../bindings/progress';
6 |
7 | /** The duckdb worker API for web workers */
8 | class WebWorker extends AsyncDuckDBDispatcher {
9 | /** Post a response back to the main thread */
10 | protected postMessage(response: WorkerResponseVariant, transfer: ArrayBuffer[]) {
11 | globalThis.postMessage(response, transfer);
12 | }
13 |
14 | /** Instantiate the wasm module */
15 | protected async instantiate(
16 | mainModuleURL: string,
17 | pthreadWorkerURL: string | null,
18 | progress: (p: InstantiationProgress) => void,
19 | ): Promise {
20 | const bindings = new DuckDB(this, BROWSER_RUNTIME, mainModuleURL, pthreadWorkerURL);
21 | return await bindings.instantiate(progress);
22 | }
23 | }
24 |
25 | /** Register the worker */
26 | export function registerWorker(): void {
27 | const api = new WebWorker();
28 | globalThis.onmessage = async (event: MessageEvent) => {
29 | await api.onMessage(event.data);
30 | };
31 | }
32 |
33 | registerWorker();
34 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm/src/targets/duckdb-node-mvp.worker.ts:
--------------------------------------------------------------------------------
1 | import { AsyncDuckDBDispatcher, WorkerResponseVariant, WorkerRequestVariant } from '../parallel/';
2 | import { DuckDBBindings } from '../bindings';
3 | import { DuckDB } from '../bindings/bindings_node_mvp';
4 | import { NODE_RUNTIME } from '../bindings/runtime_node';
5 | import { InstantiationProgress } from '../bindings/progress';
6 |
7 | /** The duckdb worker API for node.js workers */
8 | class NodeWorker extends AsyncDuckDBDispatcher {
9 | /** Post a response back to the main thread */
10 | protected postMessage(response: WorkerResponseVariant, transfer: ArrayBuffer[]) {
11 | globalThis.postMessage(response, transfer);
12 | }
13 |
14 | /** Instantiate the wasm module */
15 | protected async instantiate(
16 | mainModulePath: string,
17 | pthreadWorkerPath: string | null,
18 | progress: (p: InstantiationProgress) => void,
19 | ): Promise {
20 | const bindings = new DuckDB(this, NODE_RUNTIME, mainModulePath, pthreadWorkerPath);
21 | return await bindings.instantiate(progress);
22 | }
23 | }
24 |
25 | /** Register the worker */
26 | export function registerWorker(): void {
27 | const api = new NodeWorker();
28 | globalThis.onmessage = async (event: MessageEvent) => {
29 | await api.onMessage(event.data);
30 | };
31 | }
32 |
33 | registerWorker();
34 |
--------------------------------------------------------------------------------
/packages/benchmarks/scripts/tpch/7.sql:
--------------------------------------------------------------------------------
1 | select
2 | supp_nation,
3 | cust_nation,
4 | l_year,
5 | sum(volume) as revenue
6 | from
7 | (
8 | select
9 | n1.n_name as supp_nation,
10 | n2.n_name as cust_nation,
11 | extract(
12 | year
13 | from
14 | l_shipdate
15 | ) as l_year,
16 | l_extendedprice * (1 - l_discount) as volume
17 | from
18 | supplier,
19 | lineitem,
20 | orders,
21 | customer,
22 | nation n1,
23 | nation n2
24 | where
25 | s_suppkey = l_suppkey
26 | and o_orderkey = l_orderkey
27 | and c_custkey = o_custkey
28 | and s_nationkey = n1.n_nationkey
29 | and c_nationkey = n2.n_nationkey
30 | and (
31 | (
32 | n1.n_name = 'FRANCE'
33 | and n2.n_name = 'GERMANY'
34 | )
35 | or (
36 | n1.n_name = 'GERMANY'
37 | and n2.n_name = 'FRANCE'
38 | )
39 | )
40 | and l_shipdate between '1995-01-01'
41 | and '1996-12-31'
42 | ) as shipping
43 | group by
44 | supp_nation,
45 | cust_nation,
46 | l_year
47 | order by
48 | supp_nation,
49 | cust_nation,
50 | l_year;
51 |
--------------------------------------------------------------------------------
/lib/cmake/rapidjson.cmake:
--------------------------------------------------------------------------------
1 | include(ExternalProject)
2 |
3 | # Get rapidjson
4 | ExternalProject_Add(
5 | rapidjson_ep
6 | SOURCE_DIR "${CMAKE_SOURCE_DIR}/../submodules/rapidjson"
7 | PREFIX "third_party/rapidjson"
8 | INSTALL_DIR "${CMAKE_BINARY_DIR}/third_party/rapidjson/install"
9 | CMAKE_ARGS
10 | -G${CMAKE_GENERATOR}
11 | -DCMAKE_CXX_STANDARD=17
12 | -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
13 | -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
14 | -DCMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER}
15 | -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
16 | -DCMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER}
17 | -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
18 | -DCMAKE_MODULE_PATH=${CMAKE_MODULE_PATH}
19 | -DCMAKE_BUILD_TYPE=Release
20 | -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/third_party/rapidjson/install
21 | -DRAPIDJSON_BUILD_DOC=FALSE
22 | -DRAPIDJSON_BUILD_EXAMPLES=FALSE
23 | -DRAPIDJSON_BUILD_TESTS=FALSE
24 | -DRAPIDJSON_BUILD_THIRDPARTY_GTEST=FALSE
25 | DOWNLOAD_COMMAND ""
26 | UPDATE_COMMAND "")
27 |
28 | # Prepare json
29 | ExternalProject_Get_Property(rapidjson_ep install_dir)
30 | set(RAPIDJSON_INCLUDE_DIR ${install_dir}/include)
31 | file(MAKE_DIRECTORY ${RAPIDJSON_INCLUDE_DIR})
32 | add_library(rapidjson INTERFACE)
33 | target_include_directories(rapidjson SYSTEM INTERFACE ${RAPIDJSON_INCLUDE_DIR})
34 |
35 | # Dependencies
36 | add_dependencies(rapidjson rapidjson_ep)
37 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-app/src/components/feature_table.module.css:
--------------------------------------------------------------------------------
1 | .table {
2 | width: 100%;
3 | display: grid;
4 | grid-template-columns: max-content 1fr 1fr 1fr 1fr;
5 | border: 1px solid rgb(180, 180, 180);
6 | overflow-x: auto;
7 | background-color: rgb(255, 255, 255);
8 | font-size: 0.8rem;
9 | margin-top: 20px;
10 | }
11 |
12 | .table_title {
13 | grid-column: 1 / span 5;
14 | padding: 0px 8px;
15 | background-color: rgb(30, 30, 30);
16 | color: white;
17 | font-size: 1rem;
18 | }
19 |
20 | .table_anchor {
21 | grid-column: 1;
22 | background-color: rgb(30, 30, 30);
23 | color: white;
24 | text-align: center;
25 | }
26 |
27 | .table_column_header {
28 | padding: 0px 8px;
29 | background-color: rgb(220, 220, 220);
30 | text-align: center;
31 | background-color: rgb(30, 30, 30);
32 | color: white;
33 | font-size: 1rem;
34 | }
35 |
36 | .table_row_header {
37 | grid-column: 1;
38 | text-align: left;
39 | font-weight: 500;
40 | padding: 0px 16px 0px 8px;
41 | background-color: rgb(90, 90, 90);
42 | color: white;
43 | }
44 |
45 | .table_entry {
46 | display: flex;
47 | flex-direction: row;
48 | justify-content: center;
49 | align-items: center;
50 | border-left: 1px solid rgb(220, 220, 220);
51 | border-top: 1px solid rgb(220, 220, 220);
52 | padding: 2px 4px 2px 4px;
53 | min-width: 160px;
54 | font-weight: 500;
55 | }
56 |
--------------------------------------------------------------------------------
/packages/duckdb-wasm-shell/crate/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "duckdb-wasm-shell"
3 | version = "0.1.0"
4 | authors = ["Andre Kohn "]
5 | edition = "2018"
6 | publish = false
7 |
8 | workspace = "../../../"
9 |
10 | [lib]
11 | crate-type = ["cdylib", "rlib"]
12 |
13 | [dependencies.web-sys]
14 | version = "0.3.51"
15 | features = [
16 | 'console',
17 | 'Crypto',
18 | 'Document',
19 | 'Element',
20 | 'Node',
21 | 'NodeList',
22 | 'Window',
23 | 'MouseEvent',
24 | 'KeyboardEvent',
25 | 'HtmlTextAreaElement',
26 | 'HtmlCanvasElement',
27 | 'WebSocket',
28 | 'Performance',
29 | ]
30 |
31 | [dependencies]
32 | serde = { version = "1.0.126", features = ["derive"] }
33 | serde_json = "1.0.64"
34 | log = "0.4.14"
35 | scopeguard = "1.1.0"
36 | anyhow = "1.0.41"
37 | console_error_panic_hook = "0.1.6"
38 | wasm-bindgen = { version = "0.2.88", features = ["serde-serialize"] }
39 | wasm-bindgen-futures = "0.4.50"
40 | chrono = "0.4.19"
41 | js-sys = "0.3.51"
42 | arrow = { version = "52.0.0", features = ["csv", "ipc"] }
43 | lazy_static = "1.4.0"
44 | encode_unicode = "0.3.6"
45 | unicode-width = "0.1.8"
46 | ropey = "1.2.0"
47 | strum = "^0.20"
48 | strum_macros = "^0.20"
49 | getrandom = { version = "0.2", features = ["js"] }
50 |
51 | [dev-dependencies]
52 | wasm-bindgen-test = "0.3.12"
53 |
54 | [profile.release]
55 | lto = true
56 | opt-level = "s"
57 |
58 | [package.metadata.wasm-pack.profile.release]
59 | wasm-opt = false
60 |
--------------------------------------------------------------------------------
/lib/cmake/spdlog.cmake:
--------------------------------------------------------------------------------
1 | include(ExternalProject)
2 |
3 | ExternalProject_Add(
4 | spdlog_ep
5 | SOURCE_DIR "${CMAKE_SOURCE_DIR}/../submodules/spdlog"
6 | INSTALL_DIR "${CMAKE_BINARY_DIR}/third_party/spdlog/install"
7 | PREFIX "${CMAKE_BINARY_DIR}/third_party/spdlog"
8 | CMAKE_ARGS
9 | -G${CMAKE_GENERATOR}
10 | -DCMAKE_CXX_STANDARD=17
11 | -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
12 | -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
13 | -DCMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER}
14 | -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
15 | -DCMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER}
16 | -DCMAKE_BUILD_TYPE=Release
17 | -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/third_party/spdlog/install
18 | -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
19 | -DSPDLOG_INSTALL=ON
20 | -DSPDLOG_BUILD_SHARED=OFF
21 | DOWNLOAD_COMMAND ""
22 | UPDATE_COMMAND ""
23 | BUILD_BYPRODUCTS /lib/libspdlog.a)
24 |
25 | ExternalProject_Get_Property(spdlog_ep install_dir)
26 | set(SPDLOG_INCLUDE_DIR ${install_dir}/include)
27 | set(SPDLOG_LIBRARY_PATH ${install_dir}/lib/libspdlog.a)
28 | file(MAKE_DIRECTORY ${SPDLOG_INCLUDE_DIR})
29 |
30 | add_library(spdlog STATIC IMPORTED)
31 | set_property(TARGET spdlog PROPERTY IMPORTED_LOCATION ${SPDLOG_LIBRARY_PATH})
32 | set_property(
33 | TARGET spdlog
34 | APPEND
35 | PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${SPDLOG_INCLUDE_DIR})
36 |
37 | add_dependencies(spdlog spdlog_ep)
38 |
--------------------------------------------------------------------------------