singlestoredb 1.0.4__cp38-abi3-macosx_10_9_universal2.whl → 1.2.0__cp38-abi3-macosx_10_9_universal2.whl

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.

Files changed (41) hide show
  1. _singlestoredb_accel.abi3.so +0 -0
  2. singlestoredb/__init__.py +1 -1
  3. singlestoredb/config.py +131 -0
  4. singlestoredb/connection.py +3 -0
  5. singlestoredb/converters.py +390 -0
  6. singlestoredb/functions/dtypes.py +5 -198
  7. singlestoredb/functions/ext/__init__.py +0 -1
  8. singlestoredb/functions/ext/asgi.py +671 -153
  9. singlestoredb/functions/ext/json.py +2 -2
  10. singlestoredb/functions/ext/mmap.py +174 -67
  11. singlestoredb/functions/ext/rowdat_1.py +2 -2
  12. singlestoredb/functions/ext/utils.py +169 -0
  13. singlestoredb/fusion/handler.py +115 -9
  14. singlestoredb/fusion/handlers/stage.py +246 -13
  15. singlestoredb/fusion/handlers/workspace.py +417 -14
  16. singlestoredb/fusion/registry.py +86 -1
  17. singlestoredb/http/connection.py +40 -2
  18. singlestoredb/management/__init__.py +1 -0
  19. singlestoredb/management/organization.py +4 -0
  20. singlestoredb/management/utils.py +2 -2
  21. singlestoredb/management/workspace.py +79 -6
  22. singlestoredb/mysql/connection.py +81 -0
  23. singlestoredb/mysql/constants/EXTENDED_TYPE.py +3 -0
  24. singlestoredb/mysql/constants/FIELD_TYPE.py +16 -0
  25. singlestoredb/mysql/constants/VECTOR_TYPE.py +6 -0
  26. singlestoredb/mysql/cursors.py +177 -4
  27. singlestoredb/mysql/protocol.py +50 -1
  28. singlestoredb/notebook/__init__.py +15 -0
  29. singlestoredb/notebook/_objects.py +212 -0
  30. singlestoredb/tests/test.sql +259 -0
  31. singlestoredb/tests/test_connection.py +1715 -133
  32. singlestoredb/tests/test_ext_func.py +2 -2
  33. singlestoredb/tests/test_ext_func_data.py +1 -1
  34. singlestoredb/utils/dtypes.py +205 -0
  35. singlestoredb/utils/results.py +367 -14
  36. {singlestoredb-1.0.4.dist-info → singlestoredb-1.2.0.dist-info}/METADATA +2 -1
  37. {singlestoredb-1.0.4.dist-info → singlestoredb-1.2.0.dist-info}/RECORD +41 -35
  38. {singlestoredb-1.0.4.dist-info → singlestoredb-1.2.0.dist-info}/LICENSE +0 -0
  39. {singlestoredb-1.0.4.dist-info → singlestoredb-1.2.0.dist-info}/WHEEL +0 -0
  40. {singlestoredb-1.0.4.dist-info → singlestoredb-1.2.0.dist-info}/entry_points.txt +0 -0
  41. {singlestoredb-1.0.4.dist-info → singlestoredb-1.2.0.dist-info}/top_level.txt +0 -0
Binary file
singlestoredb/__init__.py CHANGED
@@ -13,7 +13,7 @@ Examples
13
13
 
