MindsDB 25.5.4.2__py3-none-any.whl → 25.6.2.0__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.

Potentially problematic release.


This version of MindsDB might be problematic. Click here for more details.

Files changed (69) hide show
  1. mindsdb/__about__.py +1 -1
  2. mindsdb/api/a2a/agent.py +28 -25
  3. mindsdb/api/a2a/common/server/server.py +32 -26
  4. mindsdb/api/executor/command_executor.py +69 -14
  5. mindsdb/api/executor/datahub/datanodes/integration_datanode.py +49 -65
  6. mindsdb/api/executor/datahub/datanodes/project_datanode.py +29 -48
  7. mindsdb/api/executor/datahub/datanodes/system_tables.py +35 -61
  8. mindsdb/api/executor/planner/plan_join.py +67 -77
  9. mindsdb/api/executor/planner/query_planner.py +176 -155
  10. mindsdb/api/executor/planner/steps.py +37 -12
  11. mindsdb/api/executor/sql_query/result_set.py +45 -64
  12. mindsdb/api/executor/sql_query/steps/fetch_dataframe.py +14 -18
  13. mindsdb/api/executor/sql_query/steps/fetch_dataframe_partition.py +17 -18
  14. mindsdb/api/executor/sql_query/steps/insert_step.py +13 -33
  15. mindsdb/api/executor/sql_query/steps/subselect_step.py +43 -35
  16. mindsdb/api/executor/utilities/sql.py +42 -48
  17. mindsdb/api/http/namespaces/config.py +1 -1
  18. mindsdb/api/http/namespaces/file.py +14 -23
  19. mindsdb/api/mysql/mysql_proxy/data_types/mysql_datum.py +12 -28
  20. mindsdb/api/mysql/mysql_proxy/data_types/mysql_packets/binary_resultset_row_package.py +59 -50
  21. mindsdb/api/mysql/mysql_proxy/data_types/mysql_packets/resultset_row_package.py +9 -8
  22. mindsdb/api/mysql/mysql_proxy/libs/constants/mysql.py +449 -461
  23. mindsdb/api/mysql/mysql_proxy/utilities/dump.py +87 -36
  24. mindsdb/integrations/handlers/file_handler/file_handler.py +15 -9
  25. mindsdb/integrations/handlers/file_handler/tests/test_file_handler.py +43 -24
  26. mindsdb/integrations/handlers/litellm_handler/litellm_handler.py +10 -3
  27. mindsdb/integrations/handlers/mysql_handler/mysql_handler.py +26 -33
  28. mindsdb/integrations/handlers/oracle_handler/oracle_handler.py +74 -51
  29. mindsdb/integrations/handlers/postgres_handler/postgres_handler.py +305 -98
  30. mindsdb/integrations/handlers/salesforce_handler/salesforce_handler.py +53 -34
  31. mindsdb/integrations/handlers/salesforce_handler/salesforce_tables.py +136 -6
  32. mindsdb/integrations/handlers/snowflake_handler/snowflake_handler.py +334 -83
  33. mindsdb/integrations/libs/api_handler.py +261 -57
  34. mindsdb/integrations/libs/base.py +100 -29
  35. mindsdb/integrations/utilities/files/file_reader.py +99 -73
  36. mindsdb/integrations/utilities/handler_utils.py +23 -8
  37. mindsdb/integrations/utilities/sql_utils.py +35 -40
  38. mindsdb/interfaces/agents/agents_controller.py +196 -192
  39. mindsdb/interfaces/agents/constants.py +7 -1
  40. mindsdb/interfaces/agents/langchain_agent.py +42 -11
  41. mindsdb/interfaces/agents/mcp_client_agent.py +29 -21
  42. mindsdb/interfaces/data_catalog/__init__.py +0 -0
  43. mindsdb/interfaces/data_catalog/base_data_catalog.py +54 -0
  44. mindsdb/interfaces/data_catalog/data_catalog_loader.py +359 -0
  45. mindsdb/interfaces/data_catalog/data_catalog_reader.py +34 -0
  46. mindsdb/interfaces/database/database.py +81 -57
  47. mindsdb/interfaces/database/integrations.py +220 -234
  48. mindsdb/interfaces/database/log.py +72 -104
  49. mindsdb/interfaces/database/projects.py +156 -193
  50. mindsdb/interfaces/file/file_controller.py +21 -65
  51. mindsdb/interfaces/knowledge_base/controller.py +63 -10
  52. mindsdb/interfaces/knowledge_base/evaluate.py +519 -0
  53. mindsdb/interfaces/knowledge_base/llm_client.py +75 -0
  54. mindsdb/interfaces/skills/custom/text2sql/mindsdb_kb_tools.py +83 -43
  55. mindsdb/interfaces/skills/skills_controller.py +54 -36
  56. mindsdb/interfaces/skills/sql_agent.py +109 -86
  57. mindsdb/interfaces/storage/db.py +223 -79
  58. mindsdb/migrations/versions/2025-05-28_a44643042fe8_added_data_catalog_tables.py +118 -0
  59. mindsdb/migrations/versions/2025-06-09_608e376c19a7_updated_data_catalog_data_types.py +58 -0
  60. mindsdb/utilities/config.py +9 -2
  61. mindsdb/utilities/log.py +35 -26
  62. mindsdb/utilities/ml_task_queue/task.py +19 -22
  63. mindsdb/utilities/render/sqlalchemy_render.py +129 -181
  64. mindsdb/utilities/starters.py +40 -0
  65. {mindsdb-25.5.4.2.dist-info → mindsdb-25.6.2.0.dist-info}/METADATA +253 -253
  66. {mindsdb-25.5.4.2.dist-info → mindsdb-25.6.2.0.dist-info}/RECORD +69 -61
  67. {mindsdb-25.5.4.2.dist-info → mindsdb-25.6.2.0.dist-info}/WHEEL +0 -0
  68. {mindsdb-25.5.4.2.dist-info → mindsdb-25.6.2.0.dist-info}/licenses/LICENSE +0 -0
  69. {mindsdb-25.5.4.2.dist-info → mindsdb-25.6.2.0.dist-info}/top_level.txt +0 -0
