pyobvector 0.2.22__py3-none-any.whl → 0.2.24__py3-none-any.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.
Files changed (41) hide show
  1. pyobvector/__init__.py +6 -5
  2. pyobvector/client/__init__.py +5 -4
  3. pyobvector/client/collection_schema.py +5 -1
  4. pyobvector/client/enum.py +1 -1
  5. pyobvector/client/exceptions.py +9 -7
  6. pyobvector/client/fts_index_param.py +8 -4
  7. pyobvector/client/hybrid_search.py +10 -4
  8. pyobvector/client/index_param.py +56 -41
  9. pyobvector/client/milvus_like_client.py +71 -54
  10. pyobvector/client/ob_client.py +20 -16
  11. pyobvector/client/ob_vec_client.py +47 -40
  12. pyobvector/client/ob_vec_json_table_client.py +366 -274
  13. pyobvector/client/partitions.py +81 -39
  14. pyobvector/client/schema_type.py +3 -1
  15. pyobvector/json_table/__init__.py +4 -3
  16. pyobvector/json_table/json_value_returning_func.py +12 -10
  17. pyobvector/json_table/oceanbase_dialect.py +15 -8
  18. pyobvector/json_table/virtual_data_type.py +47 -28
  19. pyobvector/schema/__init__.py +7 -1
  20. pyobvector/schema/array.py +6 -2
  21. pyobvector/schema/dialect.py +4 -0
  22. pyobvector/schema/full_text_index.py +8 -3
  23. pyobvector/schema/geo_srid_point.py +5 -2
  24. pyobvector/schema/gis_func.py +23 -11
  25. pyobvector/schema/match_against_func.py +10 -5
  26. pyobvector/schema/ob_table.py +2 -0
  27. pyobvector/schema/reflection.py +25 -8
  28. pyobvector/schema/replace_stmt.py +4 -0
  29. pyobvector/schema/sparse_vector.py +7 -4
  30. pyobvector/schema/vec_dist_func.py +22 -9
  31. pyobvector/schema/vector.py +3 -1
  32. pyobvector/schema/vector_index.py +7 -3
  33. pyobvector/util/__init__.py +1 -0
  34. pyobvector/util/ob_version.py +2 -0
  35. pyobvector/util/sparse_vector.py +9 -6
  36. pyobvector/util/vector.py +2 -0
  37. {pyobvector-0.2.22.dist-info → pyobvector-0.2.24.dist-info}/METADATA +13 -14
  38. pyobvector-0.2.24.dist-info/RECORD +40 -0
  39. {pyobvector-0.2.22.dist-info → pyobvector-0.2.24.dist-info}/licenses/LICENSE +1 -1
  40. pyobvector-0.2.22.dist-info/RECORD +0 -40
  41. {pyobvector-0.2.22.dist-info → pyobvector-0.2.24.dist-info}/WHEEL +0 -0
@@ -3,7 +3,17 @@ import logging
3
3
  import re
4
4
  from typing import Optional, Union
5
5
 
6
- from sqlalchemy import Column, Integer, String, JSON, Engine, select, text, func, CursorResult
6
+ from sqlalchemy import (
7
+ Column,
8
+ Integer,
9
+ String,
10
+ JSON,
11
+ Engine,
12
+ select,
13
+ text,
14
+ func,
15
+ CursorResult,
16
+ )
7
17
  from sqlalchemy.dialects.mysql import TINYINT
8
18
  from sqlalchemy.orm import declarative_base, sessionmaker, Session
9
19
  from sqlglot import parse_one, exp, Expression, to_identifier
@@ -18,7 +28,7 @@ from ..json_table import (
18
28
  JsonTableDecimalFactory,
19
29
  JsonTableInt,
20
30
  val2json,
21
- json_value
31
+ json_value,
22
32
  )
23
33
 
24
34
  logger = logging.getLogger(__name__)
@@ -27,6 +37,7 @@ logger.setLevel(logging.DEBUG)
27
37
  JSON_TABLE_META_TABLE_NAME = "meta_json_t"
28
38
  JSON_TABLE_DATA_TABLE_NAME = "data_json_t"
29
39
 
40
+
30
41
  class ObVecJsonTableClient(ObVecClient):
31
42
  """OceanBase Vector Store Client with JSON Table."""
32
43
 
@@ -34,7 +45,7 @@ class ObVecJsonTableClient(ObVecClient):
34
45
 
35
46
  class JsonTableMetaTBL(Base):
36
47
  __tablename__ = JSON_TABLE_META_TABLE_NAME
37
-
48
+
38
49
  user_id = Column(String(128), primary_key=True, autoincrement=False)
39
50
  jtable_name = Column(String(512), primary_key=True)
40
51
  jcol_id = Column(Integer, primary_key=True)
@@ -53,33 +64,33 @@ class ObVecJsonTableClient(ObVecClient):
53
64
  jdata_id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
54
65
  jdata = Column(JSON)
55
66
 
56
- class JsonTableMetadata:
67
+ class JsonTableMetadata:
57
68
  def __init__(self, user_id: str):
58
69
  self.user_id = user_id
59
70
  self.meta_cache: dict[str, list] = {}
60
71
 
61
72
  @classmethod
62
73
  def _parse_col_type(cls, col_type: str):
63
- if col_type.startswith('TINYINT'):
74
+ if col_type.startswith("TINYINT"):
64
75
  return JsonTableBool
65
- elif col_type.startswith('TIMESTAMP'):
76
+ elif col_type.startswith("TIMESTAMP"):
66
77
  return JsonTableTimestamp
67
- elif col_type.startswith('INT'):
78
+ elif col_type.startswith("INT"):
68
79
  return JsonTableInt
69
- elif col_type.startswith('VARCHAR'):
70
- if col_type == 'VARCHAR':
80
+ elif col_type.startswith("VARCHAR"):
81
+ if col_type == "VARCHAR":
71
82
  factory = JsonTableVarcharFactory(255)
72
83
  else:
73
- varchar_pattern = r'VARCHAR\s*\((\d+)\)'
84
+ varchar_pattern = r"VARCHAR\s*\((\d+)\)"
74
85
  varchar_matches = re.findall(varchar_pattern, col_type)
75
86
  factory = JsonTableVarcharFactory(int(varchar_matches[0]))
76
87
  model = factory.get_json_table_varchar_type()
77
88
  return model
78
- elif col_type.startswith('DECIMAL'):
79
- if col_type == 'DECIMAL':
89
+ elif col_type.startswith("DECIMAL"):
90
+ if col_type == "DECIMAL":
80
91
  factory = JsonTableDecimalFactory(10, 0)
81
92
  else:
82
- decimal_pattern = r'DECIMAL\s*\((\d+),\s*(\d+)\)'
93
+ decimal_pattern = r"DECIMAL\s*\((\d+),\s*(\d+)\)"
83
94
  decimal_matches = re.findall(decimal_pattern, col_type)
84
95
  x, y = decimal_matches[0]
85
96
  factory = JsonTableDecimalFactory(int(x), int(y))
