diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e0184df4..5fef0fbe2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added `Trino` source - Added `MinIO` source - Added `gen_split()` method to `SAPRFCV2` class to allow looping over a data frame with generator - improves performance +- Added `adjust_where_condition_by_adding_missing_spaces()` to `SAPRFC`. The function that is checking raw sql query and modifing it - if needed. ### Changed diff --git a/src/viadot/sources/sap_rfc.py b/src/viadot/sources/sap_rfc.py index 5b4bb7876..176e3fb4a 100755 --- a/src/viadot/sources/sap_rfc.py +++ b/src/viadot/sources/sap_rfc.py @@ -33,6 +33,46 @@ logger = logging.getLogger() +def adjust_where_condition_by_adding_missing_spaces(sql: str) -> str: + """Function for adding white spaces between operators and `WHERE` statement. + This function is taking raw sql string and sanitizing it at the beginning of the + 'query()' method, so other methods that taking sql as parameter could have sql + without whitespaces issues. + + Args: + sql (str): raw sql query passed in flow + + Returns: + str: sql query after adding white spaces if needed + """ + + # Check if 'WHERE' statement is not attached to 'FROM' or column name as there is need for space " " on both side of 'WHERE' + sql = re.sub(rf'{re.escape("WHERE")}(?", "!=", "<=", ">=", "!<", "!>", "=", ">", "<"] + reverse_check = [ + "< >", + "! =", + "< =", + "> =", + "! <", + "! >", + ] + + for op in operators: + sql = re.sub(rf"(? str: raise ValueError( "WHERE conditions after the 75 character limit can only be combined with the AND keyword." ) + for val in client_side_filters.values(): + if ")" in val: + raise ValueError( + """Nested conditions eg. AND (col_1 = 'a' AND col_2 = 'b') found between or after 75 chararacters in WHERE condition! + Please change nested conditions part of query separeted with 'AND' keywords, or place nested conditions part at the begining of the where statement. + """ + ) else: filters_pretty = list(client_side_filters.items()) self.logger.warning( @@ -541,6 +588,7 @@ def query(self, sql: str, sep: str = None) -> None: sep = sep if sep is not None else self.sep + sql = adjust_where_condition_by_adding_missing_spaces(sql=sql) self.sql = sql self.extract_values(sql) @@ -866,6 +914,13 @@ def _get_where_condition(self, sql: str) -> str: raise ValueError( "WHERE conditions after the 75 character limit can only be combined with the AND keyword." ) + for val in client_side_filters.values(): + if ")" in val: + raise ValueError( + """Nested conditions eg. AND (col_1 = 'a' AND col_2 = 'b') found between or after 75 chararacters in WHERE condition! + Please change nested conditions part of query separeted with 'AND' keywords, or place nested conditions part at the begining of the where statement. + """ + ) else: filters_pretty = list(client_side_filters.items()) self.logger.warning( @@ -1000,6 +1055,7 @@ def query(self, sql: str, sep: str = None) -> None: sep = sep if sep is not None else self.sep + sql = adjust_where_condition_by_adding_missing_spaces(sql=sql) self.sql = sql self.extract_values(sql)