@@ -21,8 +21,8 @@ logger = log.getLogger(__name__)
21
21
 
22
22
 
23
23
  def _map_type(internal_type_name: str) -> MYSQL_DATA_TYPE:
24
- """ Map Oracle types to MySQL types.
25
- List of types: https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/Data-Types.html
24
+ """Map Oracle types to MySQL types.
25
+ List of types: https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/Data-Types.html
26
26
 
27
27
  Args:
28
28
  internal_type_name (str): The name of the Oracle type to map.
@@ -33,21 +33,33 @@ def _map_type(internal_type_name: str) -> MYSQL_DATA_TYPE:
33
33
  internal_type_name = internal_type_name.upper()
34
34
  types_map = {
35
35
  (
36
- 'VARCHAR2', 'NVARCHAR2', 'CHARACTER VARYING', 'CHAR VARYING', 'NATIONAL CHARACTER', 'NATIONAL CHAR',
37
- 'VARCHAR', 'NCHAR', 'NATIONAL CHARACTER VARYING', 'NATIONAL CHAR VARYING', 'NCHAR VARYING', 'LONG VARCHAR'
36
+ "VARCHAR2",
37
+ "NVARCHAR2",
38
+ "CHARACTER VARYING",
39
+ "CHAR VARYING",
40
+ "NATIONAL CHARACTER",
41
+ "NATIONAL CHAR",
42
+ "VARCHAR",
43
+ "NCHAR",
44
+ "NATIONAL CHARACTER VARYING",
45
+ "NATIONAL CHAR VARYING",
46
+ "NCHAR VARYING",
47
+ "LONG VARCHAR",
38
48
  ): MYSQL_DATA_TYPE.VARCHAR,
39
- ('INTEGER', 'INT'): MYSQL_DATA_TYPE.INT,
40
- ('SMALLINT',): MYSQL_DATA_TYPE.SMALLINT,
41
- ('NUMBER', 'DECIMAL'): MYSQL_DATA_TYPE.DECIMAL,
42
- ('FLOAT', 'BINARY_FLOAT', 'REAL'): MYSQL_DATA_TYPE.FLOAT,
43
- ('BINARY_DOUBLE',): MYSQL_DATA_TYPE.DOUBLE,
44
- ('LONG',): MYSQL_DATA_TYPE.BIGINT,
45
- ('DATE',): MYSQL_DATA_TYPE.DATE,
46
- ('HOUR', 'MINUTE', 'SECOND', 'TIMEZONE_HOUR', 'TIMEZONE_MINUTE'): MYSQL_DATA_TYPE.SMALLINT,
47
- ('TIMESTAMP', 'TIMESTAMP WITH TIME ZONE', 'TIMESTAMP WITH LOCAL TIME ZONE'): MYSQL_DATA_TYPE.TIMESTAMP,
48
- ('RAW', 'LONG RAW', 'BLOB', 'BFILE'): MYSQL_DATA_TYPE.BINARY,
49
- ('ROWID', 'UROWID'): MYSQL_DATA_TYPE.TEXT,
50
- ('CHAR', 'NCHAR', 'CLOB', 'NCLOB', 'CHARACTER'): MYSQL_DATA_TYPE.CHAR,
49
+ ("INTEGER", "INT"): MYSQL_DATA_TYPE.INT,
50
+ ("SMALLINT",): MYSQL_DATA_TYPE.SMALLINT,
51
+ ("NUMBER", "DECIMAL"): MYSQL_DATA_TYPE.DECIMAL,
52
+ ("FLOAT", "BINARY_FLOAT", "REAL"): MYSQL_DATA_TYPE.FLOAT,
53
+ ("BINARY_DOUBLE",): MYSQL_DATA_TYPE.DOUBLE,
54
+ ("LONG",): MYSQL_DATA_TYPE.BIGINT,
55
+ ("DATE",): MYSQL_DATA_TYPE.DATE,
56
+ ("HOUR", "MINUTE", "SECOND", "TIMEZONE_HOUR", "TIMEZONE_MINUTE"): MYSQL_DATA_TYPE.SMALLINT,
57
+ ("TIMESTAMP", "TIMESTAMP WITH TIME ZONE", "TIMESTAMP WITH LOCAL TIME ZONE"): MYSQL_DATA_TYPE.TIMESTAMP,
58
+ ("RAW", "LONG RAW", "BLOB", "BFILE"): MYSQL_DATA_TYPE.BINARY,
59
+ ("ROWID", "UROWID"): MYSQL_DATA_TYPE.TEXT,
60
+ ("CHAR", "NCHAR", "CLOB", "NCLOB", "CHARACTER"): MYSQL_DATA_TYPE.CHAR,
61
+ ("VECTOR",): MYSQL_DATA_TYPE.VECTOR,
62
+ ("JSON",): MYSQL_DATA_TYPE.JSON,
51
63
  }
