jupyter-duckdb 1.2.0.2__tar.gz → 1.2.0.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/PKG-INFO +26 -5
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/README.md +25 -4
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/kernel.py +38 -23
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/ConditionalSet.py +16 -3
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/tokenizer/Token.py +24 -3
- jupyter_duckdb-1.2.0.4/src/duckdb_kernel/util/TestError.py +4 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/jupyter_duckdb.egg-info/PKG-INFO +26 -5
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/jupyter_duckdb.egg-info/SOURCES.txt +1 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/test/test_dc.py +96 -2
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/setup.cfg +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/setup.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/__init__.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/__main__.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/db/Column.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/db/Connection.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/db/Constraint.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/db/DatabaseError.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/db/ForeignKey.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/db/Table.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/db/__init__.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/db/error/EmptyResultError.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/db/error/__init__.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/db/implementation/duckdb/Connection.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/db/implementation/duckdb/__init__.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/db/implementation/postgres/Connection.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/db/implementation/postgres/__init__.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/db/implementation/postgres/util.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/db/implementation/sqlite/Connection.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/db/implementation/sqlite/__init__.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/kernel.json +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/magics/MagicCommand.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/magics/MagicCommandCallback.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/magics/MagicCommandException.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/magics/MagicCommandHandler.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/magics/__init__.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/DCParser.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/LogicParser.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/RAParser.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/__init__.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/DCOperand.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/LogicElement.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/LogicOperand.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/LogicOperator.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/RABinaryOperator.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/RAElement.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/RAOperand.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/RAOperator.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/RAUnaryOperator.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/__init__.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/Add.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/And.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/ArrowLeft.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/Cross.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/Difference.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/Divide.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/Division.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/Equal.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/GreaterThan.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/GreaterThanEqual.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/Intersection.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/Join.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/LessThan.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/LessThanEqual.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/Minus.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/Multiply.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/Or.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/Unequal.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/Union.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/__init__.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/unary/Not.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/unary/Projection.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/unary/Rename.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/unary/Selection.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/unary/__init__.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/tokenizer/Tokenizer.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/tokenizer/__init__.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/util/RenamableColumn.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/util/RenamableColumnList.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/util/__init__.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/util/ResultSetComparator.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/util/__init__.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/util/formatting.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/visualization/Drawer.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/visualization/RATreeDrawer.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/visualization/SchemaDrawer.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/visualization/__init__.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/jupyter_duckdb.egg-info/dependency_links.txt +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/jupyter_duckdb.egg-info/requires.txt +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/jupyter_duckdb.egg-info/top_level.txt +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/test/test_ra.py +0 -0
- {jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/test/test_result_comparison.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: jupyter-duckdb
|
|
3
|
-
Version: 1.2.0.
|
|
3
|
+
Version: 1.2.0.4
|
|
4
4
|
Summary: a basic wrapper kernel for DuckDB
|
|
5
5
|
Home-page: https://github.com/erictroebs/jupyter-duckdb
|
|
6
6
|
Author: Eric Tröbs
|
|
@@ -32,10 +32,6 @@ This is a simple DuckDB wrapper kernel which accepts SQL as input, executes it
|
|
|
32
32
|
using a previously loaded DuckDB instance and formats the output as a table.
|
|
33
33
|
There are some magic commands that make teaching easier with this kernel.
|
|
34
34
|
|
|
35
|
-
## Quick Start
|
|
36
|
-
|
|
37
|
-
[](https://mybinder.org/v2/git/https%3A%2F%2Fdbgit.prakinf.tu-ilmenau.de%2Fertr8623%2Fjupyter-duckdb.git/master)
|
|
38
|
-
|
|
39
35
|
## Table of Contents
|
|
40
36
|
|
|
41
37
|
- [Setup](#setup)
|
|
@@ -85,6 +81,12 @@ Execute the following command to pull and run a prepared image.
|
|
|
85
81
|
docker run -p 8888:8888 troebs/jupyter-duckdb
|
|
86
82
|
```
|
|
87
83
|
|
|
84
|
+
There is also a second image. It contains an additional instance of PostgreSQL:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
docker run -p 8888:8888 troebs/jupyter-duckdb:postgresql
|
|
88
|
+
```
|
|
89
|
+
|
|
88
90
|
This image can also be used with JupyterHub and the
|
|
89
91
|
[DockerSpawner / SwarmSpawner](https://github.com/jupyterhub/dockerspawner)
|
|
90
92
|
and probably with the
|
|
@@ -138,6 +140,13 @@ Please note that `:memory:` is also a valid file path for DuckDB. The data is
|
|
|
138
140
|
then stored exclusively in the main memory. In combination with `CREATE`
|
|
139
141
|
and `OF` this makes it possible to work on a temporary copy in memory.
|
|
140
142
|
|
|
143
|
+
Although the name suggests otherwise, the kernel can also be used with other
|
|
144
|
+
databases:
|
|
145
|
+
- **SQLite** is automatically used as a fallback if the DuckDB dependency is
|
|
146
|
+
missing.
|
|
147
|
+
- To connect to a **PostgreSQL** instance, you need to specify a database URI
|
|
148
|
+
starting with `(postgresql|postgres|pgsql|psql|pg)://`.
|
|
149
|
+
|
|
141
150
|
### Schema Diagrams
|
|
142
151
|
|
|
143
152
|
The magic command `SCHEMA` can be used to create a simple schema diagram of the
|
|
@@ -153,6 +162,10 @@ representation requires more space, but can improve readability.
|
|
|
153
162
|
%SCHEMA TD
|
|
154
163
|
```
|
|
155
164
|
|
|
165
|
+
The optional argument `ONLY`, followed by one or more table names separated by a
|
|
166
|
+
comma, can be used to display only the named tables and all those connected with
|
|
167
|
+
a foreign key.
|
|
168
|
+
|
|
156
169
|
Graphviz (`dot` in PATH) is required to render schema diagrams.
|
|
157
170
|
|
|
158
171
|
### Number of Rows
|
|
@@ -234,6 +247,11 @@ UNION
|
|
|
234
247
|
SELECT 1, 'Name 1'
|
|
235
248
|
```
|
|
236
249
|
|
|
250
|
+
By default, failed tests will display an explanation, but the notebook will
|
|
251
|
+
continue to run. Set the `DUCKDB_TESTS_RAISE_EXCEPTION` environment variable to
|
|
252
|
+
`true` to raise an exception when a test fails. This can be useful for automated
|
|
253
|
+
testing in CI environments.
|
|
254
|
+
|
|
237
255
|
Disclaimer: The integrated testing is work-in-progress and thus subject to
|
|
238
256
|
potentially incompatible changes and enhancements.
|
|
239
257
|
|
|
@@ -259,6 +277,9 @@ The supported operations are:
|
|
|
259
277
|
- Cross Product `×`
|
|
260
278
|
- Division `÷`
|
|
261
279
|
|
|
280
|
+
The optional flag `ANALYZE` can be used to add an execution diagram to the
|
|
281
|
+
output.
|
|
282
|
+
|
|
262
283
|
The Dockerfile also installs the Jupyter Lab plugin
|
|
263
284
|
[jupyter-ra-extension](https://pypi.org/project/jupyter-ra-extension/). It adds
|
|
264
285
|
the symbols mentioned above and some other supported symbols to the toolbar for
|
|
@@ -4,10 +4,6 @@ This is a simple DuckDB wrapper kernel which accepts SQL as input, executes it
|
|
|
4
4
|
using a previously loaded DuckDB instance and formats the output as a table.
|
|
5
5
|
There are some magic commands that make teaching easier with this kernel.
|
|
6
6
|
|
|
7
|
-
## Quick Start
|
|
8
|
-
|
|
9
|
-
[](https://mybinder.org/v2/git/https%3A%2F%2Fdbgit.prakinf.tu-ilmenau.de%2Fertr8623%2Fjupyter-duckdb.git/master)
|
|
10
|
-
|
|
11
7
|
## Table of Contents
|
|
12
8
|
|
|
13
9
|
- [Setup](#setup)
|
|
@@ -57,6 +53,12 @@ Execute the following command to pull and run a prepared image.
|
|
|
57
53
|
docker run -p 8888:8888 troebs/jupyter-duckdb
|
|
58
54
|
```
|
|
59
55
|
|
|
56
|
+
There is also a second image. It contains an additional instance of PostgreSQL:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
docker run -p 8888:8888 troebs/jupyter-duckdb:postgresql
|
|
60
|
+
```
|
|
61
|
+
|
|
60
62
|
This image can also be used with JupyterHub and the
|
|
61
63
|
[DockerSpawner / SwarmSpawner](https://github.com/jupyterhub/dockerspawner)
|
|
62
64
|
and probably with the
|
|
@@ -110,6 +112,13 @@ Please note that `:memory:` is also a valid file path for DuckDB. The data is
|
|
|
110
112
|
then stored exclusively in the main memory. In combination with `CREATE`
|
|
111
113
|
and `OF` this makes it possible to work on a temporary copy in memory.
|
|
112
114
|
|
|
115
|
+
Although the name suggests otherwise, the kernel can also be used with other
|
|
116
|
+
databases:
|
|
117
|
+
- **SQLite** is automatically used as a fallback if the DuckDB dependency is
|
|
118
|
+
missing.
|
|
119
|
+
- To connect to a **PostgreSQL** instance, you need to specify a database URI
|
|
120
|
+
starting with `(postgresql|postgres|pgsql|psql|pg)://`.
|
|
121
|
+
|
|
113
122
|
### Schema Diagrams
|
|
114
123
|
|
|
115
124
|
The magic command `SCHEMA` can be used to create a simple schema diagram of the
|
|
@@ -125,6 +134,10 @@ representation requires more space, but can improve readability.
|
|
|
125
134
|
%SCHEMA TD
|
|
126
135
|
```
|
|
127
136
|
|
|
137
|
+
The optional argument `ONLY`, followed by one or more table names separated by a
|
|
138
|
+
comma, can be used to display only the named tables and all those connected with
|
|
139
|
+
a foreign key.
|
|
140
|
+
|
|
128
141
|
Graphviz (`dot` in PATH) is required to render schema diagrams.
|
|
129
142
|
|
|
130
143
|
### Number of Rows
|
|
@@ -206,6 +219,11 @@ UNION
|
|
|
206
219
|
SELECT 1, 'Name 1'
|
|
207
220
|
```
|
|
208
221
|
|
|
222
|
+
By default, failed tests will display an explanation, but the notebook will
|
|
223
|
+
continue to run. Set the `DUCKDB_TESTS_RAISE_EXCEPTION` environment variable to
|
|
224
|
+
`true` to raise an exception when a test fails. This can be useful for automated
|
|
225
|
+
testing in CI environments.
|
|
226
|
+
|
|
209
227
|
Disclaimer: The integrated testing is work-in-progress and thus subject to
|
|
210
228
|
potentially incompatible changes and enhancements.
|
|
211
229
|
|
|
@@ -231,6 +249,9 @@ The supported operations are:
|
|
|
231
249
|
- Cross Product `×`
|
|
232
250
|
- Division `÷`
|
|
233
251
|
|
|
252
|
+
The optional flag `ANALYZE` can be used to add an execution diagram to the
|
|
253
|
+
output.
|
|
254
|
+
|
|
234
255
|
The Dockerfile also installs the Jupyter Lab plugin
|
|
235
256
|
[jupyter-ra-extension](https://pypi.org/project/jupyter-ra-extension/). It adds
|
|
236
257
|
the symbols mentioned above and some other supported symbols to the toolbar for
|
|
@@ -9,11 +9,12 @@ from typing import Optional, Dict, List, Tuple
|
|
|
9
9
|
|
|
10
10
|
from ipykernel.kernelbase import Kernel
|
|
11
11
|
|
|
12
|
-
from .db import Connection, DatabaseError
|
|
12
|
+
from .db import Connection, DatabaseError, Table
|
|
13
13
|
from .db.error import *
|
|
14
14
|
from .magics import *
|
|
15
15
|
from .parser import RAParser, DCParser
|
|
16
16
|
from .util.ResultSetComparator import ResultSetComparator
|
|
17
|
+
from .util.TestError import TestError
|
|
17
18
|
from .util.formatting import row_count, rows_table, wrap_image
|
|
18
19
|
from .visualization import *
|
|
19
20
|
|
|
@@ -139,6 +140,7 @@ class DuckDBKernel(Kernel):
|
|
|
139
140
|
return False
|
|
140
141
|
|
|
141
142
|
def _execute_stmt(self, query: str, silent: bool,
|
|
143
|
+
column_name_mapping: Dict[str, str],
|
|
142
144
|
max_rows: Optional[int]) -> Tuple[Optional[List[str]], Optional[List[List]]]:
|
|
143
145
|
if self._db is None:
|
|
144
146
|
raise AssertionError('load a database first')
|
|
@@ -168,7 +170,8 @@ class DuckDBKernel(Kernel):
|
|
|
168
170
|
else:
|
|
169
171
|
if columns is not None:
|
|
170
172
|
# table header
|
|
171
|
-
|
|
173
|
+
mapped_columns = (column_name_mapping.get(c, c) for c in columns)
|
|
174
|
+
table_header = ''.join(f'<th>{c}</th>' for c in mapped_columns)
|
|
172
175
|
|
|
173
176
|
# table data
|
|
174
177
|
if max_rows is not None and len(rows) > max_rows:
|
|
@@ -302,12 +305,23 @@ class DuckDBKernel(Kernel):
|
|
|
302
305
|
result_columns = [col.rsplit('.', 1)[-1] for col in result_columns]
|
|
303
306
|
|
|
304
307
|
# extract data for test
|
|
305
|
-
|
|
308
|
+
test_data = self._tests[name]
|
|
306
309
|
|
|
310
|
+
# execute test
|
|
311
|
+
try:
|
|
312
|
+
self._execute_test(test_data, result_columns, result)
|
|
313
|
+
self.print_data(wrap_image(True))
|
|
314
|
+
except TestError as e:
|
|
315
|
+
self.print_data(wrap_image(False, e.message))
|
|
316
|
+
if os.environ.get('DUCKDB_TESTS_RAISE_EXCEPTION', 'false').lower() in ('true', '1'):
|
|
317
|
+
raise e
|
|
318
|
+
|
|
319
|
+
@staticmethod
|
|
320
|
+
def _execute_test(test_data: Dict, result_columns: List[str], result: List[List]):
|
|
307
321
|
# check columns if required
|
|
308
|
-
if isinstance(
|
|
322
|
+
if isinstance(test_data['equals'], dict):
|
|
309
323
|
# get column order
|
|
310
|
-
data_columns = list(
|
|
324
|
+
data_columns = list(test_data['equals'].keys())
|
|
311
325
|
column_order = []
|
|
312
326
|
|
|
313
327
|
for dc in data_columns:
|
|
@@ -318,39 +332,37 @@ class DuckDBKernel(Kernel):
|
|
|
318
332
|
found += 1
|
|
319
333
|
|
|
320
334
|
if found == 0:
|
|
321
|
-
|
|
335
|
+
raise TestError(f'attribute {dc} missing')
|
|
322
336
|
if found >= 2:
|
|
323
|
-
|
|
337
|
+
raise TestError(f'ambiguous attribute {dc}')
|
|
324
338
|
|
|
325
339
|
# abort if columns from result are unnecessary
|
|
326
340
|
for i, rc in enumerate(result_columns):
|
|
327
341
|
if i not in column_order:
|
|
328
|
-
|
|
342
|
+
raise TestError(f'unnecessary attribute {rc}')
|
|
329
343
|
|
|
330
344
|
# reorder columns and transform to list of lists
|
|
331
345
|
sorted_columns = [x for _, x in sorted(zip(column_order, data_columns))]
|
|
332
346
|
rows = []
|
|
333
347
|
|
|
334
|
-
for row in zip(*(
|
|
348
|
+
for row in zip(*(test_data['equals'][col] for col in sorted_columns)):
|
|
335
349
|
rows.append(row)
|
|
336
350
|
|
|
337
351
|
else:
|
|
338
|
-
rows =
|
|
352
|
+
rows = test_data['equals']
|
|
339
353
|
|
|
340
354
|
# ordered test
|
|
341
|
-
if
|
|
355
|
+
if test_data['ordered']:
|
|
342
356
|
# calculate diff
|
|
343
357
|
rsc = ResultSetComparator(result, rows)
|
|
344
358
|
|
|
345
359
|
missing = len(rsc.ordered_right_only)
|
|
346
360
|
if missing > 0:
|
|
347
|
-
|
|
361
|
+
raise TestError(f'{row_count(missing)} missing')
|
|
348
362
|
|
|
349
363
|
missing = len(rsc.ordered_left_only)
|
|
350
364
|
if missing > 0:
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
return self.print_data(wrap_image(True))
|
|
365
|
+
raise TestError(f'{row_count(missing)} more than required')
|
|
354
366
|
|
|
355
367
|
# unordered test
|
|
356
368
|
else:
|
|
@@ -362,13 +374,11 @@ class DuckDBKernel(Kernel):
|
|
|
362
374
|
|
|
363
375
|
# print result
|
|
364
376
|
if below > 0 and above > 0:
|
|
365
|
-
|
|
377
|
+
raise TestError(f'{row_count(below)} missing, {row_count(above)} unnecessary')
|
|
366
378
|
elif below > 0:
|
|
367
|
-
|
|
379
|
+
raise TestError(f'{row_count(below)} missing')
|
|
368
380
|
elif above > 0:
|
|
369
|
-
|
|
370
|
-
else:
|
|
371
|
-
self.print_data(wrap_image(True))
|
|
381
|
+
raise TestError(f'{row_count(above)} unnecessary')
|
|
372
382
|
|
|
373
383
|
def _all_magic(self, silent: bool):
|
|
374
384
|
return {
|
|
@@ -404,7 +414,7 @@ class DuckDBKernel(Kernel):
|
|
|
404
414
|
whitelist = set()
|
|
405
415
|
|
|
406
416
|
# split and strip names
|
|
407
|
-
names = [n.strip() for n in re.split(r'[, \t]', only)]
|
|
417
|
+
names = [Table.normalize_name(n.strip()) for n in re.split(r'[, \t]', only)]
|
|
408
418
|
|
|
409
419
|
# add initial tables to result set
|
|
410
420
|
for name in names:
|
|
@@ -503,10 +513,11 @@ class DuckDBKernel(Kernel):
|
|
|
503
513
|
root_node = DCParser.parse_query(code)
|
|
504
514
|
|
|
505
515
|
# generate sql
|
|
506
|
-
sql = root_node.
|
|
516
|
+
sql, cnm = root_node.to_sql_with_renamed_columns(tables)
|
|
507
517
|
|
|
508
518
|
return {
|
|
509
|
-
'generated_code': sql
|
|
519
|
+
'generated_code': sql,
|
|
520
|
+
'column_name_mapping': cnm
|
|
510
521
|
}
|
|
511
522
|
|
|
512
523
|
# jupyter related functions
|
|
@@ -530,6 +541,10 @@ class DuckDBKernel(Kernel):
|
|
|
530
541
|
clean_code = execution_args['generated_code']
|
|
531
542
|
del execution_args['generated_code']
|
|
532
543
|
|
|
544
|
+
# set default column name mapping if none provided
|
|
545
|
+
if 'column_name_mapping' not in execution_args:
|
|
546
|
+
execution_args['column_name_mapping'] = {}
|
|
547
|
+
|
|
533
548
|
# execute statement if needed
|
|
534
549
|
if clean_code.strip():
|
|
535
550
|
cols, rows = self._execute_stmt(clean_code, silent, **execution_args)
|
|
@@ -42,7 +42,7 @@ class ConditionalSet:
|
|
|
42
42
|
|
|
43
43
|
# If a constant was found, we store the value and replace it with a random attribute name.
|
|
44
44
|
constant = le.names[i]
|
|
45
|
-
new_token = Token.random()
|
|
45
|
+
new_token = Token.random(constant)
|
|
46
46
|
new_operand = DCOperand(le.relation, le.names[:i] + (new_token,) + le.names[i + 1:], skip_comma=True)
|
|
47
47
|
|
|
48
48
|
# We now need an equality comparison to ensure the introduced attribute is equal to the constant.
|
|
@@ -103,7 +103,7 @@ class ConditionalSet:
|
|
|
103
103
|
# The default case is to return the LogicElement with not DCOperands.
|
|
104
104
|
return le, []
|
|
105
105
|
|
|
106
|
-
def
|
|
106
|
+
def to_sql_with_renamed_columns(self, tables: Dict[str, Table]) -> Tuple[str, Dict[str, str]]:
|
|
107
107
|
# First we have to find and remove all DCOperands from the operator tree.
|
|
108
108
|
condition, dc_operands = self.split_tree(self.condition)
|
|
109
109
|
|
|
@@ -339,5 +339,18 @@ class ConditionalSet:
|
|
|
339
339
|
sql_join_filters += f' AND {join_filter}'
|
|
340
340
|
|
|
341
341
|
sql_condition = condition.to_sql(joined_columns) if condition is not None else '1=1'
|
|
342
|
+
sql_query = f'SELECT DISTINCT {sql_select} FROM {sql_tables} WHERE ({sql_join_filters}) AND ({sql_condition})'
|
|
343
|
+
|
|
344
|
+
# Create a mapping from intermediate column names to constant values.
|
|
345
|
+
column_name_mapping = {
|
|
346
|
+
p: p.constant
|
|
347
|
+
for o in dc_operands
|
|
348
|
+
for p in o.names
|
|
349
|
+
if p.constant is not None
|
|
350
|
+
}
|
|
342
351
|
|
|
343
|
-
return
|
|
352
|
+
return sql_query, column_name_mapping
|
|
353
|
+
|
|
354
|
+
def to_sql(self, tables: Dict[str, Table]) -> str:
|
|
355
|
+
sql, _ = self.to_sql_with_renamed_columns(tables)
|
|
356
|
+
return sql
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/tokenizer/Token.py
RENAMED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
from typing import Optional
|
|
1
2
|
from uuid import uuid4
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
class Token(str):
|
|
5
|
-
def __new__(cls, value: str):
|
|
6
|
+
def __new__(cls, value: str, constant: 'Token' = None):
|
|
6
7
|
while True:
|
|
7
8
|
# strip whitespaces
|
|
8
9
|
value = value.strip()
|
|
@@ -38,20 +39,40 @@ class Token(str):
|
|
|
38
39
|
|
|
39
40
|
return super().__new__(cls, value)
|
|
40
41
|
|
|
42
|
+
def __init__(self, value: str, constant: 'Token' = None):
|
|
43
|
+
self.constant: Optional[Token] = constant
|
|
44
|
+
|
|
41
45
|
@staticmethod
|
|
42
|
-
def random() -> 'Token':
|
|
43
|
-
return Token('__' + str(uuid4()).replace('-', '_'))
|
|
46
|
+
def random(constant: 'Token' = None) -> 'Token':
|
|
47
|
+
return Token('__' + str(uuid4()).replace('-', '_'), constant)
|
|
44
48
|
|
|
45
49
|
@property
|
|
46
50
|
def empty(self) -> bool:
|
|
47
51
|
return len(self) == 0
|
|
48
52
|
|
|
53
|
+
@property
|
|
54
|
+
def is_temporary(self) -> bool:
|
|
55
|
+
return self.startswith('__')
|
|
56
|
+
|
|
49
57
|
@property
|
|
50
58
|
def is_constant(self) -> bool:
|
|
51
59
|
return ((self[0] == '"' and self[-1] == '"') or
|
|
52
60
|
(self[0] == "'" and self[-1] == "'") or
|
|
53
61
|
self.replace('.', '', 1).isnumeric())
|
|
54
62
|
|
|
63
|
+
@property
|
|
64
|
+
def no_quotes(self) -> str:
|
|
65
|
+
quotes = ('"', "'")
|
|
66
|
+
|
|
67
|
+
if self[0] in quotes and self[-1] in quotes:
|
|
68
|
+
return self[1:-1]
|
|
69
|
+
if self[0] in quotes:
|
|
70
|
+
return self[1:]
|
|
71
|
+
if self[-1] in quotes:
|
|
72
|
+
return self[:-1]
|
|
73
|
+
else:
|
|
74
|
+
return self
|
|
75
|
+
|
|
55
76
|
@property
|
|
56
77
|
def single_quotes(self) -> str:
|
|
57
78
|
# TODO Is this comparison useless because tokens are cleaned automatically?
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: jupyter-duckdb
|
|
3
|
-
Version: 1.2.0.
|
|
3
|
+
Version: 1.2.0.4
|
|
4
4
|
Summary: a basic wrapper kernel for DuckDB
|
|
5
5
|
Home-page: https://github.com/erictroebs/jupyter-duckdb
|
|
6
6
|
Author: Eric Tröbs
|
|
@@ -32,10 +32,6 @@ This is a simple DuckDB wrapper kernel which accepts SQL as input, executes it
|
|
|
32
32
|
using a previously loaded DuckDB instance and formats the output as a table.
|
|
33
33
|
There are some magic commands that make teaching easier with this kernel.
|
|
34
34
|
|
|
35
|
-
## Quick Start
|
|
36
|
-
|
|
37
|
-
[](https://mybinder.org/v2/git/https%3A%2F%2Fdbgit.prakinf.tu-ilmenau.de%2Fertr8623%2Fjupyter-duckdb.git/master)
|
|
38
|
-
|
|
39
35
|
## Table of Contents
|
|
40
36
|
|
|
41
37
|
- [Setup](#setup)
|
|
@@ -85,6 +81,12 @@ Execute the following command to pull and run a prepared image.
|
|
|
85
81
|
docker run -p 8888:8888 troebs/jupyter-duckdb
|
|
86
82
|
```
|
|
87
83
|
|
|
84
|
+
There is also a second image. It contains an additional instance of PostgreSQL:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
docker run -p 8888:8888 troebs/jupyter-duckdb:postgresql
|
|
88
|
+
```
|
|
89
|
+
|
|
88
90
|
This image can also be used with JupyterHub and the
|
|
89
91
|
[DockerSpawner / SwarmSpawner](https://github.com/jupyterhub/dockerspawner)
|
|
90
92
|
and probably with the
|
|
@@ -138,6 +140,13 @@ Please note that `:memory:` is also a valid file path for DuckDB. The data is
|
|
|
138
140
|
then stored exclusively in the main memory. In combination with `CREATE`
|
|
139
141
|
and `OF` this makes it possible to work on a temporary copy in memory.
|
|
140
142
|
|
|
143
|
+
Although the name suggests otherwise, the kernel can also be used with other
|
|
144
|
+
databases:
|
|
145
|
+
- **SQLite** is automatically used as a fallback if the DuckDB dependency is
|
|
146
|
+
missing.
|
|
147
|
+
- To connect to a **PostgreSQL** instance, you need to specify a database URI
|
|
148
|
+
starting with `(postgresql|postgres|pgsql|psql|pg)://`.
|
|
149
|
+
|
|
141
150
|
### Schema Diagrams
|
|
142
151
|
|
|
143
152
|
The magic command `SCHEMA` can be used to create a simple schema diagram of the
|
|
@@ -153,6 +162,10 @@ representation requires more space, but can improve readability.
|
|
|
153
162
|
%SCHEMA TD
|
|
154
163
|
```
|
|
155
164
|
|
|
165
|
+
The optional argument `ONLY`, followed by one or more table names separated by a
|
|
166
|
+
comma, can be used to display only the named tables and all those connected with
|
|
167
|
+
a foreign key.
|
|
168
|
+
|
|
156
169
|
Graphviz (`dot` in PATH) is required to render schema diagrams.
|
|
157
170
|
|
|
158
171
|
### Number of Rows
|
|
@@ -234,6 +247,11 @@ UNION
|
|
|
234
247
|
SELECT 1, 'Name 1'
|
|
235
248
|
```
|
|
236
249
|
|
|
250
|
+
By default, failed tests will display an explanation, but the notebook will
|
|
251
|
+
continue to run. Set the `DUCKDB_TESTS_RAISE_EXCEPTION` environment variable to
|
|
252
|
+
`true` to raise an exception when a test fails. This can be useful for automated
|
|
253
|
+
testing in CI environments.
|
|
254
|
+
|
|
237
255
|
Disclaimer: The integrated testing is work-in-progress and thus subject to
|
|
238
256
|
potentially incompatible changes and enhancements.
|
|
239
257
|
|
|
@@ -259,6 +277,9 @@ The supported operations are:
|
|
|
259
277
|
- Cross Product `×`
|
|
260
278
|
- Division `÷`
|
|
261
279
|
|
|
280
|
+
The optional flag `ANALYZE` can be used to add an execution diagram to the
|
|
281
|
+
output.
|
|
282
|
+
|
|
262
283
|
The Dockerfile also installs the Jupyter Lab plugin
|
|
263
284
|
[jupyter-ra-extension](https://pypi.org/project/jupyter-ra-extension/). It adds
|
|
264
285
|
the symbols mentioned above and some other supported symbols to the toolbar for
|
|
@@ -72,6 +72,7 @@ src/duckdb_kernel/parser/util/RenamableColumn.py
|
|
|
72
72
|
src/duckdb_kernel/parser/util/RenamableColumnList.py
|
|
73
73
|
src/duckdb_kernel/parser/util/__init__.py
|
|
74
74
|
src/duckdb_kernel/util/ResultSetComparator.py
|
|
75
|
+
src/duckdb_kernel/util/TestError.py
|
|
75
76
|
src/duckdb_kernel/util/__init__.py
|
|
76
77
|
src/duckdb_kernel/util/formatting.py
|
|
77
78
|
src/duckdb_kernel/visualization/Drawer.py
|
|
@@ -7,7 +7,23 @@ def test_case_insensitivity():
|
|
|
7
7
|
'{ username | users(id, username) }',
|
|
8
8
|
'{ username | Users(id, username) }',
|
|
9
9
|
'{ username | USERS(id, username) }',
|
|
10
|
-
'{ username | uSers(id, username) }'
|
|
10
|
+
'{ username | uSers(id, username) }',
|
|
11
|
+
):
|
|
12
|
+
root = DCParser.parse_query(query)
|
|
13
|
+
|
|
14
|
+
# execute to test case insensitivity
|
|
15
|
+
with Connection() as con:
|
|
16
|
+
assert con.execute_dc(root) == [
|
|
17
|
+
('Alice',),
|
|
18
|
+
('Bob',),
|
|
19
|
+
('Charlie',)
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
for query in (
|
|
23
|
+
'{ username | users(id, username) }',
|
|
24
|
+
'{ Username | users(id, username) }',
|
|
25
|
+
'{ USERNAME | users(id, username) }',
|
|
26
|
+
'{ userName | users(id, username) }',
|
|
11
27
|
):
|
|
12
28
|
root = DCParser.parse_query(query)
|
|
13
29
|
|
|
@@ -79,7 +95,8 @@ def test_conditions():
|
|
|
79
95
|
]
|
|
80
96
|
|
|
81
97
|
for query in [
|
|
82
|
-
'{ id | Users(id, name) ∧ name
|
|
98
|
+
'{ id | Users(id, name) ∧ name = "Bob" }',
|
|
99
|
+
'{ id | Users(id, name) ∧ name > "B" ∧ name < "C" }',
|
|
83
100
|
]:
|
|
84
101
|
root = DCParser.parse_query(query)
|
|
85
102
|
assert con.execute_dc(root) == [
|
|
@@ -189,6 +206,33 @@ def test_joins():
|
|
|
189
206
|
]
|
|
190
207
|
|
|
191
208
|
|
|
209
|
+
def test_disjunction_joins():
|
|
210
|
+
with Connection() as con:
|
|
211
|
+
for query in [
|
|
212
|
+
"{ enum, snum, sid | Episodes(enum, snum, sid, ename) ∧ (Characters('Character B', enum, snum, sid, _) ∨ Characters('Character D', enum, snum, sid, _)) }",
|
|
213
|
+
"{ enum, snum, sid | Episodes(enum, snum, sid, ename) ∧ (Characters(cname1, enum, snum, sid, _) ∧ cname1 = 'Character B' ∨ Characters(cname2, enum, snum, sid, _) ∧ cname2 = 'Character D') }",
|
|
214
|
+
]:
|
|
215
|
+
root = DCParser.parse_query(query)
|
|
216
|
+
assert con.execute_dc(root) == [
|
|
217
|
+
(1, 1, 1),
|
|
218
|
+
(2, 1, 1)
|
|
219
|
+
]
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def test_cross_join():
|
|
223
|
+
with Connection() as con:
|
|
224
|
+
for query in [
|
|
225
|
+
"{ cname1, cname2 | Characters(cname1, _, _, 2, _) ∧ Characters(cname2, _, _, 2, _) }",
|
|
226
|
+
]:
|
|
227
|
+
root = DCParser.parse_query(query)
|
|
228
|
+
assert con.execute_dc(root) == [
|
|
229
|
+
('Character E', 'Character E'),
|
|
230
|
+
('Character E', 'Character F'),
|
|
231
|
+
('Character F', 'Character E'),
|
|
232
|
+
('Character F', 'Character F'),
|
|
233
|
+
]
|
|
234
|
+
|
|
235
|
+
|
|
192
236
|
def test_underscores():
|
|
193
237
|
with Connection() as con:
|
|
194
238
|
# distinct underscores
|
|
@@ -239,3 +283,53 @@ def test_underscores():
|
|
|
239
283
|
('Show 2 / Season 2 / Episode 3',),
|
|
240
284
|
('Show 2 / Season 2 / Episode 4',)
|
|
241
285
|
]
|
|
286
|
+
|
|
287
|
+
def test_anonymous_column_names():
|
|
288
|
+
with Connection() as con:
|
|
289
|
+
for query in [
|
|
290
|
+
'{ * | Episodes(_, _, 2, ename) }',
|
|
291
|
+
]:
|
|
292
|
+
root = DCParser.parse_query(query)
|
|
293
|
+
cols, _ = con.execute_dc_return_cols(root)
|
|
294
|
+
|
|
295
|
+
assert cols == ['2', 'ename']
|
|
296
|
+
|
|
297
|
+
for query in [
|
|
298
|
+
"{ * | Episodes(_, _, '2', ename) }",
|
|
299
|
+
]:
|
|
300
|
+
root = DCParser.parse_query(query)
|
|
301
|
+
cols, _ = con.execute_dc_return_cols(root)
|
|
302
|
+
|
|
303
|
+
assert cols == ["'2'", 'ename']
|
|
304
|
+
|
|
305
|
+
for query in [
|
|
306
|
+
"{ * | Episodes(_, _, sid, 'ename') }",
|
|
307
|
+
]:
|
|
308
|
+
root = DCParser.parse_query(query)
|
|
309
|
+
cols, _ = con.execute_dc_return_cols(root)
|
|
310
|
+
|
|
311
|
+
assert cols == ['sid', "'ename'"]
|
|
312
|
+
|
|
313
|
+
for query in [
|
|
314
|
+
'{ * | Episodes(_, 1, 2, ename) }',
|
|
315
|
+
]:
|
|
316
|
+
root = DCParser.parse_query(query)
|
|
317
|
+
cols, _ = con.execute_dc_return_cols(root)
|
|
318
|
+
|
|
319
|
+
assert cols == ['1', '2', 'ename']
|
|
320
|
+
|
|
321
|
+
for query in [
|
|
322
|
+
'{ * | Episodes(_, 2, 2, ename) }',
|
|
323
|
+
]:
|
|
324
|
+
root = DCParser.parse_query(query)
|
|
325
|
+
cols, _ = con.execute_dc_return_cols(root)
|
|
326
|
+
|
|
327
|
+
assert cols == ['2', '2', 'ename']
|
|
328
|
+
|
|
329
|
+
for query in [
|
|
330
|
+
'{ * | Episodes(_, _, sid, ename) ∧ sid = 2 }',
|
|
331
|
+
]:
|
|
332
|
+
root = DCParser.parse_query(query)
|
|
333
|
+
cols, _ = con.execute_dc_return_cols(root)
|
|
334
|
+
|
|
335
|
+
assert cols == ['sid', 'ename']
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/db/error/EmptyResultError.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/magics/MagicCommandCallback.py
RENAMED
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/magics/MagicCommandException.py
RENAMED
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/magics/MagicCommandHandler.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/DCOperand.py
RENAMED
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/LogicElement.py
RENAMED
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/LogicOperand.py
RENAMED
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/LogicOperator.py
RENAMED
|
File without changes
|
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/RAElement.py
RENAMED
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/RAOperand.py
RENAMED
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/RAOperator.py
RENAMED
|
File without changes
|
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/__init__.py
RENAMED
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/Add.py
RENAMED
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/And.py
RENAMED
|
File without changes
|
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/Cross.py
RENAMED
|
File without changes
|
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/Divide.py
RENAMED
|
File without changes
|
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/Equal.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/Join.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/Minus.py
RENAMED
|
File without changes
|
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/Or.py
RENAMED
|
File without changes
|
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/binary/Union.py
RENAMED
|
File without changes
|
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/unary/Not.py
RENAMED
|
File without changes
|
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/elements/unary/Rename.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/tokenizer/Tokenizer.py
RENAMED
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/tokenizer/__init__.py
RENAMED
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/parser/util/RenamableColumn.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/util/ResultSetComparator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/visualization/RATreeDrawer.py
RENAMED
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/visualization/SchemaDrawer.py
RENAMED
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/duckdb_kernel/visualization/__init__.py
RENAMED
|
File without changes
|
{jupyter_duckdb-1.2.0.2 → jupyter_duckdb-1.2.0.4}/src/jupyter_duckdb.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|