14
14
  """
15
15
 
16
- __version__ = '1.0.4'
16
+ __version__ = '1.2.0'
17
17
 
18
18
  from typing import Any
19
19
 
singlestoredb/config.py CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env python
2
2
  """SingleStoreDB package options."""
3
3
  import functools
4
+ import os
4
5
 
5
6
  from . import auth
6
7
  from .utils.config import check_bool # noqa: F401
@@ -214,6 +215,12 @@ register_option(
214
215
  environ='SINGLESTOREDB_TRACK_ENV',
215
216
  )
216
217
 
218
+ register_option(
219
+ 'enable_extended_data_types', 'bool', check_bool, True,
220
+ 'Should extended data types (BSON, vector) be enabled?',
221
+ environ='SINGLESTOREDB_ENABLE_EXTENDED_DATA_TYPES',
222
+ )
223
+
217
224
  register_option(
218
225
  'fusion.enabled', 'bool', check_bool, False,
219
226
  'Should Fusion SQL queries be enabled?',
@@ -230,6 +237,7 @@ register_option(
230
237
  valid_values=[
231
238
  'tuple', 'tuples', 'namedtuple', 'namedtuples',
232
239
  'dict', 'dicts', 'structsequence', 'structsequences',
240
+ 'numpy', 'pandas', 'polars', 'arrow', 'pyarrow',
233
241
  ],
234
242
  ),
235
243
  'tuples',
@@ -266,6 +274,129 @@ register_option(
266
274
  )
267
275
 
268
276
 
277
+ #
278
+ # External function options
279
+ #
280
+ register_option(
281
+ 'external_function.url', 'string', check_str, 'http://localhost:8000/invoke',
282
+ 'Specifies the URL of the external function application.',
283
+ environ=['SINGLESTOREDB_EXT_FUNC_URL'],
284
+ )
285
+
286
+ register_option(
287
+ 'external_function.app_mode', 'string',
288
+ functools.partial(
289
+ check_str,
290
+ valid_values=['remote', 'collocated'],
291
+ ),
292
+ 'remote',
293
+ 'Specifies the mode of operation of the external function application.',
294
+ environ=['SINGLESTOREDB_EXT_FUNC_APP_MODE'],
295
+ )
296
+
297
+ register_option(
298
+ 'external_function.data_format', 'string',
299
+ functools.partial(
300
+ check_str,
301
+ valid_values=['rowdat_1', 'json'],
302
+ ),
303
+ 'rowdat_1',
304
+ 'Specifies the format for the data rows.',
305
+ environ=['SINGLESTOREDB_EXT_FUNC_DATA_FORMAT'],
306
+ )
307
+
308
+ register_option(
309
+ 'external_function.data_version', 'string', check_str, '1.0',
310
+ 'Specifies the version of the data format.',
311
+ environ=['SINGLESTOREDB_EXT_FUNC_DATA_VERSION'],
312
+ )
313
+
314
+ register_option(
315
+ 'external_function.link_name', 'string', check_str, None,
316
+ 'Specifies the link name to use for remote external functions.',
317
+ environ=['SINGLESTOREDB_EXT_FUNC_LINK_NAME'],
318
+ )
319
+
320
+ register_option(
321
+ 'external_function.link_config', 'string', check_str, None,
322
+ 'Specifies the link config in JSON format.',
323
+ environ=['SINGLESTOREDB_EXT_FUNC_LINK_CONFIG'],
324
+ )
325
+
326
+ register_option(
327
+ 'external_function.link_credentials', 'string', check_str, None,
328
+ 'Specifies the link credentials in JSON format.',
329
+ environ=['SINGLESTOREDB_EXT_FUNC_LINK_CREDENTIALS'],
330
+ )
331
+
332
+ register_option(
333
+ 'external_function.replace_existing', 'bool', check_bool, False,
334
+ 'Should existing functions be replaced when registering external functions?',
335
+ environ=['SINGLESTOREDB_EXT_FUNC_REPLACE_EXISTING'],
336
+ )
337
+
338
+ register_option(
339
+ 'external_function.socket_path', 'string', check_str, None,
340
+ 'Specifies the socket path for collocated external functions.',
341
+ environ=['SINGLESTOREDB_EXT_FUNC_SOCKET_PATH'],
342
+ )
343
+
344
+ register_option(
345
+ 'external_function.max_connections', 'int', check_int, 32,
346
+ 'Specifies the maximum connections in a collocated external function ' +
347
+ 'before reusing them.',
348
+ environ=['SINGLESTOREDB_EXT_FUNC_MAX_CONNECTIONS'],
349
+ )
350
+
351
+ register_option(
352
+ 'external_function.process_mode', 'string',
353
+ functools.partial(
354
+ check_str,
355
+ valid_values=['thread', 'subprocess'],
356
+ ),
357
+ 'subprocess',
358
+ 'Specifies the method to use for concurrent handlers in ' +
359
+ 'collocated external functions',
360
+ environ=['SINGLESTOREDB_EXT_FUNC_PROCESS_MODE'],
361
+ )
362
+
363
+ register_option(
364
+ 'external_function.single_thread', 'bool', check_bool, False,
365
+ 'Should the collocated server run in single-thread mode?',
366
+ environ=['SINGLESTOREDB_EXT_FUNC_SINGLE_THREAD'],
367
+ )
368
+
369
+ register_option(
370
+ 'external_function.log_level', 'string',
371
+ functools.partial(
372
+ check_str,
373
+ valid_values=['info', 'debug', 'warning', 'error'],
374
+ ),
375
+ 'info',
376
+ 'Logging level of external function server.',
377
+ environ=['SINGLESTOREDB_EXT_FUNC_LOG_LEVEL'],
378
+ )
379
+
380
+ register_option(
381
+ 'external_function.connection', 'string', check_str,
382
+ os.environ.get('SINGLESTOREDB_URL') or None,
383
+ 'Specifies the connection string for the database to register functions with.',
384
+ environ=['SINGLESTOREDB_EXT_FUNC_CONNECTION'],
385
+ )
386
+
387
+ register_option(
388
+ 'external_function.host', 'string', check_str, '127.0.0.1',
389
+ 'Specifies the host to bind the server to.',
390
+ environ=['SINGLESTOREDB_EXT_FUNC_HOST'],
391
+ )
392
+
393
+ register_option(
394
+ 'external_function.port', 'int', check_int, 8000,
395
+ 'Specifies the port to bind the server to.',
396
+ environ=['SINGLESTOREDB_EXT_FUNC_PORT'],
397
+ )
398
+
399
+
269
400
  #
270
401
  # Debugging options
271
402
  #
@@ -1285,6 +1285,7 @@ def connect(
1285
1285
  inf_as_null: Optional[bool] = None,
1286
1286
  encoding_errors: Optional[str] = None,
1287
1287
  track_env: Optional[bool] = None,
1288
+ enable_extended_data_types: Optional[bool] = None,
1288
1289
  ) -> Connection:
1289
1290
  """