52
64
 
53
65
  for db_types_list, mysql_data_type in types_map.items():
@@ -74,7 +86,11 @@ def _make_table_response(result: list[tuple[Any]], cursor: Cursor) -> Response:
74
86
  db_type = column[1]
75
87
  precision = column[4]
76
88
  scale = column[5]
77
- if db_type is oracledb.DB_TYPE_NUMBER:
89
+ if db_type is oracledb.DB_TYPE_JSON:
90
+ mysql_types.append(MYSQL_DATA_TYPE.JSON)
91
+ elif db_type is oracledb.DB_TYPE_VECTOR:
92
+ mysql_types.append(MYSQL_DATA_TYPE.VECTOR)
93
+ elif db_type is oracledb.DB_TYPE_NUMBER:
78
94
  if scale != 0:
79
95
  mysql_types.append(MYSQL_DATA_TYPE.FLOAT)
80
96
  else:
@@ -92,8 +108,12 @@ def _make_table_response(result: list[tuple[Any]], cursor: Cursor) -> Response:
92
108
  elif db_type is oracledb.DB_TYPE_BOOLEAN:
93
109
  mysql_types.append(MYSQL_DATA_TYPE.BOOLEAN)
94
110
  elif db_type in (
95
- oracledb.DB_TYPE_CHAR, oracledb.DB_TYPE_NCHAR, oracledb.DB_TYPE_LONG,
96
- oracledb.DB_TYPE_NVARCHAR, oracledb.DB_TYPE_VARCHAR, oracledb.DB_TYPE_LONG_NVARCHAR,
111
+ oracledb.DB_TYPE_CHAR,
112
+ oracledb.DB_TYPE_NCHAR,
113
+ oracledb.DB_TYPE_LONG,
114
+ oracledb.DB_TYPE_NVARCHAR,
115
+ oracledb.DB_TYPE_VARCHAR,
116
+ oracledb.DB_TYPE_LONG_NVARCHAR,
97
117
  ):
