Skip to content

Commit 5885d02

Browse files
authored
Merge pull request #68 from mindsdb/alter-kb
Alter knowledge base syntax
2 parents 6647d23 + 391825e commit 5885d02

File tree

5 files changed

+137
-53
lines changed

5 files changed

+137
-53
lines changed

mindsdb_sql_parser/__about__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
__title__ = 'mindsdb_sql_parser'
22
__package_name__ = 'mindsdb_sql_parser'
3-
__version__ = '0.11.4'
3+
__version__ = '0.12.0'
44
__description__ = "Mindsdb SQL parser"
55
__email__ = "[email protected]"
66
__author__ = 'MindsDB Inc'

mindsdb_sql_parser/ast/mindsdb/__init__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@
1717
from .drop_job import DropJob
1818
from .chatbot import CreateChatBot, UpdateChatBot, DropChatBot
1919
from .trigger import CreateTrigger, DropTrigger
20-
from .knowledge_base import CreateKnowledgeBase, DropKnowledgeBase, CreateKnowledgeBaseIndex, DropKnowledgeBaseIndex \
21-
, EvaluateKnowledgeBase
20+
from .knowledge_base import (
21+
CreateKnowledgeBase, DropKnowledgeBase, CreateKnowledgeBaseIndex, DropKnowledgeBaseIndex, AlterKnowledgeBase,
22+
EvaluateKnowledgeBase
23+
)
24+
2225
from .skills import CreateSkill, DropSkill, UpdateSkill
2326

2427
# remove it in next release

mindsdb_sql_parser/ast/mindsdb/knowledge_base.py

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,15 @@ def __init__(
3737

3838
def to_tree(self, *args, level=0, **kwargs):
3939
ind = indent(level)
40-
storage_str = f"{ind} storage={self.storage.to_string()},\n" if self.storage else ""
41-
model_str = f"{ind} model={self.model.to_string()},\n" if self.model else ""
42-
out_str = f"""
43-
{ind}CreateKnowledgeBase(
44-
{ind} if_not_exists={self.if_not_exists},
45-
{ind} name={self.name.to_string()},
46-
{ind} from_query={self.from_query.to_tree(level=level + 1) if self.from_query else None},
47-
{model_str}{storage_str}{ind} params={self.params}
48-
{ind})
49-
"""
40+
storage_str = f"{ind} storage={self.storage.to_string()},\n" if self.storage else ""
41+
model_str = f"{ind} model={self.model.to_string()},\n" if self.model else ""
42+
out_str = f"{ind}CreateKnowledgeBase(\n" \
43+
f"{ind} if_not_exists={self.if_not_exists},\n" \
44+
f"{ind} name={self.name.to_string()},\n" \
45+
f"{ind} from_query={self.from_query.to_tree(level=level + 1) if self.from_query else None},\n" \
46+
f"{ind}{model_str}{storage_str}{ind} params={self.params}\n" \
47+
f"{ind})"
48+
5049
return out_str
5150

5251
def get_string(self, *args, **kwargs):
@@ -80,6 +79,55 @@ def __repr__(self) -> str:
8079
return self.to_tree()
8180

8281

82+
class AlterKnowledgeBase(ASTNode):
83+
"""
84+
Update the knowledge base
85+
"""
86+
def __init__(
87+
self,
88+
name,
89+
params=None,
90+
*args,
91+
**kwargs,
92+
):
93+
"""
94+
Args:
95+
name: Identifier -- name of the knowledge base
96+
params: dict -- additional parameters to pass to the knowledge base. E.g., chunking strategy, etc.
97+
"""
98+
super().__init__(*args, **kwargs)
99+
self.name = name
100+
self.params = params
101+
def to_tree(self, *args, level=0, **kwargs):
102+
ind = indent(level)
103+
out_str = f"{ind}AlterKnowledgeBase(\n" \
104+
f"{ind} name={self.name.to_string()},\n" \
105+
f"{ind} params={self.params}\n" \
106+
f"{ind})"
107+
return out_str
108+
109+
def get_string(self, *args, **kwargs):
110+
111+
using_ar = []
112+
params = self.params.copy()
113+
if params:
114+
using_ar += [f"{k}={repr(v)}" for k, v in params.items()]
115+
if using_ar:
116+
using_str = "USING " + ", ".join(using_ar)
117+
else:
118+
using_str = ""
119+
120+
out_str = (
121+
f"ALTER KNOWLEDGE_BASE {self.name.to_string()} "
122+
f"{using_str}"
123+
)
124+
125+
return out_str
126+
127+
def __repr__(self) -> str:
128+
return self.to_tree()
129+
130+
83131
class DropKnowledgeBase(ASTNode):
84132
"""
85133
Delete a knowledge base

mindsdb_sql_parser/parser.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from mindsdb_sql_parser.ast.mindsdb.latest import Latest
2222
from mindsdb_sql_parser.ast.mindsdb.evaluate import Evaluate
2323
from mindsdb_sql_parser.ast.mindsdb.knowledge_base import CreateKnowledgeBase, DropKnowledgeBase, \
24-
CreateKnowledgeBaseIndex, DropKnowledgeBaseIndex, EvaluateKnowledgeBase
24+
AlterKnowledgeBase, CreateKnowledgeBaseIndex, DropKnowledgeBaseIndex, EvaluateKnowledgeBase
2525
from mindsdb_sql_parser.ast.mindsdb.skills import CreateSkill, DropSkill, UpdateSkill
2626
from mindsdb_sql_parser.exceptions import ParsingException
2727
from mindsdb_sql_parser.ast.mindsdb.retrain_predictor import RetrainPredictor
@@ -95,6 +95,7 @@ class MindsDBParser(Parser):
9595
'create_trigger',
9696
'drop_trigger',
9797
'create_kb',
98+
'alter_kb',
9899
'drop_kb',
99100
'evaluate_kb',
100101
'create_skill',
@@ -113,9 +114,6 @@ def query(self, p):
113114
@_(
114115
'CREATE KNOWLEDGE_BASE if_not_exists_or_empty identifier USING kw_parameter_list',
115116
'CREATE KNOWLEDGE_BASE if_not_exists_or_empty identifier',
116-
# from select
117-
'CREATE KNOWLEDGE_BASE if_not_exists_or_empty identifier FROM LPAREN select RPAREN USING kw_parameter_list',
118-
'CREATE KNOWLEDGE_BASE if_not_exists_or_empty identifier FROM LPAREN select RPAREN',
119117
)
120118
def create_kb(self, p):
121119
params = getattr(p, 'kw_parameter_list', {})
@@ -145,6 +143,19 @@ def create_kb(self, p):
145143
if_not_exists=if_not_exists
146144
)
147145

146+
@_(
147+
'ALTER KNOWLEDGE_BASE identifier USING kw_parameter_list',
148+
)
149+
def alter_kb(self, p):
150+
params = getattr(p, 'kw_parameter_list', {})
151+
name = p.identifier
152+
params = {k.lower(): v for k, v in params.items()} # case insensitive
153+
154+
return AlterKnowledgeBase(
155+
name=name,
156+
params=params
157+
)
158+
148159
@_('CREATE INDEX ON KNOWLEDGE_BASE identifier')
149160
def create_index(self, p):
150161
return CreateKnowledgeBaseIndex(name=p.identifier)

tests/test_mindsdb/test_knowledgebase.py

Lines changed: 58 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from mindsdb_sql_parser.ast.mindsdb.knowledge_base import (
44
CreateKnowledgeBase,
55
DropKnowledgeBase,
6+
AlterKnowledgeBase,
67
)
78
from mindsdb_sql_parser.ast import (
89
Select,
@@ -18,6 +19,7 @@
1819
)
1920
from mindsdb_sql_parser.utils import to_single_line
2021

22+
2123
class TestKB:
2224

2325
def test_create_knowledge_base(self):
@@ -60,42 +62,6 @@ def test_create_knowledge_base(self):
6062
ast = parse_sql(sql)
6163
assert ast == expected_ast
6264

63-
# create from a query
64-
sql = """
65-
CREATE KNOWLEDGE_BASE my_knowledge_base
66-
FROM (
67-
SELECT id, content, embeddings, metadata
68-
FROM my_table
69-
JOIN my_embedding_model
70-
)
71-
USING
72-
MODEL = mindsdb.my_embedding_model,
73-
STORAGE = my_vector_database.some_table
74-
"""
75-
ast = parse_sql(sql)
76-
expected_ast = CreateKnowledgeBase(
77-
name=Identifier("my_knowledge_base"),
78-
if_not_exists=False,
79-
model=Identifier(parts=["mindsdb", "my_embedding_model"]),
80-
storage=Identifier(parts=["my_vector_database", "some_table"]),
81-
from_select=Select(
82-
targets=[
83-
Identifier("id"),
84-
Identifier("content"),
85-
Identifier("embeddings"),
86-
Identifier("metadata"),
87-
],
88-
from_table=Join(
89-
left=Identifier("my_table"),
90-
right=Identifier("my_embedding_model"),
91-
join_type="JOIN",
92-
),
93-
),
94-
params={},
95-
)
96-
97-
assert ast == expected_ast
98-
9965
# create without MODEL
10066
sql = """
10167
CREATE KNOWLEDGE_BASE my_knowledge_base
@@ -189,6 +155,62 @@ def test_create_knowledge_base(self):
189155
)
190156
assert ast == expected_ast
191157

