| 784 | sql_ast = ast_transformer(sql_ast) |
| 785 | return sql_ast, attr_offsets |
| 786 | def construct_delete_sql_ast(translator): |
| 787 | entity = translator.expr_type |
| 788 | expr_monad = translator.tree.elt.monad |
| 789 | if not isinstance(entity, EntityMeta): |
| 790 | throw(TranslationError, |
| 791 | 'Delete query should be applied to a single entity. Got: %s' % ast2src(translator.tree.expr)) |
| 792 | force_in = False |
| 793 | if translator.groupby_monads: |
| 794 | force_in = True |
| 795 | else: |
| 796 | assert not translator.having_conditions |
| 797 | tableref = expr_monad.tableref |
| 798 | from_ast = translator.sqlquery.from_ast |
| 799 | if from_ast[0] != 'FROM': |
| 800 | force_in = True |
| 801 | |
| 802 | if not force_in and len(from_ast) == 2 and not translator.sqlquery.used_from_subquery: |
| 803 | sql_ast = [ 'DELETE', None, from_ast ] |
| 804 | if translator.conditions: |
| 805 | sql_ast.append([ 'WHERE' ] + translator.conditions) |
| 806 | elif not force_in and translator.dialect == 'MySQL': |
| 807 | sql_ast = [ 'DELETE', tableref.alias, from_ast ] |
| 808 | if translator.conditions: |
| 809 | sql_ast.append([ 'WHERE' ] + translator.conditions) |
| 810 | else: |
| 811 | delete_from_ast = [ 'FROM', [ None, 'TABLE', entity._table_ ] ] |
| 812 | if len(entity._pk_columns_) == 1: |
| 813 | inner_expr = expr_monad.getsql() |
| 814 | outer_expr = [ 'COLUMN', None, entity._pk_columns_[0] ] |
| 815 | elif translator.rowid_support: |
| 816 | inner_expr = [ [ 'COLUMN', tableref.alias, 'ROWID' ] ] |
| 817 | outer_expr = [ 'COLUMN', None, 'ROWID' ] |
| 818 | elif translator.row_value_syntax: |
| 819 | inner_expr = expr_monad.getsql() |
| 820 | outer_expr = [ 'ROW' ] + [ [ 'COLUMN', None, column_name ] for column_name in entity._pk_columns_ ] |
| 821 | else: throw(NotImplementedError) |
| 822 | subquery_ast = [ 'SELECT', [ 'ALL' ] + inner_expr, from_ast ] |
| 823 | if translator.conditions: |
| 824 | subquery_ast.append([ 'WHERE' ] + translator.conditions) |
| 825 | delete_where_ast = [ 'WHERE', [ 'IN', outer_expr, subquery_ast ] ] |
| 826 | sql_ast = [ 'DELETE', None, delete_from_ast, delete_where_ast ] |
| 827 | return sql_ast |
| 828 | def get_used_attrs(translator): |
| 829 | if isinstance(translator.expr_type, EntityMeta) and not translator.aggregated and not translator.optimize: |
| 830 | return translator.tableref.used_attrs |