1290
1291
  Return a SingleStoreDB connection.
@@ -1361,6 +1362,8 @@ def connect(
1361
1362
  The error handler name for value decoding errors
1362
1363
  track_env : bool, optional
1363
1364
  Should the connection track the SINGLESTOREDB_URL environment variable?
1365
+ enable_extended_data_types : bool, optional
1366
+ Should extended data types (BSON, vector) be enabled?
1364
1367
 
1365
1368
  Examples
1366
1369
  --------
@@ -2,6 +2,7 @@
2
2
  """Data value conversion utilities."""
3
3
  import datetime
4
4
  import re
5
+ import struct
5
6
  from base64 import b64decode
6
7
  from decimal import Decimal
7
8
  from json import loads as json_loads
@@ -25,7 +26,20 @@ try:
25
26
  except ImportError:
26
27
  has_pygeos = False
27
28
 
29
+ try:
30
+ import numpy
31
+ has_numpy = True
32
+ except ImportError:
33
+ has_numpy = False
34
+
35
+ try:
36
+ import bson
37
+ has_bson = True
38
+ except ImportError:
39
+ has_bson = False
40
+
28
41
 
42
+ # Cache fromisoformat methods if they exist
29
43
  # Cache fromisoformat methods if they exist
30
44
  _dt_datetime_fromisoformat = None
31
45
  if hasattr(datetime.datetime, 'fromisoformat'):
@@ -527,6 +541,369 @@ def geometry_or_none(x: Optional[str]) -> Optional[Any]:
527
541
  return x
528
542
 
529
543
 
544
+ def float32_vector_json_or_none(x: Optional[str]) -> Optional[Any]:
545
+ """
546
+ Covert value to float32 array.
547
+
548
+ Parameters
549
+ ----------
550
+ x : str or None
551
+ JSON array
552
+
553
+ Returns
554
+ -------
555
+ float32 numpy array
556
+ If input value is not None and numpy is installed
557
+ float Python list
558
+ If input value is not None and numpy is not installed
559
+ None
560
+ If input value is None
561
+
562
+ """
563
+ if x is None:
564
+ return None
565
+
566
+ if has_numpy:
567
+ return numpy.array(json_loads(x), dtype=numpy.float32)
568
+
569
+ return map(float, json_loads(x))
570
+
571
+
572
+ def float32_vector_or_none(x: Optional[bytes]) -> Optional[Any]:
573
+ """
574
+ Covert value to float32 array.
575
+
576
+ Parameters
577
+ ----------
578
+ x : bytes or None
579
+ Little-endian block of bytes.
580
+
581
+ Returns
582
+ -------
583
+ float32 numpy array
584
+ If input value is not None and numpy is installed
585
+ float Python list
586
+ If input value is not None and numpy is not installed
587
+ None
588
+ If input value is None
589
+
590
+ """
591
+ if x is None:
592
+ return None
593
+
594
+ if has_numpy:
595
+ return numpy.frombuffer(x, dtype=numpy.float32)
596
+
597
+ return struct.unpack(f'<{len(x)/4}f', x)
598
+
599
+
600
+ def float64_vector_json_or_none(x: Optional[str]) -> Optional[Any]:
601
+ """
602
+ Covert value to float64 array.
603
+
604
+ Parameters
605
+ ----------
606
+ x : str or None
607
+ JSON array
608
+
609
+ Returns
610
+ -------
611
+ float64 numpy array
612
+ If input value is not None and numpy is installed
613
+ float Python list
614
+ If input value is not None and numpy is not installed
615
+ None
616
+ If input value is None
617
+
618
+ """
619
+ if x is None:
620
+ return None
621
+
622
+ if has_numpy:
623
+ return numpy.array(json_loads(x), dtype=numpy.float64)
624
+
625
+ return map(float, json_loads(x))
626
+
627
+
628
+ def float64_vector_or_none(x: Optional[bytes]) -> Optional[Any]:
629
+ """
630
+ Covert value to float64 array.
631
+
632
+ Parameters
633
+ ----------
634
+ x : bytes or None
635
+ JSON array
636
+
637
+ Returns
638
+ -------
639
+ float64 numpy array
640
+ If input value is not None and numpy is installed
641
+ float Python list
642
+ If input value is not None and numpy is not installed
643
+ None
644
+ If input value is None
645
+
646
+ """
647
+ if x is None:
648
+ return None
649
+
650
+ if has_numpy:
651
+ return numpy.frombuffer(x, dtype=numpy.float64)
652
+
653
+ return struct.unpack(f'<{len(x)/8}d', x)
654
+
655
+
656
+ def int8_vector_json_or_none(x: Optional[str]) -> Optional[Any]:
657
+ """
658
+ Covert value to int8 array.
659
+
660
+ Parameters
661
+ ----------
662
+ x : str or None
663
+ JSON array
664
+
665
+ Returns
666
+ -------
667
+ int8 numpy array
668
+ If input value is not None and numpy is installed
669
+ int Python list
670
+ If input value is not None and numpy is not installed
671
+ None
672
+ If input value is None
673
+
674
+ """
675
+ if x is None:
676
+ return None
677
+
678
+ if has_numpy:
679
+ return numpy.array(json_loads(x), dtype=numpy.int8)
680
+
681
+ return map(int, json_loads(x))
682
+
683
+
684
+ def int8_vector_or_none(x: Optional[bytes]) -> Optional[Any]:
685
+ """
686
+ Covert value to int8 array.
687
+
688
+ Parameters
689
+ ----------
690
+ x : bytes or None
691
+ Little-endian block of bytes.
692
+
693
+ Returns
694
+ -------
695
+ int8 numpy array
696
+ If input value is not None and numpy is installed
697
+ int Python list
698
+ If input value is not None and numpy is not installed
699
+ None
700
+ If input value is None
701
+
702
+ """
703
+ if x is None:
704
+ return None
705
+
706
+ if has_numpy:
707
+ return numpy.frombuffer(x, dtype=numpy.int8)
708
+
709
+ return struct.unpack(f'<{len(x)}b', x)
710
+
711
+
712
+ def int16_vector_json_or_none(x: Optional[str]) -> Optional[Any]:
713
+ """
714
+ Covert value to int16 array.
715
+
716
+ Parameters
717
+ ----------
718
+ x : str or None
719
+ JSON array
720
+
721
+ Returns
722
+ -------
723
+ int16 numpy array
724
+ If input value is not None and numpy is installed
725
+ int Python list
726
+ If input value is not None and numpy is not installed
727
+ None
728
+ If input value is None
729
+
730
+ """
731
+ if x is None:
732
+ return None
733
+
734
+ if has_numpy:
735
+ return numpy.array(json_loads(x), dtype=numpy.int16)
736
+
737
+ return map(int, json_loads(x))
738
+
739
+
740
+ def int16_vector_or_none(x: Optional[bytes]) -> Optional[Any]:
741
+ """
742
+ Covert value to int16 array.
743
+
744
+ Parameters
745
+ ----------
746
+ x : bytes or None
747
+ Little-endian block of bytes.
748
+
749
+ Returns
750
+ -------
751
+ int16 numpy array
752
+ If input value is not None and numpy is installed
753
+ int Python list
754
+ If input value is not None and numpy is not installed
755
+ None
756
+ If input value is None
757
+
758
+ """
759
+ if x is None:
760
+ return None
761
+
762
+ if has_numpy:
763
+ return numpy.frombuffer(x, dtype=numpy.int16)
764
+
765
+ return struct.unpack(f'<{len(x)/2}h', x)
766
+
767
+
768
+ def int32_vector_json_or_none(x: Optional[str]) -> Optional[Any]:
769
+ """
770
+ Covert value to int32 array.
771
+
772
+ Parameters
773
+ ----------
774
+ x : str or None
775
+ JSON array
776
+
777
+ Returns
778
+ -------
779
+ int32 numpy array
780
+ If input value is not None and numpy is installed
781
+ int Python list
782
+ If input value is not None and numpy is not installed
783
+ None
784
+ If input value is None
785
+
786
+ """
787
+ if x is None:
788
+ return None
789
+
790
+ if has_numpy:
791
+ return numpy.array(json_loads(x), dtype=numpy.int32)
792
+
793
+ return map(int, json_loads(x))
794
+
795
+
796
+ def int32_vector_or_none(x: Optional[bytes]) -> Optional[Any]:
797
+ """
798
+ Covert value to int32 array.
799
+
800
+ Parameters
801
+ ----------
802
+ x : bytes or None
803
+ Little-endian block of bytes.
804
+
805
+ Returns
806
+ -------
807
+ int32 numpy array
808
+ If input value is not None and numpy is installed
809
+ int Python list
810
+ If input value is not None and numpy is not installed
811
+ None
812
+ If input value is None
813
+
814
+ """
815
+ if x is None:
816
+ return None
817
+
818
+ if has_numpy:
819
+ return numpy.frombuffer(x, dtype=numpy.int32)
820
+
821
+ return struct.unpack(f'<{len(x)/4}l', x)
822
+
823
+
824
+ def int64_vector_json_or_none(x: Optional[str]) -> Optional[Any]:
825
+ """
826
+ Covert value to int64 array.
827
+
828
+ Parameters
829
+ ----------
830
+ x : str or None
831
+ JSON array
832
+
833
+ Returns
834
+ -------
835
+ int64 numpy array
836
+ If input value is not None and numpy is installed
837
+ int Python list
838
+ If input value is not None and numpy is not installed
839
+ None
840
+ If input value is None
841
+
842
+ """
843
+ if x is None:
844
+ return None
845
+
846
+ if has_numpy:
847
+ return numpy.array(json_loads(x), dtype=numpy.int64)
848
+
849
+ return map(int, json_loads(x))
850
+
851
+
852
+ def int64_vector_or_none(x: Optional[bytes]) -> Optional[Any]:
853
+ """
854
+ Covert value to int64 array.
855
+
856
+ Parameters
857
+ ----------
858
+ x : bytes or None
859
+ Little-endian block of bytes.
860
+
861
+ Returns
862
+ -------
863
+ int64 numpy array
864
+ If input value is not None and numpy is installed
865
+ int Python list
866
+ If input value is not None and numpy is not installed
867
+ None
868
+ If input value is None
869
+
870
+ """
871
+ if x is None:
872
+ return None
873
+
874
+ # Bytes
875
+ if has_numpy:
876
+ return numpy.frombuffer(x, dtype=numpy.int64)
877
+
878
+ return struct.unpack(f'<{len(x)/8}l', x)
879
+
880
+
881
+ def bson_or_none(x: Optional[bytes]) -> Optional[Any]:
882
+ """
883
+ Convert a BSON value to a dictionary.
884
+
885
+ Parameters
886
+ ----------
887
+ x : bytes or None
888
+ BSON formatted bytes
889
+
890
+ Returns
891
+ -------
892
+ dict
893
+ If input value is not None and bson package is installed
894
+ bytes
895
+ If input value is not None and bson package is not installed
896
+ None
897
+ If input value is None
898
+
899
+ """
900
+ if x is None:
901
+ return None
902
+ if has_bson:
903
+ return bson.decode(x)
904
+ return x
905
+
906
+
530
907
  # Map of database types and conversion functions
531
908
  converters: Dict[int, Callable[..., Any]] = {
532
909
  0: decimal_or_none,
@@ -557,4 +934,17 @@ converters: Dict[int, Callable[..., Any]] = {
557
934
  # 253: identity,
558
935
  # 254: identity,
559
936
  255: geometry_or_none,
937
+ 1001: bson_or_none,
938
+ 2001: float32_vector_json_or_none,
939
+ 2002: float64_vector_json_or_none,
940
+ 2003: int8_vector_json_or_none,
941
+ 2004: int16_vector_json_or_none,
942
+ 2005: int32_vector_json_or_none,
943
+ 2006: int64_vector_json_or_none,
944
+ 3001: float32_vector_or_none,
945
+ 3002: float64_vector_or_none,
946
+ 3003: int8_vector_or_none,
947
+ 3004: int16_vector_or_none,
948
+ 3005: int32_vector_or_none,
949
+ 3006: int64_vector_or_none,
560
950
  }