158+
def disabled_test_create_from_select(self):
159+
# create from a query
160+
sql = """
161+
CREATE KNOWLEDGE_BASE my_knowledge_base
162+
FROM (
163+
SELECT id, content, embeddings, metadata
164+
FROM my_table
165+
JOIN my_embedding_model
166+
)
167+
USING
168+
MODEL = mindsdb.my_embedding_model,
169+
STORAGE = my_vector_database.some_table
170+
"""
171+
ast = parse_sql(sql)
172+
expected_ast = CreateKnowledgeBase(
173+
name=Identifier("my_knowledge_base"),
174+
if_not_exists=False,
175+
model=Identifier(parts=["mindsdb", "my_embedding_model"]),
176+
storage=Identifier(parts=["my_vector_database", "some_table"]),
177+
from_select=Select(
178+
targets=[
179+
Identifier("id"),
180+
Identifier("content"),
181+
Identifier("embeddings"),
182+
Identifier("metadata"),
183+
],
184+
from_table=Join(
185+
left=Identifier("my_table"),
186+
right=Identifier("my_embedding_model"),
187+
join_type="JOIN",
188+
),
189+
),
190+
params={},
191+
)
192+
193+
assert ast == expected_ast
194+
195+
def test_update_knowledge_base(self):
196+
# create without select
197+
sql = """
198+
ALTER KNOWLEDGE_BASE my_kb
199+
USING
200+
reranking_model={'provider': 'openai'},
201+
embedding_model={'api_key': '123'}
202+
"""
203+
ast = parse_sql(sql)
204+
expected_ast = AlterKnowledgeBase(
205+
name=Identifier("my_kb"),
206+
params={
207+
'reranking_model': {'provider': 'openai'},
208+
'embedding_model': {'api_key': '123'},
209+
},
210+
)
211+
assert to_single_line(str(ast)) == to_single_line(str(expected_ast))
212+
assert ast == expected_ast
213+
192214
def test_drop_knowledge_base(self):
193215
# drop if exists
194216
sql = """

0 commit comments

Comments
 (0)