98
118
  mysql_types.append(MYSQL_DATA_TYPE.TEXT)
99
119
  elif db_type in (oracledb.DB_TYPE_RAW, oracledb.DB_TYPE_LONG_RAW):
@@ -111,21 +131,20 @@ def _make_table_response(result: list[tuple[Any]], cursor: Cursor) -> Response:
111
131
  for i, mysql_type in enumerate(mysql_types):
112
132
  expected_dtype = None
113
133
  if mysql_type in (
114
- MYSQL_DATA_TYPE.SMALLINT, MYSQL_DATA_TYPE.INT, MYSQL_DATA_TYPE.MEDIUMINT,
115
- MYSQL_DATA_TYPE.BIGINT, MYSQL_DATA_TYPE.TINYINT
134
+ MYSQL_DATA_TYPE.SMALLINT,
135
+ MYSQL_DATA_TYPE.INT,
136
+ MYSQL_DATA_TYPE.MEDIUMINT,
137
+ MYSQL_DATA_TYPE.BIGINT,
138
+ MYSQL_DATA_TYPE.TINYINT,
116
139
  ):
117
- expected_dtype = 'Int64'
140
+ expected_dtype = "Int64"
118
141
  elif mysql_type in (MYSQL_DATA_TYPE.BOOL, MYSQL_DATA_TYPE.BOOLEAN):
119
- expected_dtype = 'boolean'
142
+ expected_dtype = "boolean"
120
143
  serieses.append(pd.Series([row[i] for row in result], dtype=expected_dtype, name=description[i][0]))
121
144
  df = pd.concat(serieses, axis=1, copy=False)
122
145
  # endregion
123
146
 
124
- return Response(
125
- RESPONSE_TYPE.TABLE,
126
- data_frame=df,
127
- mysql_types=mysql_types
128
- )
147
+ return Response(RESPONSE_TYPE.TABLE, data_frame=df, mysql_types=mysql_types)
129
148
 
130
149
 
131
150
  class OracleHandler(DatabaseHandler):
@@ -165,59 +184,63 @@ class OracleHandler(DatabaseHandler):
165
184
  return self.connection
166
185
 
167
186
  # Mandatory connection parameters.
168
- if not all(key in self.connection_data for key in ['user', 'password']):
169
- raise ValueError('Required parameters (user, password) must be provided.')
187
+ if not all(key in self.connection_data for key in ["user", "password"]):
188
+ raise ValueError("Required parameters (user, password) must be provided.")
170
189
 
171
- if self.connection_data.get('thick_mode', False):
190
+ if self.connection_data.get("thick_mode", False):
172
191
  oracledb.init_oracle_client()
173
192
 
174
193
  config = {
175
- 'user': self.connection_data['user'],
176
- 'password': self.connection_data['password'],
194
+ "user": self.connection_data["user"],
195
+ "password": self.connection_data["password"],
177
196
  }
178
197
 
179
198
  # If 'dsn' is given, use it. Otherwise, use the individual connection parameters.
