Coverage for mindsdb / utilities / sql.py: 92%

46 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-21 00:36 +0000

1def _is_in_quotes(pos: int, quote_positions: list[tuple[int, int]]) -> bool: 

2 """ 

3 Check if a position is within any quoted string. 

4 

5 Args: 

6 pos (int): The position to check. 

7 quote_positions (list[tuple[int, int]]): A list of tuples, each containing the start and 

8 end positions of a quoted string. 

9 

10 Returns: 

11 bool: True if the position is within any quoted string, False otherwise. 

12 """ 

13 return any(start < pos < end for start, end in quote_positions) 

14 

15 

16def clear_sql(sql: str) -> str: 

17 '''Remove comments (--, /**/, and oracle-stype #) and trailing ';' from sql 

18 Note: written mostly by LLM 

19 

20 Args: 

21 sql (str): The SQL query to clear. 

22 

23 Returns: 

24 str: The cleared SQL query. 

25 ''' 

26 if sql is None: 26 ↛ 27line 26 didn't jump to line 27 because the condition on line 26 was never true

27 raise ValueError('sql query is None') 

28 

29 # positions of (', ", `) 

30 quote_positions = [] 

31 for quote_char in ["'", '"', '`']: 

32 i = 0 

33 while i < len(sql): 

34 if sql[i] == quote_char and (i == 0 or sql[i - 1] != '\\'): 

35 start = i 

36 i += 1 

37 while i < len(sql) and (sql[i] != quote_char or sql[i - 1] == '\\'): 

38 i += 1 

39 if i < len(sql): 39 ↛ 41line 39 didn't jump to line 41 because the condition on line 39 was always true

40 quote_positions.append((start, i)) 

41 i += 1 

42 

43 # del /* */ comments 

44 result = [] 

45 i = 0 

46 while i < len(sql): 

47 if i + 1 < len(sql) and sql[i:i + 2] == '/*' and not _is_in_quotes(i, quote_positions): 

48 # skip until */ 

49 i += 2 

50 while i + 1 < len(sql) and sql[i:i + 2] != '*/': 

51 i += 1 

52 if i + 1 < len(sql): 52 ↛ 55line 52 didn't jump to line 55 because the condition on line 52 was always true

53 i += 2 # skip */ 

54 else: 

55 i += 1 

56 else: 

57 result.append(sql[i]) 

58 i += 1 

59 

60 sql = ''.join(result) 

61 

62 # del -- and # comments 

63 result = [] 

64 i = 0 

65 while i < len(sql): 

66 if i + 1 < len(sql) and sql[i:i + 2] == '--' and not _is_in_quotes(i, quote_positions): 

67 while i < len(sql) and sql[i] != '\n': 

68 i += 1 

69 elif sql[i] == '#' and not _is_in_quotes(i, quote_positions): 

70 while i < len(sql) and sql[i] != '\n': 

71 i += 1 

72 else: 

73 result.append(sql[i]) 

74 i += 1 

75 

76 sql = ''.join(result) 

77 

78 # del ; at the end 

79 sql = sql.rstrip() 

80 if sql and sql[-1] == ';': 80 ↛ 83line 80 didn't jump to line 83 because the condition on line 80 was always true

81 sql = sql[:-1].rstrip() 

82 

83 return sql.strip(' \n\t')