singlestoredb 1.11.0__tar.gz → 1.12.1__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.
Potentially problematic release.
This version of singlestoredb might be problematic. Click here for more details.
- {singlestoredb-1.11.0/singlestoredb.egg-info → singlestoredb-1.12.1}/PKG-INFO +2 -1
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/accel.c +18 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/setup.cfg +4 -2
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/__init__.py +1 -1
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/config.py +6 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/connection.py +7 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/converters.py +5 -5
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/functions/__init__.py +1 -0
- singlestoredb-1.12.1/singlestoredb/functions/decorator.py +331 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/functions/ext/asgi.py +121 -27
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/functions/signature.py +100 -9
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/fusion/handlers/export.py +58 -2
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/fusion/handlers/files.py +6 -6
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/fusion/handlers/utils.py +14 -8
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/fusion/result.py +1 -1
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/http/connection.py +4 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/management/export.py +30 -7
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/management/files.py +7 -8
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/management/workspace.py +5 -6
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/connection.py +24 -19
- singlestoredb-1.12.1/singlestoredb/server/docker.py +455 -0
- singlestoredb-1.12.1/singlestoredb/server/free_tier.py +267 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/tests/test_management.py +50 -2
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/tests/test_udf.py +84 -32
- singlestoredb-1.12.1/singlestoredb/utils/__init__.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1/singlestoredb.egg-info}/PKG-INFO +2 -1
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb.egg-info/SOURCES.txt +3 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb.egg-info/requires.txt +3 -0
- singlestoredb-1.11.0/singlestoredb/functions/decorator.py +0 -142
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/LICENSE +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/README.md +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/setup.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/ai/__init__.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/ai/embeddings.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/alchemy/__init__.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/apps/__init__.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/apps/_cloud_functions.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/apps/_config.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/apps/_connection_info.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/apps/_dashboards.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/apps/_process.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/apps/_stdout_supress.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/apps/_uvicorn_util.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/auth.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/exceptions.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/functions/dtypes.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/functions/ext/__init__.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/functions/ext/arrow.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/functions/ext/json.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/functions/ext/mmap.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/functions/ext/rowdat_1.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/functions/ext/utils.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/fusion/__init__.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/fusion/graphql.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/fusion/handler.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/fusion/handlers/__init__.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/fusion/handlers/job.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/fusion/handlers/models.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/fusion/handlers/stage.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/fusion/handlers/workspace.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/fusion/registry.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/http/__init__.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/magics/__init__.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/magics/run_personal.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/magics/run_shared.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/management/__init__.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/management/billing_usage.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/management/cluster.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/management/job.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/management/manager.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/management/organization.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/management/region.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/management/utils.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/__init__.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/_auth.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/charset.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/constants/CLIENT.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/constants/COMMAND.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/constants/CR.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/constants/ER.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/constants/EXTENDED_TYPE.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/constants/FIELD_TYPE.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/constants/FLAG.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/constants/SERVER_STATUS.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/constants/VECTOR_TYPE.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/constants/__init__.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/converters.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/cursors.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/err.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/optionfile.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/protocol.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/tests/__init__.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/tests/base.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/tests/conftest.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/tests/test_DictCursor.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/tests/test_SSCursor.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/tests/test_basic.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/tests/test_connection.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/tests/test_converters.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/tests/test_cursor.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/tests/test_err.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/tests/test_issues.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/tests/test_load_local.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/tests/test_nextset.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/tests/test_optionfile.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/tests/thirdparty/__init__.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/tests/thirdparty/test_MySQLdb/__init__.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/tests/thirdparty/test_MySQLdb/capabilities.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/tests/thirdparty/test_MySQLdb/dbapi20.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_capabilities.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_dbapi20.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_nonstandard.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/mysql/times.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/notebook/__init__.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/notebook/_objects.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/notebook/_portal.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/py.typed +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/pytest.py +0 -0
- {singlestoredb-1.11.0/singlestoredb/tests → singlestoredb-1.12.1/singlestoredb/server}/__init__.py +0 -0
- {singlestoredb-1.11.0/singlestoredb/utils → singlestoredb-1.12.1/singlestoredb/tests}/__init__.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/tests/empty.sql +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/tests/ext_funcs/__init__.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/tests/local_infile.csv +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/tests/test.ipynb +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/tests/test.sql +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/tests/test2.ipynb +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/tests/test2.sql +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/tests/test_basics.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/tests/test_config.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/tests/test_connection.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/tests/test_dbapi.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/tests/test_exceptions.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/tests/test_ext_func.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/tests/test_ext_func_data.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/tests/test_fusion.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/tests/test_http.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/tests/test_plugin.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/tests/test_results.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/tests/test_types.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/tests/test_xdict.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/tests/utils.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/types.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/utils/config.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/utils/convert_rows.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/utils/debug.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/utils/dtypes.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/utils/events.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/utils/mogrify.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/utils/results.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb/utils/xdict.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb.egg-info/dependency_links.txt +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb.egg-info/entry_points.txt +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/singlestoredb.egg-info/top_level.txt +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/sqlx/__init__.py +0 -0
- {singlestoredb-1.11.0 → singlestoredb-1.12.1}/sqlx/magic.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: singlestoredb
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.12.1
|
|
4
4
|
Summary: Interface to the SingleStoreDB database and workspace management APIs
|
|
5
5
|
Home-page: https://github.com/singlestore-labs/singlestoredb-python
|
|
6
6
|
Author: SingleStore
|
|
@@ -15,6 +15,7 @@ Requires-Python: >=3.8
|
|
|
15
15
|
Description-Content-Type: text/markdown
|
|
16
16
|
Provides-Extra: dataframe
|
|
17
17
|
Provides-Extra: dbt
|
|
18
|
+
Provides-Extra: docker
|
|
18
19
|
Provides-Extra: ed22519
|
|
19
20
|
Provides-Extra: gssapi
|
|
20
21
|
Provides-Extra: ibis
|
|
@@ -1533,6 +1533,15 @@ static PyObject *read_row_from_packet(
|
|
|
1533
1533
|
if (!py_str) goto error;
|
|
1534
1534
|
} else {
|
|
1535
1535
|
py_str = PyUnicode_Decode(out, out_l, py_state->encodings[i], py_state->encoding_errors);
|
|
1536
|
+
if (PyErr_Occurred()) {
|
|
1537
|
+
PyErr_Clear();
|
|
1538
|
+
PyErr_Format(
|
|
1539
|
+
PyExc_UnicodeDecodeError,
|
|
1540
|
+
"failed to decode string value in column '%S' using encoding '%s'; "
|
|
1541
|
+
"use the 'encoding_errors' option on the connection to specify how to handle this error",
|
|
1542
|
+
py_state->py_names[i], py_state->encodings[i]
|
|
1543
|
+
);
|
|
1544
|
+
}
|
|
1536
1545
|
if (!py_str) goto error;
|
|
1537
1546
|
}
|
|
1538
1547
|
if (py_state->py_converters[i] == Py_None) {
|
|
@@ -1740,6 +1749,15 @@ static PyObject *read_row_from_packet(
|
|
|
1740
1749
|
}
|
|
1741
1750
|
|
|
1742
1751
|
py_item = PyUnicode_Decode(out, out_l, py_state->encodings[i], py_state->encoding_errors);
|
|
1752
|
+
if (PyErr_Occurred()) {
|
|
1753
|
+
PyErr_Clear();
|
|
1754
|
+
PyErr_Format(
|
|
1755
|
+
PyExc_UnicodeDecodeError,
|
|
1756
|
+
"failed to decode string value in column '%S' using encoding '%s'; "
|
|
1757
|
+
"use the 'encoding_errors' option on the connection to specify how to handle this error",
|
|
1758
|
+
py_state->py_names[i], py_state->encodings[i]
|
|
1759
|
+
);
|
|
1760
|
+
}
|
|
1743
1761
|
if (!py_item) goto error;
|
|
1744
1762
|
|
|
1745
1763
|
// Parse JSON string.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[metadata]
|
|
2
2
|
name = singlestoredb
|
|
3
|
-
version = 1.
|
|
3
|
+
version = 1.12.1
|
|
4
4
|
description = Interface to the SingleStoreDB database and workspace management APIs
|
|
5
5
|
long_description = file: README.md
|
|
6
6
|
long_description_content_type = text/markdown
|
|
@@ -50,6 +50,8 @@ dataframe =
|
|
|
50
50
|
ibis-singlestoredb
|
|
51
51
|
dbt =
|
|
52
52
|
dbt-singlestore
|
|
53
|
+
docker =
|
|
54
|
+
docker
|
|
53
55
|
ed22519 =
|
|
54
56
|
PyNaCl>=1.4.0
|
|
55
57
|
gssapi =
|
|
@@ -81,7 +83,7 @@ exclude =
|
|
|
81
83
|
docs/*
|
|
82
84
|
resources/*
|
|
83
85
|
licenses/*
|
|
84
|
-
max-complexity =
|
|
86
|
+
max-complexity = 45
|
|
85
87
|
max-line-length = 90
|
|
86
88
|
per-file-ignores =
|
|
87
89
|
singlestoredb/__init__.py:F401
|
|
@@ -201,6 +201,12 @@ register_option(
|
|
|
201
201
|
environ='SINGLESTOREDB_BUFFERED',
|
|
202
202
|
)
|
|
203
203
|
|
|
204
|
+
register_option(
|
|
205
|
+
'parse_json', 'bool', check_bool, True,
|
|
206
|
+
'Parse JSON values into Python objects?',
|
|
207
|
+
environ='SINGLESTOREDB_PARSE_JSON',
|
|
208
|
+
)
|
|
209
|
+
|
|
204
210
|
register_option(
|
|
205
211
|
'connect_timeout', 'int', check_int, 10,
|
|
206
212
|
'The timeout for connecting to the database in seconds. '
|
|
@@ -541,10 +541,16 @@ class Cursor(metaclass=abc.ABCMeta):
|
|
|
541
541
|
|
|
542
542
|
Examples
|
|
543
543
|
--------
|
|
544
|
+
Query with no parameters
|
|
545
|
+
|
|
544
546
|
>>> cur.execute('select * from mytable')
|
|
545
547
|
|
|
548
|
+
Query with positional parameters
|
|
549
|
+
|
|
546
550
|
>>> cur.execute('select * from mytable where id < %s', [100])
|
|
547
551
|
|
|
552
|
+
Query with named parameters
|
|
553
|
+
|
|
548
554
|
>>> cur.execute('select * from mytable where id < %(max)s', dict(max=100))
|
|
549
555
|
|
|
550
556
|
Returns
|
|
@@ -1317,6 +1323,7 @@ def connect(
|
|
|
1317
1323
|
track_env: Optional[bool] = None,
|
|
1318
1324
|
enable_extended_data_types: Optional[bool] = None,
|
|
1319
1325
|
vector_data_format: Optional[str] = None,
|
|
1326
|
+
parse_json: Optional[bool] = None,
|
|
1320
1327
|
) -> Connection:
|
|
1321
1328
|
"""
|
|
1322
1329
|
Return a SingleStoreDB connection.
|
|
@@ -594,7 +594,7 @@ def float32_vector_or_none(x: Optional[bytes]) -> Optional[Any]:
|
|
|
594
594
|
if has_numpy:
|
|
595
595
|
return numpy.frombuffer(x, dtype=numpy.float32)
|
|
596
596
|
|
|
597
|
-
return struct.unpack(f'<{len(x)
|
|
597
|
+
return struct.unpack(f'<{len(x)//4}f', x)
|
|
598
598
|
|
|
599
599
|
|
|
600
600
|
def float64_vector_json_or_none(x: Optional[str]) -> Optional[Any]:
|
|
@@ -650,7 +650,7 @@ def float64_vector_or_none(x: Optional[bytes]) -> Optional[Any]:
|
|
|
650
650
|
if has_numpy:
|
|
651
651
|
return numpy.frombuffer(x, dtype=numpy.float64)
|
|
652
652
|
|
|
653
|
-
return struct.unpack(f'<{len(x)
|
|
653
|
+
return struct.unpack(f'<{len(x)//8}d', x)
|
|
654
654
|
|
|
655
655
|
|
|
656
656
|
def int8_vector_json_or_none(x: Optional[str]) -> Optional[Any]:
|
|
@@ -762,7 +762,7 @@ def int16_vector_or_none(x: Optional[bytes]) -> Optional[Any]:
|
|
|
762
762
|
if has_numpy:
|
|
763
763
|
return numpy.frombuffer(x, dtype=numpy.int16)
|
|
764
764
|
|
|
765
|
-
return struct.unpack(f'<{len(x)
|
|
765
|
+
return struct.unpack(f'<{len(x)//2}h', x)
|
|
766
766
|
|
|
767
767
|
|
|
768
768
|
def int32_vector_json_or_none(x: Optional[str]) -> Optional[Any]:
|
|
@@ -818,7 +818,7 @@ def int32_vector_or_none(x: Optional[bytes]) -> Optional[Any]:
|
|
|
818
818
|
if has_numpy:
|
|
819
819
|
return numpy.frombuffer(x, dtype=numpy.int32)
|
|
820
820
|
|
|
821
|
-
return struct.unpack(f'<{len(x)
|
|
821
|
+
return struct.unpack(f'<{len(x)//4}l', x)
|
|
822
822
|
|
|
823
823
|
|
|
824
824
|
def int64_vector_json_or_none(x: Optional[str]) -> Optional[Any]:
|
|
@@ -875,7 +875,7 @@ def int64_vector_or_none(x: Optional[bytes]) -> Optional[Any]:
|
|
|
875
875
|
if has_numpy:
|
|
876
876
|
return numpy.frombuffer(x, dtype=numpy.int64)
|
|
877
877
|
|
|
878
|
-
return struct.unpack(f'<{len(x)
|
|
878
|
+
return struct.unpack(f'<{len(x)//8}l', x)
|
|
879
879
|
|
|
880
880
|
|
|
881
881
|
def bson_or_none(x: Optional[bytes]) -> Optional[Any]:
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import dataclasses
|
|
2
|
+
import datetime
|
|
3
|
+
import functools
|
|
4
|
+
import inspect
|
|
5
|
+
from typing import Any
|
|
6
|
+
from typing import Callable
|
|
7
|
+
from typing import Dict
|
|
8
|
+
from typing import List
|
|
9
|
+
from typing import Optional
|
|
10
|
+
from typing import Tuple
|
|
11
|
+
from typing import Union
|
|
12
|
+
|
|
13
|
+
from . import dtypes
|
|
14
|
+
from .dtypes import DataType
|
|
15
|
+
from .signature import simplify_dtype
|
|
16
|
+
|
|
17
|
+
try:
|
|
18
|
+
import pydantic
|
|
19
|
+
has_pydantic = True
|
|
20
|
+
except ImportError:
|
|
21
|
+
has_pydantic = False
|
|
22
|
+
|
|
23
|
+
python_type_map: Dict[Any, Callable[..., str]] = {
|
|
24
|
+
str: dtypes.TEXT,
|
|
25
|
+
int: dtypes.BIGINT,
|
|
26
|
+
float: dtypes.DOUBLE,
|
|
27
|
+
bool: dtypes.BOOL,
|
|
28
|
+
bytes: dtypes.BINARY,
|
|
29
|
+
bytearray: dtypes.BINARY,
|
|
30
|
+
datetime.datetime: dtypes.DATETIME,
|
|
31
|
+
datetime.date: dtypes.DATE,
|
|
32
|
+
datetime.timedelta: dtypes.TIME,
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def listify(x: Any) -> List[Any]:
|
|
37
|
+
"""Make sure sure value is a list."""
|
|
38
|
+
if x is None:
|
|
39
|
+
return []
|
|
40
|
+
if isinstance(x, (list, tuple, set)):
|
|
41
|
+
return list(x)
|
|
42
|
+
return [x]
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def process_annotation(annotation: Any) -> Tuple[Any, bool]:
|
|
46
|
+
types = simplify_dtype(annotation)
|
|
47
|
+
if isinstance(types, list):
|
|
48
|
+
nullable = False
|
|
49
|
+
if type(None) in types:
|
|
50
|
+
nullable = True
|
|
51
|
+
types = [x for x in types if x is not type(None)]
|
|
52
|
+
if len(types) > 1:
|
|
53
|
+
raise ValueError(f'multiple types not supported: {annotation}')
|
|
54
|
+
return types[0], nullable
|
|
55
|
+
return types, True
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def process_types(params: Any) -> Any:
|
|
59
|
+
if params is None:
|
|
60
|
+
return params, []
|
|
61
|
+
|
|
62
|
+
elif isinstance(params, (list, tuple)):
|
|
63
|
+
params = list(params)
|
|
64
|
+
for i, item in enumerate(params):
|
|
65
|
+
if params[i] in python_type_map:
|
|
66
|
+
params[i] = python_type_map[params[i]]()
|
|
67
|
+
elif callable(item):
|
|
68
|
+
params[i] = item()
|
|
69
|
+
for item in params:
|
|
70
|
+
if not isinstance(item, str):
|
|
71
|
+
raise TypeError(f'unrecognized type for parameter: {item}')
|
|
72
|
+
return params, []
|
|
73
|
+
|
|
74
|
+
elif isinstance(params, dict):
|
|
75
|
+
names = []
|
|
76
|
+
params = dict(params)
|
|
77
|
+
for k, v in list(params.items()):
|
|
78
|
+
names.append(k)
|
|
79
|
+
if params[k] in python_type_map:
|
|
80
|
+
params[k] = python_type_map[params[k]]()
|
|
81
|
+
elif callable(v):
|
|
82
|
+
params[k] = v()
|
|
83
|
+
for item in params.values():
|
|
84
|
+
if not isinstance(item, str):
|
|
85
|
+
raise TypeError(f'unrecognized type for parameter: {item}')
|
|
86
|
+
return params, names
|
|
87
|
+
|
|
88
|
+
elif dataclasses.is_dataclass(params):
|
|
89
|
+
names = []
|
|
90
|
+
out = []
|
|
91
|
+
for item in dataclasses.fields(params):
|
|
92
|
+
typ, nullable = process_annotation(item.type)
|
|
93
|
+
sql_type = process_types(typ)[0]
|
|
94
|
+
if not nullable:
|
|
95
|
+
sql_type = sql_type.replace('NULL', 'NOT NULL')
|
|
96
|
+
out.append(sql_type)
|
|
97
|
+
names.append(item.name)
|
|
98
|
+
return out, names
|
|
99
|
+
|
|
100
|
+
elif has_pydantic and inspect.isclass(params) \
|
|
101
|
+
and issubclass(params, pydantic.BaseModel):
|
|
102
|
+
names = []
|
|
103
|
+
out = []
|
|
104
|
+
for name, item in params.model_fields.items():
|
|
105
|
+
typ, nullable = process_annotation(item.annotation)
|
|
106
|
+
sql_type = process_types(typ)[0]
|
|
107
|
+
if not nullable:
|
|
108
|
+
sql_type = sql_type.replace('NULL', 'NOT NULL')
|
|
109
|
+
out.append(sql_type)
|
|
110
|
+
names.append(name)
|
|
111
|
+
return out, names
|
|
112
|
+
|
|
113
|
+
elif params in python_type_map:
|
|
114
|
+
return python_type_map[params](), []
|
|
115
|
+
|
|
116
|
+
elif callable(params):
|
|
117
|
+
return params(), []
|
|
118
|
+
|
|
119
|
+
elif isinstance(params, str):
|
|
120
|
+
return params, []
|
|
121
|
+
|
|
122
|
+
raise TypeError(f'unrecognized data type for args: {params}')
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def _func(
|
|
126
|
+
func: Optional[Callable[..., Any]] = None,
|
|
127
|
+
*,
|
|
128
|
+
name: Optional[str] = None,
|
|
129
|
+
args: Optional[
|
|
130
|
+
Union[
|
|
131
|
+
DataType,
|
|
132
|
+
List[DataType],
|
|
133
|
+
Dict[str, DataType],
|
|
134
|
+
'pydantic.BaseModel',
|
|
135
|
+
type,
|
|
136
|
+
]
|
|
137
|
+
] = None,
|
|
138
|
+
returns: Optional[
|
|
139
|
+
Union[
|
|
140
|
+
str,
|
|
141
|
+
List[DataType],
|
|
142
|
+
List[type],
|
|
143
|
+
'pydantic.BaseModel',
|
|
144
|
+
type,
|
|
145
|
+
]
|
|
146
|
+
] = None,
|
|
147
|
+
data_format: Optional[str] = None,
|
|
148
|
+
include_masks: bool = False,
|
|
149
|
+
function_type: str = 'udf',
|
|
150
|
+
output_fields: Optional[List[str]] = None,
|
|
151
|
+
) -> Callable[..., Any]:
|
|
152
|
+
"""Generic wrapper for UDF and TVF decorators."""
|
|
153
|
+
args, _ = process_types(args)
|
|
154
|
+
returns, fields = process_types(returns)
|
|
155
|
+
|
|
156
|
+
if not output_fields and fields:
|
|
157
|
+
output_fields = fields
|
|
158
|
+
|
|
159
|
+
if isinstance(returns, list) \
|
|
160
|
+
and isinstance(output_fields, list) \
|
|
161
|
+
and len(output_fields) != len(returns):
|
|
162
|
+
raise ValueError(
|
|
163
|
+
'The number of output fields must match the number of return types',
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
if include_masks and data_format == 'python':
|
|
167
|
+
raise RuntimeError(
|
|
168
|
+
'include_masks is only valid when using '
|
|
169
|
+
'vectors for input parameters',
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
_singlestoredb_attrs = { # type: ignore
|
|
173
|
+
k: v for k, v in dict(
|
|
174
|
+
name=name,
|
|
175
|
+
args=args,
|
|
176
|
+
returns=returns,
|
|
177
|
+
data_format=data_format,
|
|
178
|
+
include_masks=include_masks,
|
|
179
|
+
function_type=function_type,
|
|
180
|
+
output_fields=output_fields or None,
|
|
181
|
+
).items() if v is not None
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
# No func was specified, this is an uncalled decorator that will get
|
|
185
|
+
# called later, so the wrapper much be created with the func passed
|
|
186
|
+
# in at that time.
|
|
187
|
+
if func is None:
|
|
188
|
+
def decorate(func: Callable[..., Any]) -> Callable[..., Any]:
|
|
189
|
+
def wrapper(*args: Any, **kwargs: Any) -> Callable[..., Any]:
|
|
190
|
+
return func(*args, **kwargs) # type: ignore
|
|
191
|
+
wrapper._singlestoredb_attrs = _singlestoredb_attrs # type: ignore
|
|
192
|
+
return functools.wraps(func)(wrapper)
|
|
193
|
+
return decorate
|
|
194
|
+
|
|
195
|
+
def wrapper(*args: Any, **kwargs: Any) -> Callable[..., Any]:
|
|
196
|
+
return func(*args, **kwargs) # type: ignore
|
|
197
|
+
|
|
198
|
+
wrapper._singlestoredb_attrs = _singlestoredb_attrs # type: ignore
|
|
199
|
+
|
|
200
|
+
return functools.wraps(func)(wrapper)
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def udf(
|
|
204
|
+
func: Optional[Callable[..., Any]] = None,
|
|
205
|
+
*,
|
|
206
|
+
name: Optional[str] = None,
|
|
207
|
+
args: Optional[Union[DataType, List[DataType], Dict[str, DataType]]] = None,
|
|
208
|
+
returns: Optional[Union[str, List[DataType], List[type]]] = None,
|
|
209
|
+
data_format: Optional[str] = None,
|
|
210
|
+
include_masks: bool = False,
|
|
211
|
+
) -> Callable[..., Any]:
|
|
212
|
+
"""
|
|
213
|
+
Apply attributes to a UDF.
|
|
214
|
+
|
|
215
|
+
Parameters
|
|
216
|
+
----------
|
|
217
|
+
func : callable, optional
|
|
218
|
+
The UDF to apply parameters to
|
|
219
|
+
name : str, optional
|
|
220
|
+
The name to use for the UDF in the database
|
|
221
|
+
args : str | Callable | List[str | Callable] | Dict[str, str | Callable], optional
|
|
222
|
+
Specifies the data types of the function arguments. Typically,
|
|
223
|
+
the function data types are derived from the function parameter
|
|
224
|
+
annotations. These annotations can be overridden. If the function
|
|
225
|
+
takes a single type for all parameters, `args` can be set to a
|
|
226
|
+
SQL string describing all parameters. If the function takes more
|
|
227
|
+
than one parameter and all of the parameters are being manually
|
|
228
|
+
defined, a list of SQL strings may be used (one for each parameter).
|
|
229
|
+
A dictionary of SQL strings may be used to specify a parameter type
|
|
230
|
+
for a subset of parameters; the keys are the names of the
|
|
231
|
+
function parameters. Callables may also be used for datatypes. This
|
|
232
|
+
is primarily for using the functions in the ``dtypes`` module that
|
|
233
|
+
are associated with SQL types with all default options (e.g., ``dt.FLOAT``).
|
|
234
|
+
returns : str, optional
|
|
235
|
+
Specifies the return data type of the function. If not specified,
|
|
236
|
+
the type annotation from the function is used.
|
|
237
|
+
data_format : str, optional
|
|
238
|
+
The data format of each parameter: python, pandas, arrow, polars
|
|
239
|
+
include_masks : bool, optional
|
|
240
|
+
Should boolean masks be included with each input parameter to indicate
|
|
241
|
+
which elements are NULL? This is only used when a input parameters are
|
|
242
|
+
configured to a vector type (numpy, pandas, polars, arrow).
|
|
243
|
+
|
|
244
|
+
Returns
|
|
245
|
+
-------
|
|
246
|
+
Callable
|
|
247
|
+
|
|
248
|
+
"""
|
|
249
|
+
return _func(
|
|
250
|
+
func=func,
|
|
251
|
+
name=name,
|
|
252
|
+
args=args,
|
|
253
|
+
returns=returns,
|
|
254
|
+
data_format=data_format,
|
|
255
|
+
include_masks=include_masks,
|
|
256
|
+
function_type='udf',
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
udf.pandas = functools.partial(udf, data_format='pandas') # type: ignore
|
|
261
|
+
udf.polars = functools.partial(udf, data_format='polars') # type: ignore
|
|
262
|
+
udf.arrow = functools.partial(udf, data_format='arrow') # type: ignore
|
|
263
|
+
udf.numpy = functools.partial(udf, data_format='numpy') # type: ignore
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
def tvf(
|
|
267
|
+
func: Optional[Callable[..., Any]] = None,
|
|
268
|
+
*,
|
|
269
|
+
name: Optional[str] = None,
|
|
270
|
+
args: Optional[Union[DataType, List[DataType], Dict[str, DataType]]] = None,
|
|
271
|
+
returns: Optional[Union[str, List[DataType], List[type]]] = None,
|
|
272
|
+
data_format: Optional[str] = None,
|
|
273
|
+
include_masks: bool = False,
|
|
274
|
+
output_fields: Optional[List[str]] = None,
|
|
275
|
+
) -> Callable[..., Any]:
|
|
276
|
+
"""
|
|
277
|
+
Apply attributes to a TVF.
|
|
278
|
+
|
|
279
|
+
Parameters
|
|
280
|
+
----------
|
|
281
|
+
func : callable, optional
|
|
282
|
+
The TVF to apply parameters to
|
|
283
|
+
name : str, optional
|
|
284
|
+
The name to use for the TVF in the database
|
|
285
|
+
args : str | Callable | List[str | Callable] | Dict[str, str | Callable], optional
|
|
286
|
+
Specifies the data types of the function arguments. Typically,
|
|
287
|
+
the function data types are derived from the function parameter
|
|
288
|
+
annotations. These annotations can be overridden. If the function
|
|
289
|
+
takes a single type for all parameters, `args` can be set to a
|
|
290
|
+
SQL string describing all parameters. If the function takes more
|
|
291
|
+
than one parameter and all of the parameters are being manually
|
|
292
|
+
defined, a list of SQL strings may be used (one for each parameter).
|
|
293
|
+
A dictionary of SQL strings may be used to specify a parameter type
|
|
294
|
+
for a subset of parameters; the keys are the names of the
|
|
295
|
+
function parameters. Callables may also be used for datatypes. This
|
|
296
|
+
is primarily for using the functions in the ``dtypes`` module that
|
|
297
|
+
are associated with SQL types with all default options (e.g., ``dt.FLOAT``).
|
|
298
|
+
returns : str, optional
|
|
299
|
+
Specifies the return data type of the function. If not specified,
|
|
300
|
+
the type annotation from the function is used.
|
|
301
|
+
data_format : str, optional
|
|
302
|
+
The data format of each parameter: python, pandas, arrow, polars
|
|
303
|
+
include_masks : bool, optional
|
|
304
|
+
Should boolean masks be included with each input parameter to indicate
|
|
305
|
+
which elements are NULL? This is only used when a input parameters are
|
|
306
|
+
configured to a vector type (numpy, pandas, polars, arrow).
|
|
307
|
+
output_fields : List[str], optional
|
|
308
|
+
The names of the output fields for the TVF. If not specified, the
|
|
309
|
+
names are generated.
|
|
310
|
+
|
|
311
|
+
Returns
|
|
312
|
+
-------
|
|
313
|
+
Callable
|
|
314
|
+
|
|
315
|
+
"""
|
|
316
|
+
return _func(
|
|
317
|
+
func=func,
|
|
318
|
+
name=name,
|
|
319
|
+
args=args,
|
|
320
|
+
returns=returns,
|
|
321
|
+
data_format=data_format,
|
|
322
|
+
include_masks=include_masks,
|
|
323
|
+
function_type='tvf',
|
|
324
|
+
output_fields=output_fields,
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
tvf.pandas = functools.partial(tvf, data_format='pandas') # type: ignore
|
|
329
|
+
tvf.polars = functools.partial(tvf, data_format='polars') # type: ignore
|
|
330
|
+
tvf.arrow = functools.partial(tvf, data_format='arrow') # type: ignore
|
|
331
|
+
tvf.numpy = functools.partial(tvf, data_format='numpy') # type: ignore
|