@@ -98,26 +109,29 @@ class ObVecJsonTableClient(ObVecClient):
98
109
  for r in res:
99
110
  if r[1] not in self.meta_cache:
100
111
  self.meta_cache[r[1]] = []
101
- self.meta_cache[r[1]].append({
102
- 'jcol_id': r[2],
103
- 'jcol_name': r[3],
104
- 'jcol_type': r[4],
105
- 'jcol_nullable': bool(r[5]),
106
- 'jcol_has_default': bool(r[6]),
107
- 'jcol_default': (
108
- r[7]['default']
109
- if isinstance(r[7], dict) else
110
- json.loads(r[7])['default']
111
- ),
112
- 'jcol_model': ObVecJsonTableClient.JsonTableMetadata._parse_col_type(r[4])
113
- })
112
+ self.meta_cache[r[1]].append(
113
+ {
114
+ "jcol_id": r[2],
115
+ "jcol_name": r[3],
116
+ "jcol_type": r[4],
117
+ "jcol_nullable": bool(r[5]),
118
+ "jcol_has_default": bool(r[6]),
119
+ "jcol_default": (
120
+ r[7]["default"]
121
+ if isinstance(r[7], dict)
122
+ else json.loads(r[7])["default"]
123
+ ),
124
+ "jcol_model": ObVecJsonTableClient.JsonTableMetadata._parse_col_type(
125
+ r[4]
126
+ ),
127
+ }
128
+ )
114
129
  for k, _ in self.meta_cache.items():
115
- self.meta_cache[k].sort(key=lambda x: x['jcol_id'])
130
+ self.meta_cache[k].sort(key=lambda x: x["jcol_id"])
116
131
 
117
132
  for k, v in self.meta_cache.items():
118
133
  logger.debug(f"LOAD TABLE --- {k}: {v}")
119
134
 
120
-
121
135
  def __init__(
122
136
  self,
123
137
  user_id: Optional[str],
@@ -137,28 +151,30 @@ class ObVecJsonTableClient(ObVecClient):
137
151
  raise ValueError(f"Invalid admin_id: {admin_id}")
138
152
  self.jmetadata = ObVecJsonTableClient.JsonTableMetadata(self.admin_id)
139
153
  self.jmetadata.reflect(self.engine)
140
-
154
+
141
155
  def check_admin_id_ok(self):
142
156
  if self.user_id is None:
143
157
  return True
144
-
158
+
145
159
  with self.session() as session:
146
160
  with session.begin():
147
161
  distinct_admin_ids = (
148
162
  session.query(ObVecJsonTableClient.JsonTableDataTBL.admin_id)
149
- .filter_by(user_id = self.user_id)
163
+ .filter_by(user_id=self.user_id)
150
164
  .distinct()
151
165
  .all()
152
166
  )
153
167
  admin_ids = [admin_id[0] for admin_id in distinct_admin_ids]
154
- return (len(admin_ids) == 0) or (len(admin_ids) == 1 and admin_ids[0] == self.admin_id)
168
+ return (len(admin_ids) == 0) or (
169
+ len(admin_ids) == 1 and admin_ids[0] == self.admin_id
170
+ )
155
171
 
156
172
  def _reset(self):
157
173
  # Only for test
158
174
  self.perform_raw_text_sql(f"TRUNCATE TABLE {JSON_TABLE_DATA_TABLE_NAME}")
159
175
  self.perform_raw_text_sql(f"TRUNCATE TABLE {JSON_TABLE_META_TABLE_NAME}")
160
176
  self.jmetadata = ObVecJsonTableClient.JsonTableMetadata(self.admin_id)
161
-
177
+
162
178
  def refresh_metadata(self) -> None:
163
179
  self.jmetadata.reflect(self.engine)
164
180
 
@@ -171,7 +187,7 @@ class ObVecJsonTableClient(ObVecClient):
171
187
  """Perform common SQL that operates on JSON Table."""
172
188
  ast = parse_one(sql, dialect="oceanbase")
173
189
  if isinstance(ast, exp.Create):
174
- if ast.kind and ast.kind == 'TABLE':
190
+ if ast.kind and ast.kind == "TABLE":
175
191
  self._handle_create_json_table(ast)
176
192
  else:
177
193
  raise ValueError(f"Create {ast.kind} is not supported")
@@ -192,7 +208,7 @@ class ObVecJsonTableClient(ObVecClient):
192
208
  return self._handle_jtable_dml_select(ast, select_with_data_id, opt_user_id)
193
209
  else:
194
210
  raise ValueError(f"{type(ast)} not supported")
195
-
211
+
196
212
  def _parse_datatype_to_str(self, datatype):
197
213
  if datatype == exp.DataType.Type.INT:
198
214
  return "INT"
@@ -205,7 +221,7 @@ class ObVecJsonTableClient(ObVecClient):
205
221
  if datatype == exp.DataType.Type.DECIMAL:
206
222
  return "DECIMAL"
207
223
  raise ValueError(f"{datatype} not supported")
208
-
224
+
209
225
  def _calc_default_value(self, default_val):
210
226
  if default_val is None:
211
227
  return None
@@ -214,7 +230,7 @@ class ObVecJsonTableClient(ObVecClient):
214
230
  for r in res:
215
231
  logger.debug(f"============== Calculate default value: {r[0]}")
216
232
  return r[0]
217
-
233
+
218
234
  def _handle_create_json_table(self, ast: Expression):
219
235
  logger.debug("HANDLE CREATE JSON TABLE")
220
236
 
@@ -228,11 +244,14 @@ class ObVecJsonTableClient(ObVecClient):
228
244
  raise ValueError("Invalid create table statement")
229
245
  jtable_name = jtable.this.this
230
246
 
231
- if jtable_name == JSON_TABLE_META_TABLE_NAME or jtable_name == JSON_TABLE_DATA_TABLE_NAME:
247
+ if (
248
+ jtable_name == JSON_TABLE_META_TABLE_NAME
249
+ or jtable_name == JSON_TABLE_DATA_TABLE_NAME
250
+ ):
232
251
  raise ValueError(f"Invalid table name: {jtable_name}")
233
252
  if jtable_name in self.jmetadata.meta_cache:
234
253
  raise ValueError("Table name duplicated")
235
-
254
+
236
255
  session = self.session()
237
256
  session.execute(text("SET @@session.autocommit=0"))
238
257
  new_meta_cache_items = []
@@ -251,13 +270,17 @@ class ObVecJsonTableClient(ObVecClient):
251
270
  else:
252
271
  col_type_params_list.append(f"{param.this}")
253
272
  if len(col_type_params_list) > 0:
254
- col_type_str += '(' + ','.join(col_type_params_list) + ')'
255
- col_type_model = ObVecJsonTableClient.JsonTableMetadata._parse_col_type(col_type_str)
256
-
273
+ col_type_str += "(" + ",".join(col_type_params_list) + ")"
274
+ col_type_model = ObVecJsonTableClient.JsonTableMetadata._parse_col_type(
275
+ col_type_str
276
+ )
277
+
257
278
  for cons in col_def.constraints:
258
279
  if isinstance(cons.kind, exp.DefaultColumnConstraint):
259
280
  col_has_default = True
260
- logger.debug(f"############ create jtable ########### {str(cons.kind.this)}")
281
+ logger.debug(
282
+ f"############ create jtable ########### {str(cons.kind.this)}"
283
+ )
261
284
  col_default_val = str(cons.kind.this)
262
285
  if col_default_val.upper() == "NULL":
263
286
  col_default_val = None
@@ -267,7 +290,7 @@ class ObVecJsonTableClient(ObVecClient):
267
290
  pass
268
291
  # raise ValueError(f"{cons.kind} constriaint is not supported.")
269
292
  # TODO support json index
270
-
293
+
271
294
  if col_has_default and (col_default_val is not None):
272
295
  # check default value is valid
273
296
  col_type_model(val=self._calc_default_value(col_default_val))
@@ -280,34 +303,40 @@ class ObVecJsonTableClient(ObVecClient):
280
303
  f"col_type_str={col_type_str}, col_nullable={col_nullable}, "
281
304
  f"col_has_default={col_has_default}, col_default_val={col_default_val}"
282
305
  )