180
- if 'dsn' in self.connection_data:
181
- config['dsn'] = self.connection_data['dsn']
199
+ if "dsn" in self.connection_data:
200
+ config["dsn"] = self.connection_data["dsn"]
182
201
 
183
202
  else:
184
- if 'host' not in self.connection_data and not any(key in self.connection_data for key in ['sid', 'service_name']):
185
- raise ValueError('Required parameter host and either sid or service_name must be provided. Alternatively, dsn can be provided.')
203
+ if "host" not in self.connection_data and not any(
204
+ key in self.connection_data for key in ["sid", "service_name"]
205
+ ):
206
+ raise ValueError(
207
+ "Required parameter host and either sid or service_name must be provided. Alternatively, dsn can be provided."
208
+ )
186
209
 
187
- config['host'] = self.connection_data.get('host')
210
+ config["host"] = self.connection_data.get("host")
188
211
 
189
212
  # Optional connection parameters when 'dsn' is not given.
190
- optional_parameters = ['port', 'sid', 'service_name']
213
+ optional_parameters = ["port", "sid", "service_name"]
191
214
  for parameter in optional_parameters:
192
215
  if parameter in self.connection_data:
193
216
  config[parameter] = self.connection_data[parameter]
194
217
 
195
218
  # Other optional connection parameters.
196
- if 'disable_oob' in self.connection_data:
197
- config['disable_oob'] = self.connection_data['disable_oob']
219
+ if "disable_oob" in self.connection_data:
220
+ config["disable_oob"] = self.connection_data["disable_oob"]
198
221
 
199
- if 'auth_mode' in self.connection_data:
200
- mode_name = 'AUTH_MODE_' + self.connection_data['auth_mode'].upper()
222
+ if "auth_mode" in self.connection_data:
223
+ mode_name = "AUTH_MODE_" + self.connection_data["auth_mode"].upper()
201
224
  if not hasattr(oracledb, mode_name):
202
- raise ValueError(f'Unknown auth mode: {mode_name}')
203
- config['mode'] = getattr(oracledb, mode_name)
225
+ raise ValueError(f"Unknown auth mode: {mode_name}")
226
+ config["mode"] = getattr(oracledb, mode_name)
204
227
 
205
228
  try:
206
229
  connection = connect(
207
230
  **config,
208
231
  )
209
232
 
210
- if 'session_variables' in self.connection_data:
233
+ if "session_variables" in self.connection_data:
211
234
  with connection.cursor() as cur:
212
- for key, value in self.connection_data['session_variables'].items():
235
+ for key, value in self.connection_data["session_variables"].items():
213
236
  cur.execute(f"ALTER SESSION SET {key} = {repr(value)}")
214
237
 
215
238
  except DatabaseError as database_error:
216
- logger.error(f'Error connecting to Oracle, {database_error}!')
239
+ logger.error(f"Error connecting to Oracle, {database_error}!")
217
240
  raise
218
241
 
219
242
  except Exception as unknown_error:
220
- logger.error(f'Unknown error when connecting to Elasticsearch: {unknown_error}')
243
+ logger.error(f"Unknown error when connecting to Elasticsearch: {unknown_error}")
221
244
  raise
222
245
 
223
246
  self.is_connected = True
@@ -248,10 +271,10 @@ class OracleHandler(DatabaseHandler):
248
271
  con.ping()
249
272
  response.success = True
250
273
  except (ValueError, DatabaseError) as known_error:
251
- logger.error(f'Connection check to Oracle failed, {known_error}!')
274
+ logger.error(f"Connection check to Oracle failed, {known_error}!")
252
275
  response.error_message = str(known_error)
253
276
  except Exception as unknown_error:
254
- logger.error(f'Connection check to Oracle failed due to an unknown error, {unknown_error}!')
277
+ logger.error(f"Connection check to Oracle failed due to an unknown error, {unknown_error}!")
255
278
  response.error_message = str(unknown_error)
256
279
 
257
280
  if response.success and need_to_close: