singlestoredb 0.9.1__cp36-abi3-win_amd64.whl → 0.9.3__cp36-abi3-win_amd64.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.

@@ -41,6 +41,7 @@ except ImportError:
41
41
  has_shapely = False
42
42
 
43
43
  from .. import connection
44
+ from .. import fusion
44
45
  from .. import types
45
46
  from ..config import get_option
46
47
  from ..converters import converters
@@ -56,6 +57,7 @@ from ..exceptions import ProgrammingError
56
57
  from ..exceptions import Warning # noqa: F401
57
58
  from ..utils.convert_rows import convert_rows
58
59
  from ..utils.debug import log_query
60
+ from ..utils.mogrify import mogrify
59
61
  from ..utils.results import Description
60
62
  from ..utils.results import format_results
61
63
  from ..utils.results import Result
@@ -431,16 +433,79 @@ class Cursor(connection.Cursor):
431
433
  else:
432
434
  query = query % args
433
435
 
436
+ def _execute_fusion_query(
437
+ self,
438
+ oper: Union[str, bytes],
439
+ params: Optional[Union[Sequence[Any], Dict[str, Any]]] = None,
440
+ handler: Any = None,
441
+ ) -> int:
442
+ oper = mogrify(oper, params)
443
+
444
+ if isinstance(oper, bytes):
445
+ oper = oper.decode('utf-8')
446
+
447
+ log_query(oper, None)
448
+
449
+ results_type = self._results_type
450
+ self._results_type = 'tuples'
451
+ try:
452
+ mgmt_res = fusion.execute(
453
+ self._connection, # type: ignore
454
+ oper,
455
+ handler=handler,
456
+ )
457
+ finally:
458
+ self._results_type = results_type
459
+
460
+ self._descriptions.append(list(mgmt_res.description))
461
+ self._results.append(list(mgmt_res.rows))
462
+ self.rowcount = len(self._results[-1])
463
+
464
+ pymy_res = PyMyResult()
465
+ for field in mgmt_res.fields:
466
+ pymy_res.append(
467
+ PyMyField(
468
+ field.name,
469
+ field.flags,
470
+ field.charsetnr,
471
+ ),
472
+ )
473
+
474
+ self._pymy_results.append(pymy_res)
475
+
476
+ if self._results and self._results[0]:
477
+ self._row_idx = 0
478
+ self._result_idx = 0
479
+
480
+ return self.rowcount
481
+
434
482
  def _execute(
435
483
  self, oper: str,
436
484
  params: Optional[Union[Sequence[Any], Dict[str, Any]]] = None,
437
485
  is_callproc: bool = False,
438
486
  ) -> int:
487
+ self._descriptions = []
488
+ self._results = []
489
+ self._pymy_results = []
490
+ self._row_idx = -1
491
+ self._result_idx = -1
492
+ self.rowcount = 0
493
+ self._expect_results = False
494
+
439
495
  if self._connection is None:
440
496
  raise ProgrammingError(errno=2048, msg='Connection is closed.')
441
497
 
498
+ sql_type = 'exec'
499
+ if re.match(r'^\s*(select|show|call|echo|describe|with)\s+', oper, flags=re.I):
500
+ self._expect_results = True
501
+ sql_type = 'query'
502
+
442
503
  self._validate_param_subs(oper, params)
443
504
 
505
+ handler = fusion.get_handler(oper)
506
+ if handler is not None:
507
+ return self._execute_fusion_query(oper, params, handler=handler)
508
+
444
509
  oper, params = self._connection._convert_params(oper, params)
445
510
 
446
511
  log_query(oper, params)
@@ -455,12 +520,6 @@ class Cursor(connection.Cursor):
455
520
  if self._connection._database:
456
521
  data['database'] = self._connection._database
457
522
 
458
- self._expect_results = False
459
- sql_type = 'exec'
460
- if re.match(r'^\s*(select|show|call|echo|describe|with)\s+', oper, flags=re.I):
461
- self._expect_results = True
462
- sql_type = 'query'
463
-
464
523
  if sql_type == 'query':