283
- new_meta_cache_items.append({
284
- 'jcol_id': col_id,
285
- 'jcol_name': col_name,
286
- 'jcol_type': col_type_str,
287
- 'jcol_nullable': col_nullable,
288
- 'jcol_has_default': col_has_default,
289
- 'jcol_default': col_default_val,
290
- 'jcol_model': col_type_model,
291
- })
292
- session.add(ObVecJsonTableClient.JsonTableMetaTBL(
293
- user_id = self.admin_id,
294
- jtable_name = jtable_name,
295
- jcol_id = col_id,
296
- jcol_name = col_name,
297
- jcol_type = col_type_str,
298
- jcol_nullable = col_nullable,
299
- jcol_has_default = col_has_default,
300
- jcol_default = {
301
- 'default': col_default_val,
306
+ new_meta_cache_items.append(
307
+ {
308
+ "jcol_id": col_id,
309
+ "jcol_name": col_name,
310
+ "jcol_type": col_type_str,
311
+ "jcol_nullable": col_nullable,
312
+ "jcol_has_default": col_has_default,
313
+ "jcol_default": col_default_val,
314
+ "jcol_model": col_type_model,
302
315
  }
303
- ))
304
-
316
+ )
317
+ session.add(
318
+ ObVecJsonTableClient.JsonTableMetaTBL(
319
+ user_id=self.admin_id,
320
+ jtable_name=jtable_name,
321
+ jcol_id=col_id,
322
+ jcol_name=col_name,
323
+ jcol_type=col_type_str,
324
+ jcol_nullable=col_nullable,
325
+ jcol_has_default=col_has_default,
326
+ jcol_default={
327
+ "default": col_default_val,
328
+ },
329
+ )
330
+ )
331
+
305
332
  col_id += 1
306
-
333
+
307
334
  try:
308
335
  session.commit()
309
336
  self.jmetadata.meta_cache[jtable_name] = new_meta_cache_items
310
- logger.debug(f"ADD METADATA CACHE ---- {jtable_name}: {new_meta_cache_items}")
337
+ logger.debug(
338
+ f"ADD METADATA CACHE ---- {jtable_name}: {new_meta_cache_items}"
339
+ )
311
340
  except Exception as e:
312
341
  session.rollback()
313
342
  logger.error(f"Error occurred: {e}")
@@ -316,15 +345,15 @@ class ObVecJsonTableClient(ObVecClient):
316
345
 
317
346
  def _check_table_exists(self, jtable_name: str) -> bool:
318
347
  return jtable_name in self.jmetadata.meta_cache
319
-
348
+
320
349
  def _check_col_exists(self, jtable_name: str, col_name: str) -> Optional[dict]:
321
350
  if not self._check_table_exists(jtable_name):
322
351
  return None
323
352
  for col_meta in self.jmetadata.meta_cache[jtable_name]:
324
- if col_meta['jcol_name'] == col_name:
353
+ if col_meta["jcol_name"] == col_name:
325
354
  return col_meta
326
355
  return None
327
-
356
+
328
357
  def _parse_col_datatype(self, expr: Expression) -> str:
329
358
  col_type_str = self._parse_datatype_to_str(expr.this)
330
359
  col_type_params_list = []
@@ -334,16 +363,18 @@ class ObVecJsonTableClient(ObVecClient):
334
363
  else:
335
364
  col_type_params_list.append(f"{param.this}")
336
365
  if len(col_type_params_list) > 0:
337
- col_type_str += '(' + ','.join(col_type_params_list) + ')'
366
+ col_type_str += "(" + ",".join(col_type_params_list) + ")"
338
367
  return col_type_str
339
-
368
+
340
369
  def _parse_col_constraints(self, expr: Expression) -> dict:
341
370
  col_has_default = False
342
371
  col_nullable = True
343
372
  for cons in expr:
344
373
  if isinstance(cons.kind, exp.DefaultColumnConstraint):
345
374
  col_has_default = True
346
- logger.debug(f"############ column constraints ########### {str(cons.kind.this)}")
375
+ logger.debug(
376
+ f"############ column constraints ########### {str(cons.kind.this)}"
377
+ )
347
378
  col_default_val = str(cons.kind.this)
348
379
  if col_default_val.upper() == "NULL":
349
380
  col_default_val = None
@@ -352,9 +383,9 @@ class ObVecJsonTableClient(ObVecClient):
352
383
  else:
353
384
  raise ValueError(f"{cons.kind} constriaint is not supported.")
354
385
  return {
355
- 'jcol_nullable': col_nullable,
356
- 'jcol_has_default': col_has_default,
357
- 'jcol_default': col_default_val,
386
+ "jcol_nullable": col_nullable,
387
+ "jcol_has_default": col_has_default,
388
+ "jcol_default": col_default_val,
358
389
  }
359
390
 
360
391
  def _handle_alter_jtable_change_column(
@@ -367,56 +398,60 @@ class ObVecJsonTableClient(ObVecClient):
367
398
  origin_col_name = change_col.origin_col_name.this
368
399
  if not self._check_col_exists(jtable_name, origin_col_name):
369
400
  raise ValueError(f"{origin_col_name} not exists in {jtable_name}")
370
-
401
+
371
402
  new_col_name = change_col.this
372
403
  if self._check_col_exists(jtable_name, new_col_name):
373
404
  raise ValueError(f"Column {new_col_name} exists!")
374
-
405
+
375
406
  col_type_str = self._parse_col_datatype(change_col.dtype)
376
407
 
377
408
  session.query(ObVecJsonTableClient.JsonTableMetaTBL).filter_by(
378
- user_id=self.admin_id,
379
- jtable_name=jtable_name,
380
- jcol_name=origin_col_name
381
- ).update({
382
- ObVecJsonTableClient.JsonTableMetaTBL.jcol_name: new_col_name,
383
- ObVecJsonTableClient.JsonTableMetaTBL.jcol_type: col_type_str,
384
- ObVecJsonTableClient.JsonTableMetaTBL.jcol_nullable: True,
385
- ObVecJsonTableClient.JsonTableMetaTBL.jcol_has_default: True,
386
- ObVecJsonTableClient.JsonTableMetaTBL.jcol_default: {
387
- 'default': None
388
- },
389
- })
409
+ user_id=self.admin_id, jtable_name=jtable_name, jcol_name=origin_col_name
410
+ ).update(
411
+ {
412
+ ObVecJsonTableClient.JsonTableMetaTBL.jcol_name: new_col_name,
413
+ ObVecJsonTableClient.JsonTableMetaTBL.jcol_type: col_type_str,
414
+ ObVecJsonTableClient.JsonTableMetaTBL.jcol_nullable: True,
415
+ ObVecJsonTableClient.JsonTableMetaTBL.jcol_has_default: True,
416
+ ObVecJsonTableClient.JsonTableMetaTBL.jcol_default: {"default": None},
417
+ }
418
+ )
390
419
 
391
420
  session.query(ObVecJsonTableClient.JsonTableDataTBL).filter_by(
392
421
  admin_id=self.admin_id,
393
422
  jtable_name=jtable_name,
394
- ).update({
395
- ObVecJsonTableClient.JsonTableDataTBL.jdata: func.json_insert(
396
- func.json_remove(
397
- ObVecJsonTableClient.JsonTableDataTBL.jdata, f'$.{origin_col_name}'
398
- ),
399
- f'$.{new_col_name}',
400
- func.json_value(
401
- ObVecJsonTableClient.JsonTableDataTBL.jdata, f'$.{origin_col_name}',
402
- ),
403
- )
404
- })
423
+ ).update(
424
+ {
425
+ ObVecJsonTableClient.JsonTableDataTBL.jdata: func.json_insert(
426
+ func.json_remove(
427
+ ObVecJsonTableClient.JsonTableDataTBL.jdata,
428
+ f"$.{origin_col_name}",
429
+ ),
430
+ f"$.{new_col_name}",
431
+ func.json_value(
432
+ ObVecJsonTableClient.JsonTableDataTBL.jdata,
433
+ f"$.{origin_col_name}",
434
+ ),
435
+ )
436
+ }
437
+ )
405
438
 
