sqlglot.optimizer.lower_identities
1from sqlglot import exp 2 3 4def lower_identities(expression): 5 """ 6 Convert all unquoted identifiers to lower case. 7 8 Assuming the schema is all lower case, this essentially makes identifiers case-insensitive. 9 10 Example: 11 >>> import sqlglot 12 >>> expression = sqlglot.parse_one('SELECT Bar.A AS A FROM "Foo".Bar') 13 >>> lower_identities(expression).sql() 14 'SELECT bar.a AS A FROM "Foo".bar' 15 16 Args: 17 expression (sqlglot.Expression): expression to quote 18 Returns: 19 sqlglot.Expression: quoted expression 20 """ 21 # We need to leave the output aliases unchanged, so the selects need special handling 22 _lower_selects(expression) 23 24 # These clauses can reference output aliases and also need special handling 25 _lower_order(expression) 26 _lower_having(expression) 27 28 # We've already handled these args, so don't traverse into them 29 traversed = {"expressions", "order", "having"} 30 31 if isinstance(expression, exp.Subquery): 32 # Root subquery, e.g. (SELECT A AS A FROM X) LIMIT 1 33 lower_identities(expression.this) 34 traversed |= {"this"} 35 36 if isinstance(expression, exp.Union): 37 # Union, e.g. SELECT A AS A FROM X UNION SELECT A AS A FROM X 38 lower_identities(expression.left) 39 lower_identities(expression.right) 40 traversed |= {"this", "expression"} 41 42 for k, v in expression.iter_expressions(): 43 if k in traversed: 44 continue 45 v.transform(_lower, copy=False) 46 47 return expression 48 49 50def _lower_selects(expression): 51 for e in expression.expressions: 52 # Leave output aliases as-is 53 e.unalias().transform(_lower, copy=False) 54 55 56def _lower_order(expression): 57 order = expression.args.get("order") 58 59 if not order: 60 return 61 62 output_aliases = {e.alias for e in expression.expressions if isinstance(e, exp.Alias)} 63 64 for ordered in order.expressions: 65 # Don't lower references to output aliases 66 if not ( 67 isinstance(ordered.this, exp.Column) 68 and not ordered.this.table 69 and ordered.this.name in output_aliases 70 ): 71 ordered.transform(_lower, copy=False) 72 73 74def _lower_having(expression): 75 having = expression.args.get("having") 76 77 if not having: 78 return 79 80 # Don't lower references to output aliases 81 for agg in having.find_all(exp.AggFunc): 82 agg.transform(_lower, copy=False) 83 84 85def _lower(node): 86 if isinstance(node, exp.Identifier) and not node.quoted: 87 node.set("this", node.this.lower()) 88 return node
def
lower_identities(expression):
5def lower_identities(expression): 6 """ 7 Convert all unquoted identifiers to lower case. 8 9 Assuming the schema is all lower case, this essentially makes identifiers case-insensitive. 10 11 Example: 12 >>> import sqlglot 13 >>> expression = sqlglot.parse_one('SELECT Bar.A AS A FROM "Foo".Bar') 14 >>> lower_identities(expression).sql() 15 'SELECT bar.a AS A FROM "Foo".bar' 16 17 Args: 18 expression (sqlglot.Expression): expression to quote 19 Returns: 20 sqlglot.Expression: quoted expression 21 """ 22 # We need to leave the output aliases unchanged, so the selects need special handling 23 _lower_selects(expression) 24 25 # These clauses can reference output aliases and also need special handling 26 _lower_order(expression) 27 _lower_having(expression) 28 29 # We've already handled these args, so don't traverse into them 30 traversed = {"expressions", "order", "having"} 31 32 if isinstance(expression, exp.Subquery): 33 # Root subquery, e.g. (SELECT A AS A FROM X) LIMIT 1 34 lower_identities(expression.this) 35 traversed |= {"this"} 36 37 if isinstance(expression, exp.Union): 38 # Union, e.g. SELECT A AS A FROM X UNION SELECT A AS A FROM X 39 lower_identities(expression.left) 40 lower_identities(expression.right) 41 traversed |= {"this", "expression"} 42 43 for k, v in expression.iter_expressions(): 44 if k in traversed: 45 continue 46 v.transform(_lower, copy=False) 47 48 return expression
Convert all unquoted identifiers to lower case.
Assuming the schema is all lower case, this essentially makes identifiers case-insensitive.
Example:
>>> import sqlglot >>> expression = sqlglot.parse_one('SELECT Bar.A AS A FROM "Foo".Bar') >>> lower_identities(expression).sql() 'SELECT bar.a AS A FROM "Foo".bar'
Arguments:
- expression (sqlglot.Expression): expression to quote
Returns:
sqlglot.Expression: quoted expression