Skip to content

Commit f989abb

Browse files
authored
fix: redshift execute dynamic query (#264)
1 parent 440fb8f commit f989abb

5 files changed

Lines changed: 67 additions & 39 deletions

File tree

wavefront/server/plugins/datasource/datasource/__init__.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from .odata_parser import ODataQueryParser
1414

1515

16-
class DatasourcePlugin(DataSourceABC):
16+
class DatasourcePlugin:
1717
def __init__(
1818
self,
1919
datasource_type: DataSourceType,
@@ -65,7 +65,7 @@ def fetch_data(
6565
) -> QueryResult:
6666
where_clause, params = self.odata_parser.prepare_odata_filter(filter)
6767
join_query, table_aliases, join_where_clause, join_params = (
68-
self.odata_parser.prepare_odata_joins(join, table_name)
68+
self.odata_parser.prepare_odata_joins(join or '', table_name)
6969
)
7070

7171
where_clause = where_clause if where_clause else 'true'
@@ -110,13 +110,13 @@ async def execute_dynamic_query(
110110
rls_filter
111111
)
112112
result_by_query: Dict[str, Any] = await self.datasource.execute_dynamic_query(
113-
query,
114-
offset,
115-
limit,
116-
odata_filter,
117-
odata_params,
118-
odata_data_filter,
119-
odata_data_params,
120-
params,
113+
query=query,
114+
odata_filter=odata_filter,
115+
odata_params=odata_params,
116+
odata_data_filter=odata_data_filter,
117+
odata_data_params=odata_data_params,
118+
offset=offset,
119+
limit=limit,
120+
params=params,
121121
)
122122
return result_by_query

wavefront/server/plugins/datasource/datasource/bigquery/__init__.py

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,17 @@ def __init__(self, config: BigQueryConfig):
2020
async def test_connection(self) -> bool:
2121
return await self.client.test_connection()
2222

23-
def get_schema(self, table_id: str) -> dict:
24-
table_info = self.client.get_table_info(self.config.dataset_id, table_id)
25-
return table_info['schema'] or {}
23+
def get_schema(self) -> dict:
24+
tables = self.client.list_tables(self.config.dataset_id)
25+
return {
26+
table.table_id: (
27+
self.client.get_table_info(self.config.dataset_id, table.table_id).get(
28+
'schema'
29+
)
30+
or {}
31+
)
32+
for table in tables
33+
}
2634

2735
def get_table_names(self, **kwargs) -> list[str]:
2836
dataset_id = kwargs.get('dataset_id', self.config.dataset_id)
@@ -32,24 +40,29 @@ def get_table_names(self, **kwargs) -> list[str]:
3240
def fetch_data(
3341
self,
3442
table_names: List[str],
35-
projection: str = '*',
36-
where_clause: str = 'true',
43+
projection: Optional[str] = '*',
44+
where_clause: Optional[str] = 'true',
3745
join_query: Optional[str] = None,
3846
params: Optional[Dict[str, Any]] = None,
39-
offset: int = 0,
40-
limit: int = 1000,
47+
offset: Optional[int] = 0,
48+
limit: Optional[int] = 1000,
4149
order_by: Optional[str] = None,
4250
group_by: Optional[str] = None,
4351
) -> List[Dict[str, Any]]:
52+
projection_value = projection or '*'
53+
where_clause_value = where_clause or 'true'
54+
limit_value = limit if limit is not None else 1000
55+
offset_value = offset if offset is not None else 0
56+
4457
result = self.client.execute_query_to_dict(
45-
projection=projection,
58+
projection=projection_value,
4659
table_prefix=self.table_prefix,
4760
table_names=table_names,
48-
where_clause=where_clause,
61+
where_clause=where_clause_value,
4962
join_query=join_query,
5063
params=params,
51-
limit=limit,
52-
offset=offset,
64+
limit=limit_value,
65+
offset=offset_value,
5366
order_by=order_by,
5467
group_by=group_by,
5568
)
@@ -73,19 +86,19 @@ async def execute_query(
7386

7487
async def execute_dynamic_query(
7588
self,
76-
queries: List[Dict[str, Any]],
77-
offset: Optional[int] = 0,
78-
limit: Optional[int] = 100,
89+
query: List[Dict[str, Any]],
7990
odata_filter: Optional[str] = None,
8091
odata_params: Optional[Dict[str, Any]] = None,
8192
odata_data_filter: Optional[str] = None,
8293
odata_data_params: Optional[Dict[str, Any]] = None,
94+
offset: Optional[int] = 0,
95+
limit: Optional[int] = 100,
8396
params: Optional[Dict[str, Any]] = None,
8497
) -> Dict[str, Any]:
8598
results = {}
8699
tasks = []
87100

88-
for query_obj in queries:
101+
for query_obj in query:
89102
query_to_execute = query_obj.get('query', '')
90103
query_params = query_obj.get('parameters', [])
91104
query_id = query_obj.get('id')

wavefront/server/plugins/datasource/datasource/odata_parser.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def read_string(self, quote_char: str) -> str:
7979
self.advance()
8080

8181
if self.current_char == quote_char:
82-
result += self.current_char
82+
result += quote_char
8383
self.advance()
8484

8585
return result
@@ -217,8 +217,8 @@ def get_next_token(self) -> Token:
217217
class ODataParserABC(ABC):
218218
@abstractmethod
219219
def prepare_odata_filter(
220-
self, filter_expr: str, dynamic_var_char: str = '@'
221-
) -> Tuple[str, dict]:
220+
self, filter_expr: Optional[str]
221+
) -> Tuple[Optional[str], Optional[Dict[str, Any]]]:
222222
pass
223223

224224
@abstractmethod
@@ -240,7 +240,9 @@ def __init__(self, type: str, dynamic_var_char: str = '@'):
240240
else:
241241
raise ValueError(f'Invalid type: {self.type}')
242242

243-
def prepare_odata_filter(self, odata_filter: str) -> Dict[str, Any]:
243+
def prepare_odata_filter(
244+
self, odata_filter: Optional[str]
245+
) -> Tuple[Optional[str], Optional[Dict[str, Any]]]:
244246
return self.parser.prepare_odata_filter(odata_filter)
245247

246248
def prepare_odata_joins(
@@ -666,7 +668,9 @@ class SQLODataParser(ODataParserABC):
666668
def __init__(self, dynamic_var_char: str = '@'):
667669
self.dynamic_var_char = dynamic_var_char
668670

669-
def prepare_odata_filter(self, filter_expr: str) -> Tuple[str, dict]:
671+
def prepare_odata_filter(
672+
self, filter_expr: Optional[str]
673+
) -> Tuple[Optional[str], Optional[Dict[str, Any]]]:
670674
"""Parses an OData-like filter expression and converts it into a SQL-like query with parameters."""
671675
if not filter_expr:
672676
return None, None
@@ -800,6 +804,7 @@ def build_joins(
800804
sql_filter, filter_params = filter_parser.prepare_odata_filter(
801805
filter_expr
802806
)
807+
filter_params = filter_params or {}
803808
if sql_filter:
804809
# Prefix the filter with table name to avoid ambiguity
805810
# Replace @param with @table_param_ to match the new parameter names

wavefront/server/plugins/datasource/datasource/redshift/__init__.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,32 +22,41 @@ async def test_connection(self) -> bool:
2222
return await asyncio.to_thread(self.client.test_connection)
2323

2424
def get_schema(self) -> dict:
25-
return self.client.get_table_info()
25+
table_names = self.client.list_tables()
26+
return {
27+
table_name: self.client.get_table_info(table_name)
28+
for table_name in table_names
29+
}
2630

2731
def get_table_names(self, **kwargs) -> list[str]:
2832
return self.client.list_tables()
2933

3034
def fetch_data(
3135
self,
3236
table_names: List[str],
33-
projection: str = '*',
34-
where_clause: str = 'true',
37+
projection: Optional[str] = '*',
38+
where_clause: Optional[str] = 'true',
3539
join_query: Optional[str] = None,
3640
params: Optional[Dict[str, Any]] = None,
37-
offset: int = 0,
38-
limit: int = 10,
41+
offset: Optional[int] = 0,
42+
limit: Optional[int] = 10,
3943
order_by: Optional[str] = None,
4044
group_by: Optional[str] = None,
4145
) -> List[Dict[str, Any]]:
46+
projection_value = projection or '*'
47+
where_clause_value = where_clause or 'true'
48+
limit_value = limit if limit is not None else 10
49+
offset_value = offset if offset is not None else 0
50+
4251
return self.client.execute_query_to_dict(
43-
projection=projection,
52+
projection=projection_value,
4453
table_prefix=f'{self.db_name}.',
4554
table_names=table_names,
46-
where_clause=where_clause,
55+
where_clause=where_clause_value,
4756
join_query=join_query,
4857
params=params,
49-
limit=limit,
50-
offset=offset,
58+
limit=limit_value,
59+
offset=offset_value,
5160
order_by=order_by,
5261
group_by=group_by,
5362
)

wavefront/server/plugins/datasource/datasource/types.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ async def execute_dynamic_query(
9191
odata_data_params: Optional[Dict[str, Any]] = None,
9292
offset: Optional[int] = 0,
9393
limit: Optional[int] = 100,
94+
params: Optional[Dict[str, Any]] = None,
9495
) -> Dict[str, Any]:
9596
pass
9697

0 commit comments

Comments
 (0)