406
439
  session.query(ObVecJsonTableClient.JsonTableDataTBL).filter_by(
407
440
  admin_id=self.admin_id,
408
441
  jtable_name=jtable_name,
409
- ).update({
410
- ObVecJsonTableClient.JsonTableDataTBL.jdata: func.json_replace(
411
- ObVecJsonTableClient.JsonTableDataTBL.jdata,
412
- f'$.{new_col_name}',
413
- json_value(
442
+ ).update(
443
+ {
444
+ ObVecJsonTableClient.JsonTableDataTBL.jdata: func.json_replace(
414
445
  ObVecJsonTableClient.JsonTableDataTBL.jdata,
415
- f'$.{new_col_name}',
416
- col_type_str,
417
- ),
418
- )
419
- })
446
+ f"$.{new_col_name}",
447
+ json_value(
448
+ ObVecJsonTableClient.JsonTableDataTBL.jdata,
449
+ f"$.{new_col_name}",
450
+ col_type_str,
451
+ ),
452
+ )
453
+ }
454
+ )
420
455
 
421
456
  def _handle_alter_jtable_drop_column(
422
457
  self,
@@ -432,19 +467,19 @@ class ObVecJsonTableClient(ObVecClient):
432
467
  raise ValueError(f"{col_name} not exists in {jtable_name}")
433
468
 
434
469
  session.query(ObVecJsonTableClient.JsonTableMetaTBL).filter_by(
435
- user_id=self.admin_id,
436
- jtable_name=jtable_name,
437
- jcol_name=col_name
470
+ user_id=self.admin_id, jtable_name=jtable_name, jcol_name=col_name
438
471
  ).delete()
439
472
 
440
473
  session.query(ObVecJsonTableClient.JsonTableDataTBL).filter_by(
441
474
  admin_id=self.admin_id,
442
475
  jtable_name=jtable_name,
443
- ).update({
444
- ObVecJsonTableClient.JsonTableDataTBL.jdata: func.json_remove(
445
- ObVecJsonTableClient.JsonTableDataTBL.jdata, f'$.{col_name}'
446
- )
447
- })
476
+ ).update(
477
+ {
478
+ ObVecJsonTableClient.JsonTableDataTBL.jdata: func.json_remove(
479
+ ObVecJsonTableClient.JsonTableDataTBL.jdata, f"$.{col_name}"
480
+ )
481
+ }
482
+ )
448
483
 
449
484
  def _handle_alter_jtable_add_column(
450
485
  self,
@@ -456,54 +491,69 @@ class ObVecJsonTableClient(ObVecClient):
456
491
  new_col_name = add_col.this.this
457
492
  if self._check_col_exists(jtable_name, new_col_name):
458
493
  raise ValueError(f"{new_col_name} exists!")
459
-
494
+
460
495
  col_type_str = self._parse_col_datatype(add_col.kind)
461
496
  model = ObVecJsonTableClient.JsonTableMetadata._parse_col_type(col_type_str)
462
497
  constraints = self._parse_col_constraints(add_col.constraints)
463
- if (not constraints['jcol_nullable']) and constraints['jcol_has_default'] and (constraints['jcol_default'] is None):
498
+ if (
499
+ (not constraints["jcol_nullable"])
500
+ and constraints["jcol_has_default"]
501
+ and (constraints["jcol_default"] is None)
502
+ ):
464
503
  raise ValueError(f"Invalid default value for '{new_col_name}'")
465
- if constraints['jcol_has_default'] and (constraints['jcol_default'] is not None):
466
- model(val=self._calc_default_value(constraints['jcol_default']))
467
- cur_col_id = max([meta['jcol_id'] for meta in self.jmetadata.meta_cache[jtable_name]]) + 1
468
-
469
- session.add(ObVecJsonTableClient.JsonTableMetaTBL(
470
- user_id = self.admin_id,
471
- jtable_name = jtable_name,
472
- jcol_id = cur_col_id,
473
- jcol_name = new_col_name,
474
- jcol_type = col_type_str,
475
- jcol_nullable = constraints['jcol_nullable'],
476
- jcol_has_default = constraints['jcol_has_default'],
477
- jcol_default = {
478
- 'default': constraints['jcol_default'],
479
- }
480
- ))
504
+ if constraints["jcol_has_default"] and (
505
+ constraints["jcol_default"] is not None
506
+ ):
507
+ model(val=self._calc_default_value(constraints["jcol_default"]))
508
+ cur_col_id = (
509
+ max([meta["jcol_id"] for meta in self.jmetadata.meta_cache[jtable_name]])
510
+ + 1
511
+ )
512
+
513
+ session.add(
514
+ ObVecJsonTableClient.JsonTableMetaTBL(
515
+ user_id=self.admin_id,
516
+ jtable_name=jtable_name,
517
+ jcol_id=cur_col_id,
518
+ jcol_name=new_col_name,
519
+ jcol_type=col_type_str,
520
+ jcol_nullable=constraints["jcol_nullable"],
521
+ jcol_has_default=constraints["jcol_has_default"],
522
+ jcol_default={
523
+ "default": constraints["jcol_default"],
524
+ },
525
+ )
526
+ )
481
527
 
482
- if constraints['jcol_default'] is None:
528
+ if constraints["jcol_default"] is None:
483
529
  session.query(ObVecJsonTableClient.JsonTableDataTBL).filter_by(
484
530
  admin_id=self.admin_id,
485
531
  jtable_name=jtable_name,
486
- ).update({
487
- ObVecJsonTableClient.JsonTableDataTBL.jdata: func.json_insert(
488
- ObVecJsonTableClient.JsonTableDataTBL.jdata,
489
- f'$.{new_col_name}',
490
- None,
491
- )
492
- })
532
+ ).update(
533
+ {
534
+ ObVecJsonTableClient.JsonTableDataTBL.jdata: func.json_insert(
535
+ ObVecJsonTableClient.JsonTableDataTBL.jdata,
536
+ f"$.{new_col_name}",
537
+ None,
538
+ )
539
+ }
540
+ )
493
541
  else:
494
542
  model = ObVecJsonTableClient.JsonTableMetadata._parse_col_type(col_type_str)
495
- datum = model(val=self._calc_default_value(constraints['jcol_default']))
543
+ datum = model(val=self._calc_default_value(constraints["jcol_default"]))
496
544
  json_val = val2json(datum.val)
497
545
  session.query(ObVecJsonTableClient.JsonTableDataTBL).filter_by(
498
546
  admin_id=self.admin_id,
499
547
  jtable_name=jtable_name,
500
- ).update({
501
- ObVecJsonTableClient.JsonTableDataTBL.jdata: func.json_insert(
502
- ObVecJsonTableClient.JsonTableDataTBL.jdata,
503
- f'$.{new_col_name}',
504
- json_val,
505
- )
506
- })
548
+ ).update(
549
+ {
550
+ ObVecJsonTableClient.JsonTableDataTBL.jdata: func.json_insert(
551
+ ObVecJsonTableClient.JsonTableDataTBL.jdata,
552
+ f"$.{new_col_name}",
553
+ json_val,
554
+ )
555
+ }
556
+ )
507
557
 
508
558
  def _handle_alter_jtable_modify_column(
509
559
  self,
@@ -516,65 +566,79 @@ class ObVecJsonTableClient(ObVecClient):
516
566
  col_name = col_def.this.this
517
567
  if not self._check_col_exists(jtable_name, col_name):
518
568
  raise ValueError(f"{col_name} not exists in {jtable_name}")
519
-
569
+
520
570
  col_type_str = self._parse_col_datatype(col_def.kind)
521
571
  model = ObVecJsonTableClient.JsonTableMetadata._parse_col_type(col_type_str)
522
572
  constraints = self._parse_col_constraints(col_def.constraints)
523
- if (not constraints['jcol_nullable']) and constraints['jcol_has_default'] and (constraints['jcol_default'] is None):
573
+ if (
574
+ (not constraints["jcol_nullable"])
575
+ and constraints["jcol_has_default"]
576
+ and (constraints["jcol_default"] is None)
577
+ ):
524
578
  raise ValueError(f"Invalid default value for '{col_name}'")
525
- if constraints['jcol_has_default'] and (constraints['jcol_default'] is not None):
526
- model(val=self._calc_default_value(constraints['jcol_default']))
579
+ if constraints["jcol_has_default"] and (
580
+ constraints["jcol_default"] is not None
581
+ ):
582
+ model(val=self._calc_default_value(constraints["jcol_default"]))
527
583
 
528
584
  session.query(ObVecJsonTableClient.JsonTableMetaTBL).filter_by(
529
- user_id=self.admin_id,
530
- jtable_name=jtable_name,
531
- jcol_name=col_name
532
- ).update({
533
- ObVecJsonTableClient.JsonTableMetaTBL.jcol_name: col_name,
534
- ObVecJsonTableClient.JsonTableMetaTBL.jcol_type: col_type_str,
535
- ObVecJsonTableClient.JsonTableMetaTBL.jcol_nullable: constraints['jcol_nullable'],
536
- ObVecJsonTableClient.JsonTableMetaTBL.jcol_has_default: constraints['jcol_has_default'],
537
- ObVecJsonTableClient.JsonTableMetaTBL.jcol_default: {
538
- 'default': constraints['jcol_default']
539
- },
540
- })
541
-
542
- if constraints['jcol_default'] is None:
585
+ user_id=self.admin_id, jtable_name=jtable_name, jcol_name=col_name
586
+ ).update(
587
+ {
588
+ ObVecJsonTableClient.JsonTableMetaTBL.jcol_name: col_name,
589
+ ObVecJsonTableClient.JsonTableMetaTBL.jcol_type: col_type_str,
590
+ ObVecJsonTableClient.JsonTableMetaTBL.jcol_nullable: constraints[
591
+ "jcol_nullable"
592
+ ],
593
+ ObVecJsonTableClient.JsonTableMetaTBL.jcol_has_default: constraints[
594
+ "jcol_has_default"
595
+ ],
596
+ ObVecJsonTableClient.JsonTableMetaTBL.jcol_default: {
597
+ "default": constraints["jcol_default"]
598
+ },
599
+ }
600
+ )
601
+
602
+ if constraints["jcol_default"] is None:
543
603
  session.query(ObVecJsonTableClient.JsonTableDataTBL).filter_by(
544
604
  admin_id=self.admin_id,
545
605
  jtable_name=jtable_name,
546
- ).update({
547
- ObVecJsonTableClient.JsonTableDataTBL.jdata: func.json_replace(
548
- ObVecJsonTableClient.JsonTableDataTBL.jdata,
549
- f'$.{col_name}',
550
- json_value(
606
+ ).update(
607
+ {
608
+ ObVecJsonTableClient.JsonTableDataTBL.jdata: func.json_replace(
551
609
  ObVecJsonTableClient.JsonTableDataTBL.jdata,
552
- f'$.{col_name}',
553
- col_type_str,
554
- ),
555
- )
556
- })
610
+ f"$.{col_name}",
611
+ json_value(
612
+ ObVecJsonTableClient.JsonTableDataTBL.jdata,
613
+ f"$.{col_name}",
614
+ col_type_str,
615
+ ),
616
+ )
617
+ }
618
+ )
557
619
  else:
558
620
  model = ObVecJsonTableClient.JsonTableMetadata._parse_col_type(col_type_str)
