Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion mindsdb/api/http/namespaces/sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def post(self):
start_time = time.time()
query = request.json["query"]
context = request.json.get("context", {})
params = request.json.get("params", {})

if isinstance(query, str) is False or isinstance(context, dict) is False:
return http_error(HTTPStatus.BAD_REQUEST, "Wrong arguments", 'Please provide "query" with the request.')
Expand All @@ -55,7 +56,7 @@ def post(self):
mysql_proxy = FakeMysqlProxy()
mysql_proxy.set_context(context)
try:
result: SQLAnswer = mysql_proxy.process_query(query)
result: SQLAnswer = mysql_proxy.process_query(query, params=params)
query_response: dict = result.dump_http_response()
except ExecutorException as e:
# classified error
Expand Down
19 changes: 18 additions & 1 deletion mindsdb/api/mysql/mysql_proxy/executor/mysql_executor.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from mindsdb_sql_parser import parse_sql
from mindsdb_sql_parser.exceptions import ParsingException
from mindsdb_sql_parser.ast.base import ASTNode
from mindsdb_sql_parser.ast import Constant, Parameter, Tuple, NullConstant

import mindsdb.utilities.profiler as profiler
from mindsdb.api.executor.sql_query import SQLQuery
Expand All @@ -11,6 +12,7 @@
from mindsdb.api.executor.exceptions import SqlSyntaxError
from mindsdb.api.mysql.mysql_proxy.libs.constants.mysql import MYSQL_DATA_TYPE
from mindsdb.utilities import log
from mindsdb.integrations.utilities.query_traversal import query_traversal

logger = log.getLogger(__name__)

Expand Down Expand Up @@ -75,10 +77,25 @@ def stmt_execute(self, param_values):
self.do_execute()

@profiler.profile()
def query_execute(self, sql):
def query_execute(self, sql, params=None):
self.parse(sql)
if params:
self.apply_parameters(params)
self.do_execute()

def apply_parameters(self, params):
def fill_parameters(node, **kwargs):
if isinstance(node, Parameter):
if node.value in params:
value = params[node.value]
if value is None:
return NullConstant()
if isinstance(value, list):
return Tuple([Constant(i) for i in value])
return Constant(value)

query_traversal(self.query, fill_parameters)

@profiler.profile()
def parse(self, sql):
self.sql = sql
Expand Down
4 changes: 2 additions & 2 deletions mindsdb/api/mysql/mysql_proxy/mysql_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -498,10 +498,10 @@ def to_mysql_columns(self, columns_list: list[Column]) -> list[dict[str, str | i
return [column_to_mysql_column_dict(column, database_name=database_name) for column in columns_list]

@profiler.profile()
def process_query(self, sql) -> SQLAnswer:
def process_query(self, sql: str, params: dict = None) -> SQLAnswer:
log.log_ram_info(logger)
executor = Executor(session=self.session, sqlserver=self)
executor.query_execute(sql)
executor.query_execute(sql, params=params)
executor_answer = executor.executor_answer

if executor_answer.data is None:
Expand Down
2 changes: 1 addition & 1 deletion requirements/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ redis >=5.0.0, < 6.0.0
walrus==0.9.3
flask-compress >= 1.0.0
appdirs >= 1.0.0
mindsdb-sql-parser ~= 0.13.1
mindsdb-sql-parser ~= 0.13.2
pydantic == 2.11.4
mindsdb-evaluator == 0.0.20
duckdb == 1.3.0; sys_platform == "win32"
Expand Down
24 changes: 24 additions & 0 deletions tests/unit/api/http/test_queries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
class TestParameters:
def test_query_parameters(self, client):
# test filter, target
response = client.post(
"/api/sql/query",
json={
"query": "select NAME, :x from information_schema.databases where NAME=:db_name",
"params": {"db_name": "mindsdb", "x": 1, "not_used": "abc"},
},
)
data = response.json["data"]
assert data[0] == ["mindsdb", 1]

# tuples
response = client.post(
"/api/sql/query",
json={
"query": "select NAME, :x from information_schema.databases where NAME in :db_name",
"params": {"db_name": ["mindsdb", "my_pg"], "x": None},
},
)
data = response.json["data"]
assert data[0] == ["mindsdb", None]
print(response)
Loading