465
524
  res = self._post('query/tuples', json=data)
466
525
  else:
@@ -479,18 +538,12 @@ class Cursor(connection.Cursor):
479
538
 
480
539
  out = json.loads(res.text)
481
540
 
482
- self._descriptions = []
483
- self._results = []
484
- self._row_idx = -1
485
- self._result_idx = -1
486
- self.rowcount = 0
487
-
488
541
  if sql_type == 'query':
489
542
  # description: (name, type_code, display_size, internal_size,
490
543
  # precision, scale, null_ok, column_flags, charset)
491
544
 
492
545
  # Remove converters for things the JSON parser already converted
493
- http_converters = dict(converters)
546
+ http_converters = dict(self._connection.decoders)
494
547
  http_converters.pop(4, None)
495
548
  http_converters.pop(5, None)
496
549
  http_converters.pop(6, None)
@@ -902,6 +955,9 @@ class Connection(connection.Connection):
902
955
  version = kwargs.get('version', 'v2')
903
956
  self.driver = kwargs.get('driver', 'https')
904
957
 
958
+ self.encoders = {k: v for (k, v) in converters.items() if type(k) is not int}
959
+ self.decoders = {k: v for (k, v) in converters.items() if type(k) is int}
960
+
905
961
  self._database = kwargs.get('database', get_option('database'))
906
962
  self._url = f'{self.driver}://{host}:{port}/api/{version}/'
907
963
  self._messages: List[Tuple[int, str]] = []
@@ -1389,7 +1389,7 @@ class WorkspaceManager(Manager):
1389
1389
  'workspaceGroups', json=dict(
1390
1390
  name=name, regionID=region,
1391
1391
  adminPassword=admin_password,
1392
- firewallRanges=firewall_ranges,
1392
+ firewallRanges=firewall_ranges or [],
1393
1393
  expiresAt=expires_at,
1394
1394
  allowAllTraffic=allow_all_traffic,
1395
1395
  updateWindow=update_window,
@@ -47,6 +47,7 @@ from .protocol import (
47
47
  )
48
48
  from . import err
49
49
  from ..config import get_option
50
+ from .. import fusion
50
51
  from ..connection import Connection as BaseConnection
51
52
 
52
53
  try:
@@ -758,10 +759,15 @@ class Connection(BaseConnection):
758
759
  """
759
760
  # if DEBUG:
760
761
  # print("DEBUG: sending query:", sql)
761
- if isinstance(sql, str):
762
- sql = sql.encode(self.encoding, 'surrogateescape')
763
- self._execute_command(COMMAND.COM_QUERY, sql)
764
- self._affected_rows = self._read_query_result(unbuffered=unbuffered)
762
+ handler = fusion.get_handler(sql)
763
+ if handler is not None:
764
+ self._result = fusion.execute(self, sql, handler=handler)
765
+ self._affected_rows = self._result.affected_rows
766
+ else:
767
+ if isinstance(sql, str):
768
+ sql = sql.encode(self.encoding, 'surrogateescape')
769
+ self._execute_command(COMMAND.COM_QUERY, sql)
770
+ self._affected_rows = self._read_query_result(unbuffered=unbuffered)
765
771
  return self._affected_rows
766
772
 
767
773
  def next_result(self, unbuffered=False):
@@ -29,3 +29,4 @@ GEOMETRY = 255
29
29
 
30
30
  CHAR = TINY
31
31
  INTERVAL = ENUM
32
+ BOOL = TINY
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env python
2
+ # type: ignore
3
+ """SingleStoreDB Fusion testing."""
4
+ import os
5
+ import unittest
6
+
7
+ import singlestoredb as s2
8
+ from singlestoredb.tests import utils
9
+
10
+
11
+ class TestFusion(unittest.TestCase):
12
+
13
+ dbname: str = ''
14
+ dbexisted: bool = False
15
+
16
+ @classmethod
17
+ def setUpClass(cls):
18
+ sql_file = os.path.join(os.path.dirname(__file__), 'test.sql')
19
+ cls.dbname, cls.dbexisted = utils.load_sql(sql_file)
20
+
21
+ @classmethod
22
+ def tearDownClass(cls):
23
+ if not cls.dbexisted:
24
+ utils.drop_database(cls.dbname)
25
+
26
+ def setUp(self):
27
+ self.enabled = os.environ.get('SINGLESTOREDB_ENABLE_FUSION')
28
+ os.environ['SINGLESTOREDB_ENABLE_FUSION'] = '1'
29
+ self.conn = s2.connect(database=type(self).dbname, local_infile=True)
30
+ self.cur = self.conn.cursor()
31
+
32
+ def tearDown(self):
33
+ if self.enabled:
34
+ os.environ['SINGLESTOREDB_ENABLE_FUSION'] = self.enabled
35
+ else:
36
+ del os.environ['SINGLESTOREDB_ENABLE_FUSION']
37
+
38
+ try:
39
+ if self.cur is not None:
40
+ self.cur.close()
41
+ except Exception:
42
+ # traceback.print_exc()
43
+ pass
44
+
45
+ try:
46
+ if self.conn is not None:
47
+ self.conn.close()
48
+ except Exception:
49
+ # traceback.print_exc()
50
+ pass
51
+
52
+ def test_env_var(self):
53
+ os.environ['SINGLESTOREDB_ENABLE_FUSION'] = '0'
54
+
55
+ with self.assertRaises(s2.ProgrammingError):
56
+ self.cur.execute('show fusion commands')
57
+
58
+ del os.environ['SINGLESTOREDB_ENABLE_FUSION']
59
+
60
+ with self.assertRaises(s2.ProgrammingError):
61
+ self.cur.execute('show fusion commands')
62
+
63
+ os.environ['SINGLESTOREDB_ENABLE_FUSION'] = 'yes'
64
+
65
+ self.cur.execute('show fusion commands')
66
+ assert list(self.cur)
67
+
68
+ def test_show_commands(self):
69
+ self.cur.execute('show fusion commands')
70
+ cmds = [x[0] for x in self.cur.fetchall()]
71
+ assert cmds
72
+ assert [x for x in cmds if x.strip().startswith('SHOW FUSION GRAMMAR')], cmds
73
+
74
+ self.cur.execute('show fusion commands like "create%"')
75
+ cmds = [x[0] for x in self.cur.fetchall()]
76
+ assert cmds
77
+ assert [x for x in cmds if x.strip().startswith('CREATE')] == cmds, cmds
78
+
79
+ def test_show_grammar(self):
80
+ self.cur.execute('show fusion grammar for "create workspace"')
81
+ cmds = [x[0] for x in self.cur.fetchall()]
82
+ assert cmds
83
+ assert [x for x in cmds if x.strip().startswith('CREATE WORKSPACE')], cmds
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env python
2
2
  # type: ignore
3
- """SingleStoreDB HTTP connection testing."""
3
+ """SingleStoreDB Management API testing."""
4
4
  import os
5
5
  import pathlib
6
6
  import random
@@ -51,7 +51,7 @@ class TestResults(unittest.TestCase):
51
51
  with conn.cursor() as cur:
52
52
  cur.execute('select * from data')
53
53
  out = cur.fetchone()
54
- assert type(out) == tuple, type(out)
54
+ assert type(out) is tuple, type(out)
55
55
  assert len(out) == 3, len(out)
56
56
  cur.fetchall()
57
57
 
@@ -59,7 +59,7 @@ class TestResults(unittest.TestCase):
59
59
  out = cur.fetchall()
60
60
  assert len(out) == 5, len(out)
61
61
  assert len(out[0]) == 3, len(out[0])
62
- assert type(out[0]) == tuple, type(out[0])
62
+ assert type(out[0]) is tuple, type(out[0])
63
63
  assert sorted(out) == sorted([
64
64
  ('a', 'antelopes', 2),
65
65
  ('b', 'bears', 2),
@@ -111,13 +111,13 @@ class TestResults(unittest.TestCase):
111
111
  with conn.cursor() as cur:
112
112
  cur.execute('select * from data')
113
113
  out = cur.fetchone()
114
- assert type(out) == dict, type(out)
114
+ assert type(out) is dict, type(out)
115
115
  assert len(out) == 3, len(out)
116
116
  cur.fetchall()
117
117
 
118
118
  cur.execute('select * from data')
119
119
  out = cur.fetchall()
120
- assert type(out[0]) == dict, type(out[0])
120
+ assert type(out[0]) is dict, type(out[0])
121
121
  assert len(out) == 5, len(out)
122
122
  assert len(out[0]) == 3, len(out[0])
123
123
  assert sorted(out, key=lambda x: x['id']) == sorted(
@@ -139,13 +139,13 @@ class TestResults(unittest.TestCase):
139
139
  with conn.cursor() as cur:
140
140
  cur.execute('select * from data')
141
141
  out = cur.fetchone()
142
- assert type(out) == pd.DataFrame, type(out)
142
+ assert type(out) is pd.DataFrame, type(out)
143
143
  assert len(out) == 1, len(out)
144
144
  cur.fetchall()
145
145
 
146
146
  cur.execute('select * from data')
147
147
  out = cur.fetchall()
148
- assert type(out) == pd.DataFrame, type(out)
148
+ assert type(out) is pd.DataFrame, type(out)
149
149
  assert len(out) == 5, len(out)
150
150
  out = out.sort_values('id').reset_index(drop=True)
151
151
  exp = pd.DataFrame(
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env python3
2
+ from typing import Any
3
+ from typing import Dict
4
+ from typing import Optional
5
+ from typing import Sequence
6
+ from typing import Union
7
+
8
+ from ..mysql import converters
9
+ from ..mysql.constants import SERVER_STATUS
10
+
11
+
12
+ Encoders = converters.Encoders
13
+
14
+
15
+ def escape(
16
+ obj: Any,
17
+ charset: str = 'utf8',
18
+ mapping: Optional[Encoders] = None,
19
+ server_status: int = 0,
20
+ binary_prefix: bool = False,
21
+ ) -> str:
22
+ """
23
+ Escape whatever value is passed.
24
+
25
+ Non-standard, for internal use; do not use this in your applications.
26
+
27
+ """
28
+ dtype = type(obj)
29
+ if dtype is str or isinstance(obj, str):
30
+ return "'{}'".format(escape_string(obj, server_status=server_status))
31
+ if dtype is bytes or dtype is bytearray or isinstance(obj, (bytes, bytearray)):
32
+ return _quote_bytes(
33
+ obj,
34
+ server_status=server_status,
35
+ binary_prefix=binary_prefix,
36
+ )
37
+ if mapping is None:
38
+ mapping = converters.encoders
39
+ return converters.escape_item(obj, charset, mapping=mapping)
40
+
41
+
42
+ def literal(
43
+ obj: Any,
44
+ charset: str = 'utf8',
45
+ encoders: Optional[Encoders] = None,
46
+ server_status: int = 0,
47
+ binary_prefix: bool = False,
48
+ ) -> str:
49
+ """
50
+ Alias for escape().
51
+
52
+ Non-standard, for internal use; do not use this in your applications.
53
+
54
+ """
55
+ return escape(
56
+ obj, charset=charset, mapping=encoders,
57
+ server_status=server_status, binary_prefix=binary_prefix,
58
+ )
59
+
60
+
61
+ def escape_string(
62
+ s: str,
63
+ server_status: int = 0,
64
+ ) -> str:
65
+ """Escape a string value."""
66
+ if server_status & SERVER_STATUS.SERVER_STATUS_NO_BACKSLASH_ESCAPES:
67
+ return s.replace("'", "''")
68
+ return converters.escape_string(s)
69
+
70
+
71
+ def _quote_bytes(
72
+ s: bytes,
73
+ server_status: int = 0,
74
+ binary_prefix: bool = False,
75
+ ) -> str:
76
+ if server_status & SERVER_STATUS.SERVER_STATUS_NO_BACKSLASH_ESCAPES:
77
+ if binary_prefix:
78
+ return "_binary X'{}'".format(s.hex())
79
+ return "X'{}'".format(s.hex())
80
+ return converters.escape_bytes(s)
81
+
82
+
83
+ def _escape_args(
84
+ args: Union[Sequence[Any], Dict[str, Any], None],
85
+ charset: str = 'utf8',
86
+ encoders: Optional[Encoders] = None,
87
+ server_status: int = 0,
88
+ binary_prefix: bool = False,
89
+ ) -> Any:
90
+ if encoders is None:
91
+ encoders = converters.encoders
92
+
93
+ if isinstance(args, (tuple, list)):
94
+ return tuple(
95
+ literal(
96
+ arg, charset=charset, encoders=encoders,
97
+ server_status=server_status,
98
+ binary_prefix=binary_prefix,
99
+ ) for arg in args
100
+ )
101
+
102
+ elif isinstance(args, dict):
103
+ return {
104
+ key: literal(
105
+ val, charset=charset, encoders=encoders,
106
+ server_status=server_status,
107
+ binary_prefix=binary_prefix,
108
+ ) for (key, val) in args.items()
109
+ }
110
+
111
+ # If it's not a dictionary let's try escaping it anyways.
112
+ # Worst case it will throw a Value error
113
+ return escape(
114
+ args, charset=charset, mapping=encoders,
115
+ server_status=server_status, binary_prefix=binary_prefix,
116
+ )
117
+
118
+
119
+ def mogrify(
120
+ query: Union[str, bytes],
121
+ args: Union[Sequence[Any], Dict[str, Any], None] = None,
122
+ charset: str = 'utf8',
123
+ encoders: Optional[Encoders] = None,
124
+ server_status: int = 0,
125
+ binary_prefix: bool = False,
126
+ ) -> Union[str, bytes]:
127
+ """
128
+ Returns the exact string sent to the database by calling the execute() method.
129
+
130
+ This method follows the extension to the DB API 2.0 followed by Psycopg.
131
+
132
+ Parameters
133
+ ----------
134
+ query : str
135
+ Query to mogrify.
136
+ args : Sequence[Any] or Dict[str, Any] or Any, optional
137
+ Parameters used with query. (optional)
138
+
139
+ Returns
140
+ -------
141
+ str : The query with argument binding applied.
142
+
143
+ """
144
+ if args:
145
+ query = query % _escape_args(
146
+ args, charset=charset,
147
+ encoders=encoders,
148
+ server_status=server_status,
149
+ binary_prefix=binary_prefix,
150
+ )
151
+ return query
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: singlestoredb
3
- Version: 0.9.1
3
+ Version: 0.9.3
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
@@ -16,6 +16,7 @@ Description-Content-Type: text/markdown
16
16
  License-File: LICENSE
17
17
  Requires-Dist: PyJWT
18
18
  Requires-Dist: build
19
+ Requires-Dist: parsimonious
19
20
  Requires-Dist: requests
20
21
  Requires-Dist: sqlparams
21
22
  Requires-Dist: wheel
@@ -1,5 +1,5 @@
1
- _singlestoredb_accel.pyd,sha256=0Sl7n7G6TXYuXZKn0_Di5V-fUR2HT-hG4eMOdPs5WoQ,37376
2
- singlestoredb/__init__.py,sha256=fakJQ_cRNOiv9DB0CNIJISqTvBGY7hZV8klG2CfFRHo,909
1
+ _singlestoredb_accel.pyd,sha256=oVCTUXoHbcAJhDASVeczCSA1-hWY33z8jk1M7AlvKxI,37376
2
+ singlestoredb/__init__.py,sha256=uPSaY4xDxpO0orU6aqssT93B24ItTyVzGvhv4tgZSOc,909
3
3
  singlestoredb/auth.py,sha256=RmYiH0Wlc2RXc4pTlRMysxtBI445ggCIwojWKC_eDLE,7844
4
4
  singlestoredb/config.py,sha256=-n8HA5_KlwFxcOnfqnLobDbIA43sMlLiVr-YmvtG3a0,7397
5
5
  singlestoredb/connection.py,sha256=XeuKeM0ihbF1QIlDn2AxnJfT5d-RNCch56q0z3dn9g8,45409
@@ -15,8 +15,14 @@ singlestoredb/functions/ext/__init__.py,sha256=NrwbyL86NeG_Kv1N23R4VwL1Ap-pY9Z1B
15
15
  singlestoredb/functions/ext/asgi.py,sha256=LFrcZL2R7sgXflWqx-wcCYRIlivywqBg1joDrGUplSg,11319
16
16
  singlestoredb/functions/ext/json.py,sha256=7dncClZrC1X42GbKzVgV5jgExdbI7GQq0BGSDB9NuTM,1107
17
17
  singlestoredb/functions/ext/rowdat_1.py,sha256=70KSVL7E2842uMWOa-pygbLFd8GyZqOviEFwFacadDs,3296
18
+ singlestoredb/fusion/__init__.py,sha256=FHWtrg6OJFTf6Ye197V5sU6ssryr2h6FBcDIgXP7-H4,367
19
+ singlestoredb/fusion/handler.py,sha256=bJRJFX-j70J3aSfAaeX38AkfV_WlwL-wWU--T5JBYjc,16725
20
+ singlestoredb/fusion/registry.py,sha256=0suBgQ87A85sCZWGWlzBoIIZxbcL18wnrt280w01qJU,4433
21
+ singlestoredb/fusion/result.py,sha256=K5WOm4_COuWXo-YxL0wjodfLhjO_X5Fdp34TrX9_FZI,4019
22
+ singlestoredb/fusion/handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
+ singlestoredb/fusion/handlers/workspace.py,sha256=PLxIM0747WN7tbQ_QMxQG_YvSSL_UqCoijMFwH2xfuA,10893
18
24
  singlestoredb/http/__init__.py,sha256=4cEDvLloGc3LSpU-PnIwacyu0n5oIIIE6xk2SPyWD_w,939
19
- singlestoredb/http/connection.py,sha256=I3m_xT7jKbEkfU05j3xOB2JZbXapAjDeup-7b0pxGdQ,33515
25
+ singlestoredb/http/connection.py,sha256=uVbHgjcU28uHf4sMpJD8UIqzcFVPmJQAcE_ikDTr_GQ,35259
20
26
  singlestoredb/management/__init__.py,sha256=pRxBjzZxNjnuAtBlv4WwYZF-2Z3dbrKoy5XilJRXT2w,102
21
27
  singlestoredb/management/billing_usage.py,sha256=0UHFSPCrN0nyeGFFM-HXS3NP8pYmYo2BCCahDEPXvzg,3883
22
28
  singlestoredb/management/cluster.py,sha256=dqozXaM8kneKTFlUg92gjw6oIT6sPsoYWwJ8aefsVCo,14611
@@ -24,11 +30,11 @@ singlestoredb/management/manager.py,sha256=6-fKCB-3biMFQqk1fQtI5ZiYcX2pKMs0jD0sB
24
30
  singlestoredb/management/organization.py,sha256=iz5Mde0lat3EYLpwNDbnS0ytI33O6tG6-wYDL4-TGdM,2200
25
31
  singlestoredb/management/region.py,sha256=oGoLLS88dE1GmY7GCc0BV7X3f7bWwKQyeXOVBFmK9Pk,1678
26
32
  singlestoredb/management/utils.py,sha256=wAJaLRm7B7urG6MDkALZXxVa-kKmidXQk_-ezuppv5U,6270
27
- singlestoredb/management/workspace.py,sha256=CuwLwqY5PIQIONne3XiycEzXwToOJ3U_q5D1y3TkiKc,47132
33
+ singlestoredb/management/workspace.py,sha256=yEI0epRCBLtWTnHLDO8WhHnsYrLpC4CLjHvwf-z9gNs,47138
28
34
  singlestoredb/mysql/__init__.py,sha256=CbpwzNUJPAmKPpIobC0-ugBta_RgHCMq7X7N75QLReY,4669
29
35
  singlestoredb/mysql/_auth.py,sha256=YaqqyvAHmeraBv3BM207rNveUVPM-mPnW20ts_ynVWg,8341
30
36
  singlestoredb/mysql/charset.py,sha256=mnCdMpvdub1S2mm2PSk2j5JddgsWRjsVLtGx-y9TskE,10724
31
- singlestoredb/mysql/connection.py,sha256=jZz7AqKutLe2Bf5H7_fFIsClaH4GrAxwIUab0_KZ7n4,63866
37
+ singlestoredb/mysql/connection.py,sha256=KD7edphkdSy5Ijj0hbpCe4Mmu4MudC2wKtCnRVrlA4A,64129
32
38
  singlestoredb/mysql/converters.py,sha256=vebFFm6IrC0WgY-5Eh-esaPizY5cq3vDOUlEKGaYM-U,7771
33
39
  singlestoredb/mysql/cursors.py,sha256=t3t5-Iq5lOwyh-Qj3jVimEUIrljewHkOPaK01Dl5xsk,21959
34
40
  singlestoredb/mysql/err.py,sha256=aDbmfq08gWVmfgIea735wSeiFdvYbB5wusgd3qTVq1s,2480
@@ -39,7 +45,7 @@ singlestoredb/mysql/constants/CLIENT.py,sha256=hAo5tQqhc1V7t7tdNd4s6TINwYoDHldys
39
45
  singlestoredb/mysql/constants/COMMAND.py,sha256=T81MAx6Vkxf5-86PTk2OtENoXtaFSlEckBzzwrI9uXQ,711
40
46
  singlestoredb/mysql/constants/CR.py,sha256=qCE-3R28NHhkyVwhgwgxQK0XX_bZyGtTlvNa3UWaXv0,2383
41
47
  singlestoredb/mysql/constants/ER.py,sha256=FuZGMUaHPJzXNxcEsQUfQNtVEMYzYUXRvPDJnVOxXyQ,12770
42
- singlestoredb/mysql/constants/FIELD_TYPE.py,sha256=bJNsusotD7U1tvXNjIk_ynQXXepJFlGnYUacJaD26P0,401
48
+ singlestoredb/mysql/constants/FIELD_TYPE.py,sha256=MWFwixlGMvI3tBq0dTknwvoza9krqVS3aZa7EMivZIU,414
43
49
  singlestoredb/mysql/constants/FLAG.py,sha256=CbdDkHclXsvS-NdAvrFhFzby4BAVpvq0tIPOszHAqgA,229
44
50
  singlestoredb/mysql/constants/SERVER_STATUS.py,sha256=W4UYyw1AW0brlgywTBaE6cm6eGq6NBvHK8iCAh2mQhM,343
45
51
  singlestoredb/mysql/constants/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -74,9 +80,10 @@ singlestoredb/tests/test_config.py,sha256=Ad0PDmCnJMOyy9f7WTKiRasSR_3mYRByUlSb7k
74
80
  singlestoredb/tests/test_connection.py,sha256=0GRvsvUz8G2I5ah0lHI97XUVv6UI13A1D5UNHk7RRmc,52215
75
81
  singlestoredb/tests/test_dbapi.py,sha256=cNJoTEZvYG7ckcwT7xqlkJX-2TDEYGTDDU1Igucp48k,679
76
82
  singlestoredb/tests/test_exceptions.py,sha256=vscMYmdOJr0JmkTAJrNI2w0Q96Nfugjkrt5_lYnw8i0,1176
83
+ singlestoredb/tests/test_fusion.py,sha256=g7sLQUJgHRDe48SWDfFPrx0onbh4qAVjQ_sEp8-VGBs,2624
77
84
  singlestoredb/tests/test_http.py,sha256=7hwXe61hlUes3nji0MTTZweo94tJAlJ-vA5ct9geXFQ,8868
78
- singlestoredb/tests/test_management.py,sha256=XSYmKBEyRz_mLRiJyx1ntlK-95ivuQnB9D9j0MeRrWs,26513
79
- singlestoredb/tests/test_results.py,sha256=cyT0dgF3aQ5CSjmzWW_oqJo4JrHmT4UWAl1J41O63rM,6753
85
+ singlestoredb/tests/test_management.py,sha256=jvT38o-nYGmzk260NS8j9Bit2kBv24CSloG3CJmcQVs,26512
86
+ singlestoredb/tests/test_results.py,sha256=Zg1ynZFRZqalAMfNLOU5C6BDXaox6JxrKm_XZwVNFcg,6753
80
87
  singlestoredb/tests/test_types.py,sha256=YeVE6KPqlqzJke-4hbRmc8ko1E7RLHu5S8qLg04Bl5Y,4632
81
88
  singlestoredb/tests/test_udf.py,sha256=6fGNQELY6KKvUUUmi6StTGw-jZUMGrVXTpfZf61bwFw,29562
82
89
  singlestoredb/tests/test_xdict.py,sha256=5ArRJqd5aNXkPK7Y6sFeRbqZ59MZ1YaGBpSlDAbBrjM,10741
@@ -85,10 +92,11 @@ singlestoredb/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
85
92
  singlestoredb/utils/config.py,sha256=WVQ567ZzqzlTGueQH5fEpm5tPZuz8y7qvpEQUB-vPjk,25453
86
93
  singlestoredb/utils/convert_rows.py,sha256=gkZeZazeJvimCYEQ1FdAC-AmMDwmFGCuP6mi653bpns,1885
87
94
  singlestoredb/utils/debug.py,sha256=y7dnJeJGt3U_BWXz9pLt1qNQREpPtumYX_sk1DiqG6Y,362
95
+ singlestoredb/utils/mogrify.py,sha256=gCcn99-vgsGVjTUV7RHJ6hH4vCNrsGB_Xo4z8kiSPDQ,4201
88
96
  singlestoredb/utils/results.py,sha256=ely2XVAHHejObjLibS3UcrPOuCO2g5aRtA3PxAMtE-g,5432
89
97
  singlestoredb/utils/xdict.py,sha256=-wi1lSPTnY99fhVMBhPKJ8cCsQhNG4GMUfkEBDKYgCw,13321
90
- singlestoredb-0.9.1.dist-info/LICENSE,sha256=Bojenzui8aPNjlF3w4ojguDP7sTf8vFV_9Gc2UAG1sg,11542
91
- singlestoredb-0.9.1.dist-info/METADATA,sha256=YGBU-RmVKRzn8jTGodZIDqUQSH2Cby5gwMaUVqoHnrU,7764
92
- singlestoredb-0.9.1.dist-info/WHEEL,sha256=CFPxCuvaTIZS0h5c8o2xFStPFn1i6Rraxc2uR61QpoA,100
93
- singlestoredb-0.9.1.dist-info/top_level.txt,sha256=SDtemIXf-Kp-_F2f_S6x0db33cHGOILdAEsIQZe2LZc,35
94
- singlestoredb-0.9.1.dist-info/RECORD,,
98
+ singlestoredb-0.9.3.dist-info/LICENSE,sha256=Bojenzui8aPNjlF3w4ojguDP7sTf8vFV_9Gc2UAG1sg,11542
99
+ singlestoredb-0.9.3.dist-info/METADATA,sha256=3Kv3yUR-JCqYGCvlmCsSX5MJdhG4lvh8tGpnfetigXI,7793
100
+ singlestoredb-0.9.3.dist-info/WHEEL,sha256=CFPxCuvaTIZS0h5c8o2xFStPFn1i6Rraxc2uR61QpoA,100
101
+ singlestoredb-0.9.3.dist-info/top_level.txt,sha256=SDtemIXf-Kp-_F2f_S6x0db33cHGOILdAEsIQZe2LZc,35
102
+ singlestoredb-0.9.3.dist-info/RECORD,,