559
- datum = model(val=self._calc_default_value(constraints['jcol_default']))
621
+ datum = model(val=self._calc_default_value(constraints["jcol_default"]))
560
622
  json_val = val2json(datum.val)
561
623
  session.query(ObVecJsonTableClient.JsonTableDataTBL).filter_by(
562
624
  admin_id=self.admin_id,
563
625
  jtable_name=jtable_name,
564
- ).update({
565
- ObVecJsonTableClient.JsonTableDataTBL.jdata: func.json_replace(
566
- ObVecJsonTableClient.JsonTableDataTBL.jdata,
567
- f'$.{col_name}',
568
- func.ifnull(
569
- json_value(
570
- ObVecJsonTableClient.JsonTableDataTBL.jdata,
571
- f'$.{col_name}',
572
- col_type_str,
626
+ ).update(
627
+ {
628
+ ObVecJsonTableClient.JsonTableDataTBL.jdata: func.json_replace(
629
+ ObVecJsonTableClient.JsonTableDataTBL.jdata,
630
+ f"$.{col_name}",
631
+ func.ifnull(
632
+ json_value(
633
+ ObVecJsonTableClient.JsonTableDataTBL.jdata,
634
+ f"$.{col_name}",
635
+ col_type_str,
636
+ ),
637
+ json_val,
573
638
  ),
574
- json_val,
575
- ),
576
- )
577
- })
639
+ )
640
+ }
641
+ )
578
642
 
579
643
  def _handle_alter_jtable_rename_table(
580
644
  self,
@@ -584,17 +648,19 @@ class ObVecJsonTableClient(ObVecClient):
584
648
  ):
585
649
  if not self._check_table_exists(jtable_name):
586
650
  raise ValueError(f"Table {jtable_name} does not exists")
587
-
651
+
588
652
  new_table_name = rename.this.this.this
589
653
  if self.check_table_exists(new_table_name):
590
654
  raise ValueError(f"Table {new_table_name} exists!")
591
-
655
+
592
656
  session.query(ObVecJsonTableClient.JsonTableMetaTBL).filter_by(
593
657
  user_id=self.admin_id,
594
658
  jtable_name=jtable_name,
595
- ).update({
596
- ObVecJsonTableClient.JsonTableMetaTBL.jtable_name: new_table_name,
597
- })
659
+ ).update(
660
+ {
661
+ ObVecJsonTableClient.JsonTableMetaTBL.jtable_name: new_table_name,
662
+ }
663
+ )
598
664
 
599
665
  def _handle_alter_json_table(self, ast: Expression):
600
666
  if not isinstance(ast.this, exp.Table):
@@ -604,7 +670,7 @@ class ObVecJsonTableClient(ObVecClient):
604
670
  jtable_name = ast.this.this.this
605
671
  if not self._check_table_exists(jtable_name):
606
672
  raise ValueError(f"Table {jtable_name} does not exists")
607
-
673
+
608
674
  session = self.session()
609
675
  session.execute(text("SET @@session.autocommit=0"))
610
676
  for action in ast.actions:
@@ -638,7 +704,7 @@ class ObVecJsonTableClient(ObVecClient):
638
704
  jtable_name,
639
705
  action,
640
706
  )
641
-
707
+
642
708
  try:
643
709
  session.commit()
644
710
  self.jmetadata.reflect(self.engine)
@@ -648,7 +714,9 @@ class ObVecJsonTableClient(ObVecClient):
648
714
  finally:
649
715
  session.close()
650
716
 
651
- def _handle_jtable_dml_insert(self, ast: Expression, opt_user_id: Optional[str] = None):
717
+ def _handle_jtable_dml_insert(
718
+ self, ast: Expression, opt_user_id: Optional[str] = None
719
+ ):
652
720
  real_user_id = opt_user_id or self.user_id
653
721
 
654
722
  if real_user_id is None:
@@ -660,11 +728,12 @@ class ObVecJsonTableClient(ObVecClient):
660
728
  table_name = ast.this.this.this
661
729
  if not self._check_table_exists(table_name):
662
730
  raise ValueError(f"Table {table_name} does not exists")
663
-
664
- table_col_names = [meta['jcol_name'] for meta in self.jmetadata.meta_cache[table_name]]
731
+
732
+ table_col_names = [
733
+ meta["jcol_name"] for meta in self.jmetadata.meta_cache[table_name]
734
+ ]
665
735
  cols = {
666
- meta['jcol_name']: meta
667
- for meta in self.jmetadata.meta_cache[table_name]
736
+ meta["jcol_name"]: meta for meta in self.jmetadata.meta_cache[table_name]
668
737
  }
669
738
  if isinstance(ast.this, exp.Schema):
670
739
  insert_col_names = [expr.this for expr in ast.this.expressions]
@@ -672,9 +741,14 @@ class ObVecJsonTableClient(ObVecClient):
672
741
  if col_name not in table_col_names:
673
742
  raise ValueError(f"Unknown column {col_name} in field list")
674
743
  for meta in self.jmetadata.meta_cache[table_name]:
675
- if ((meta['jcol_name'] not in insert_col_names) and
676
- (not meta['jcol_nullable']) and (not meta['jcol_has_default'])):
677
- raise ValueError(f"Field {meta['jcol_name']} does not have a default value")
744
+ if (
745
+ (meta["jcol_name"] not in insert_col_names)
746
+ and (not meta["jcol_nullable"])
747
+ and (not meta["jcol_has_default"])
748
+ ):
749
+ raise ValueError(
750
+ f"Field {meta['jcol_name']} does not have a default value"
751
+ )
678
752
  elif isinstance(ast.this, exp.Table):
679
753
  insert_col_names = table_col_names
680
754
  else:
@@ -686,28 +760,34 @@ class ObVecJsonTableClient(ObVecClient):
686
760
  for tuple in ast.expression.expressions:
687
761
  expr_list = tuple.expressions
688
762
  if len(expr_list) != len(insert_col_names):
689
- raise ValueError(f"Values Tuple length does not match with the length of insert columns")
763
+ raise ValueError(
764
+ f"Values Tuple length does not match with the length of insert columns"
765
+ )
690
766
  kv = {}
691
767
  for col_name, expr in zip(insert_col_names, expr_list):
692
- model = cols[col_name]['jcol_model']
768
+ model = cols[col_name]["jcol_model"]
693
769
  datum = model(val=self._calc_default_value(str(expr)))
694
770
  kv[col_name] = val2json(datum.val)
695
771
  for col_name in table_col_names:
696
772
  if col_name not in insert_col_names:
697
- model = cols[col_name]['jcol_model']
698
- datum = model(val=self._calc_default_value(cols[col_name]['jcol_default']))
773
+ model = cols[col_name]["jcol_model"]
774
+ datum = model(
775
+ val=self._calc_default_value(cols[col_name]["jcol_default"])
776
+ )
699
777
  kv[col_name] = val2json(datum.val)
700
778
 
701
779
  logger.debug(f"================= [INSERT] =============== {kv}")
702
780
 
703
- session.add(ObVecJsonTableClient.JsonTableDataTBL(
704
- user_id = real_user_id,
705
- admin_id = self.admin_id,
706
- jtable_name = table_name,
707
- jdata = kv,
708
- ))
781
+ session.add(
782
+ ObVecJsonTableClient.JsonTableDataTBL(
783
+ user_id=real_user_id,
784
+ admin_id=self.admin_id,
785
+ jtable_name=table_name,
786
+ jdata=kv,
787
+ )
788
+ )
709
789
  n_new_records += 1
710
-
790
+
711
791
  try:
712
792
  session.commit()
713
793
  except Exception as e:
@@ -718,20 +798,24 @@ class ObVecJsonTableClient(ObVecClient):
718
798
  session.close()
719
799
  return n_new_records
720
800
 
721
- def _handle_jtable_dml_update(self, ast: Expression, opt_user_id: Optional[str] = None):
801
+ def _handle_jtable_dml_update(
802
+ self, ast: Expression, opt_user_id: Optional[str] = None
803
+ ):
722
804
  real_user_id = opt_user_id or self.user_id
723
805
 
724
806
  table_name = ast.this.this.this
725
807
  if not self._check_table_exists(table_name):
726
808
  raise ValueError(f"Table {table_name} does not exists")
727
-
809
+
728
810
  path_settings = []
729
811
  for expr in ast.expressions:
730
812
  col_name = expr.this.this.this
731
813
  if not self._check_col_exists(table_name, col_name):
732
814
  raise ValueError(f"Column {col_name} does not exists")
733
815
  col_expr = expr.expression
734
- new_node = parse_one(f"JSON_VALUE({JSON_TABLE_DATA_TABLE_NAME}.jdata, '$.{col_name}')")
816
+ new_node = parse_one(
817
+ f"JSON_VALUE({JSON_TABLE_DATA_TABLE_NAME}.jdata, '$.{col_name}')"
818
+ )
735
819
  for column in col_expr.find_all(exp.Column):
736
820
  parent_node = column.parent
737
821
  if isinstance(parent_node.args[column.arg_key], list):
@@ -747,20 +831,20 @@ class ObVecJsonTableClient(ObVecClient):
747
831
  logger.info(str(col_expr))
748
832
  path_settings.append(f"'$.{col_name}', {str(col_expr)}")
749
833
 
750
- where_clause = None
751
- if 'where' in ast.args.keys() and ast.args['where']:
752
- for column in ast.args['where'].find_all(exp.Column):
834
+ where_clause = None
835
+ if "where" in ast.args.keys() and ast.args["where"]:
836
+ for column in ast.args["where"].find_all(exp.Column):
753
837
  where_col_name = column.this.this
754
838
  if not self._check_col_exists(table_name, where_col_name):
755
839
  raise ValueError(f"Column {where_col_name} does not exists")
756
- column.parent.args['this'] = parse_one(
840
+ column.parent.args["this"] = parse_one(
757
841
  f"JSON_VALUE({JSON_TABLE_DATA_TABLE_NAME}.jdata, '$.{where_col_name}')"
758
842
  )
759
843
  if real_user_id:
760
844
  where_clause = f"{JSON_TABLE_DATA_TABLE_NAME}.user_id = '{real_user_id}' AND {JSON_TABLE_DATA_TABLE_NAME}.jtable_name = '{table_name}' AND ({str(ast.args['where'].this)})"
761
845
  else:
762
846
  where_clause = f"{JSON_TABLE_DATA_TABLE_NAME}.jtable_name = '{table_name}' AND ({str(ast.args['where'].this)})"
763
-
847
+
764
848
  if where_clause:
765
849
  update_sql = f"UPDATE {JSON_TABLE_DATA_TABLE_NAME} SET jdata = JSON_REPLACE({JSON_TABLE_DATA_TABLE_NAME}.jdata, {', '.join(path_settings)}) WHERE {where_clause}"
766
850
  else:
@@ -770,29 +854,33 @@ class ObVecJsonTableClient(ObVecClient):
770
854
  res = self.perform_raw_text_sql(update_sql)
771
855
  return res.rowcount
772
856
 
773
- def _handle_jtable_dml_delete(self, ast: Expression, opt_user_id: Optional[str] = None):
857
+ def _handle_jtable_dml_delete(
858
+ self, ast: Expression, opt_user_id: Optional[str] = None
859
+ ):
774
860
  real_user_id = opt_user_id or self.user_id
775
861
 
776
862
  table_name = ast.this.this.this
777
863
  if not self._check_table_exists(table_name):
778
864
  raise ValueError(f"Table {table_name} does not exists")
779
-
865
+
780
866
  where_clause = None
781
- if 'where' in ast.args.keys() and ast.args['where']:
782
- for column in ast.args['where'].find_all(exp.Column):
867
+ if "where" in ast.args.keys() and ast.args["where"]:
868
+ for column in ast.args["where"].find_all(exp.Column):
783
869
  where_col_name = column.this.this
784
870
  if not self._check_col_exists(table_name, where_col_name):
785
871
  raise ValueError(f"Column {where_col_name} does not exists")
786
- column.parent.args['this'] = parse_one(
872
+ column.parent.args["this"] = parse_one(
787
873
  f"JSON_VALUE({JSON_TABLE_DATA_TABLE_NAME}.jdata, '$.{where_col_name}')"
788
874
  )
789
875
  if real_user_id:
790
876
  where_clause = f"{JSON_TABLE_DATA_TABLE_NAME}.user_id = '{real_user_id}' AND {JSON_TABLE_DATA_TABLE_NAME}.jtable_name = '{table_name}' AND ({str(ast.args['where'].this)})"
791
877
  else:
792
878
  where_clause = f"{JSON_TABLE_DATA_TABLE_NAME}.jtable_name = '{table_name}' AND ({str(ast.args['where'].this)})"
793
-
879
+
794
880
  if where_clause:
795
- delete_sql = f"DELETE FROM {JSON_TABLE_DATA_TABLE_NAME} WHERE {where_clause}"
881
+ delete_sql = (
882
+ f"DELETE FROM {JSON_TABLE_DATA_TABLE_NAME} WHERE {where_clause}"
883
+ )
796
884
  else:
797
885
  delete_sql = f"DELETE FROM {JSON_TABLE_DATA_TABLE_NAME}"
798
886
 
@@ -811,16 +899,18 @@ class ObVecJsonTableClient(ObVecClient):
811
899
  self,
812
900
  ast: Expression,
813
901
  select_with_data_id: bool = False,
814
- opt_user_id: Optional[str] = None
902
+ opt_user_id: Optional[str] = None,
815
903
  ):
816
904
  real_user_id = opt_user_id or self.user_id
817
905
 
818
- from_key = 'from_' if 'from_' in ast.args else 'from'
906
+ from_key = "from_" if "from_" in ast.args else "from"
819
907
  table_name = ast.args[from_key].this.this.this
820
908
  if not self._check_table_exists(table_name):
821
909
  raise ValueError(f"Table {table_name} does not exists")
822
-
823
- ast.args[from_key].args['this'].args['this'] = to_identifier(name=JSON_TABLE_DATA_TABLE_NAME, quoted=False)
910
+
911
+ ast.args[from_key].args["this"].args["this"] = to_identifier(
912
+ name=JSON_TABLE_DATA_TABLE_NAME, quoted=False
913
+ )
824
914
 
825
915
  col_meta = self.jmetadata.meta_cache[table_name]
826
916
  json_table_meta_str = []
@@ -830,42 +920,42 @@ class ObVecJsonTableClient(ObVecClient):
830
920
  f"{meta['jcol_name']} {self._get_full_datatype(meta['jcol_type'])} "
831
921
  f"PATH '$.{meta['jcol_name']}'"
832
922
  )
833
- all_jcol_names.append(meta['jcol_name'])
834
-
923
+ all_jcol_names.append(meta["jcol_name"])
924
+
835
925
  need_replace_select_exprs = False
836
926
  new_select_exprs = []
837
927
 
838
928
  if select_with_data_id:
839
929
  data_id_col_expr = exp.Column()
840
930
  data_id_identifier = exp.Identifier()
841
- data_id_identifier.args['this'] = 'jdata_id'
842
- data_id_identifier.args['quoted'] = False
931
+ data_id_identifier.args["this"] = "jdata_id"
932
+ data_id_identifier.args["quoted"] = False
843
933
  data_json_table_identifier = exp.Identifier()
844
- data_json_table_identifier.args['this'] = JSON_TABLE_DATA_TABLE_NAME
845
- data_json_table_identifier.args['quoted'] = False
846
- data_id_col_expr.args['this'] = data_id_identifier
847
- data_id_col_expr.args['table'] = data_json_table_identifier
934
+ data_json_table_identifier.args["this"] = JSON_TABLE_DATA_TABLE_NAME
935
+ data_json_table_identifier.args["quoted"] = False
936
+ data_id_col_expr.args["this"] = data_id_identifier
937
+ data_id_col_expr.args["table"] = data_json_table_identifier
848
938
  new_select_exprs.append(data_id_col_expr)
849
939
  need_replace_select_exprs = True
850
940
 
851
941
  alias_names = set()
852
- for select_expr in ast.args['expressions']:
942
+ for select_expr in ast.args["expressions"]:
853
943
  if isinstance(select_expr, exp.Star):
854
944
  need_replace_select_exprs = True
855
945
  for jcol_name in all_jcol_names:
856
946
  col_expr = exp.Column()
857
947
  identifier = exp.Identifier()
858
- identifier.args['this'] = jcol_name
859
- identifier.args['quoted'] = False
860
- col_expr.args['this'] = identifier
948
+ identifier.args["this"] = jcol_name
949
+ identifier.args["quoted"] = False
950
+ col_expr.args["this"] = identifier
861
951
  new_select_exprs.append(col_expr)
862
952
  else:
863
953
  if isinstance(select_expr, exp.Alias):
864
- alias_names.add(select_expr.args['alias'].args['this'])
954
+ alias_names.add(select_expr.args["alias"].args["this"])
865
955
  new_select_exprs.append(select_expr)
866
956
  if need_replace_select_exprs:
867
- ast.args['expressions'] = new_select_exprs
868
-
957
+ ast.args["expressions"] = new_select_exprs
958
+
869
959
  tmp_table_name = "__tmp"
870
960
  json_table_str = f"json_table({JSON_TABLE_DATA_TABLE_NAME}.jdata, '$' COLUMNS ({', '.join(json_table_meta_str)})) {tmp_table_name}"
871
961
 
@@ -873,41 +963,43 @@ class ObVecJsonTableClient(ObVecClient):
873
963
  col_name = col.args["this"].args["this"]
874
964
  if col_name in alias_names:
875
965
  continue
876
- if 'table' in col.args.keys():
877
- if col.args['table'].args['this'] != JSON_TABLE_DATA_TABLE_NAME:
878
- col.args['table'].args['this'] = tmp_table_name
966
+ if "table" in col.args.keys():
967
+ if col.args["table"].args["this"] != JSON_TABLE_DATA_TABLE_NAME:
968
+ col.args["table"].args["this"] = tmp_table_name
879
969
  else:
880
970
  identifier = exp.Identifier()
881
- identifier.args['this'] = tmp_table_name
882
- identifier.args['quoted'] = False
883
- col.args['table'] = identifier
971
+ identifier.args["this"] = tmp_table_name
972
+ identifier.args["quoted"] = False
973
+ col.args["table"] = identifier
884
974
 
885
975
  # Manually create the JOIN node for json_table
886
976
  # In some versions of sqlglot, comma-separated tables may not be parsed as
887
977
  # explicit JOINS, so we directly parse the json_table expression and create a JOIN node
888
978
  # explicitly
889
979
  json_table_expr = parse_one(json_table_str, dialect="oceanbase")
890
-
980
+
891
981
  join_node = exp.Join()
892
- join_node.args['this'] = json_table_expr
893
- join_node.args['kind'] = None # CROSS JOIN (implicit join with comma)
894
-
895
- if 'joins' not in ast.args:
896
- ast.args['joins'] = []
897
- ast.args['joins'].append(join_node)
982
+ join_node.args["this"] = json_table_expr
983
+ join_node.args["kind"] = None # CROSS JOIN (implicit join with comma)
984
+
985
+ if "joins" not in ast.args:
986
+ ast.args["joins"] = []
987
+ ast.args["joins"].append(join_node)
898
988
 
899
989
  if real_user_id:
900
990
  extra_filter_str = f"{JSON_TABLE_DATA_TABLE_NAME}.user_id = '{real_user_id}' AND {JSON_TABLE_DATA_TABLE_NAME}.jtable_name = '{table_name}'"
901
991
  else:
902
- extra_filter_str = f"{JSON_TABLE_DATA_TABLE_NAME}.jtable_name = '{table_name}'"
903
- if 'where' in ast.args.keys():
904
- filter_str = str(ast.args['where'].args['this'])
992
+ extra_filter_str = (
993
+ f"{JSON_TABLE_DATA_TABLE_NAME}.jtable_name = '{table_name}'"
994
+ )
995
+ if "where" in ast.args.keys():
996
+ filter_str = str(ast.args["where"].args["this"])
905
997
  new_filter_str = f"{extra_filter_str} AND ({filter_str})"
906
- ast.args['where'].args['this'] = parse_one(new_filter_str)
998
+ ast.args["where"].args["this"] = parse_one(new_filter_str)
907
999
  else:
908
1000
  where_clause = exp.Where()
909
- where_clause.args['this'] = parse_one(extra_filter_str)
910
- ast.args['where'] = where_clause
1001
+ where_clause.args["this"] = parse_one(extra_filter_str)
1002
+ ast.args["where"] = where_clause
911
1003
 
912
1004
  select_sql = ast.sql(dialect="mysql", identify=True)
913
1005
  logger.debug(f"===================== do select: {select_sql}")