o
    9fA                     @   sn   d dl mZmZ d dlmZmZmZmZmZ d dlm	Z	 d dl
mZ d dlZddlmZ G dd	 d	ejZdS )
    )excliteral_column)compilerelementsCOLLECT_CARTESIAN_PRODUCTSWARN_LINTINGcrud)type_api)inspect_getfullargspecN   )typesc                       s  e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zd>ddZdd Zdd Z	d> fd d!	Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Z fd.d/Zd0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Zd:d; Zd<d= Z   Z!S )?ClickHouseSQLCompilerc                 K   s,   | j |jfi |d | j |jfi | S )Nz %% processleftrightselfbinaryoperatorkw r   l/var/www/Datamplify/venv/lib/python3.10/site-packages/clickhouse_sqlalchemy/drivers/compilers/sqlcompiler.pyvisit_mod_binary   s   z&ClickHouseSQLCompiler.visit_mod_binaryc                 K   ,   d| j |jfi || j |jfi |f S )a  
        Implementation of distinctness comparison in ClickHouse SQL.
        A distinctness comparison treats NULL as if it is a (singleton)
        value and is what ClickHouse uses for `SELECT DISTINCT` and `GROUP BY`.
        Some databases have direct support for a `IS DISTINCT` comparison, but
        ClickHouse does not, so we rely on the `hasAny` array function here.
        zhasAny([%s], [%s])r   r   r   r   r   !visit_is_not_distinct_from_binary   s   	z7ClickHouseSQLCompiler.visit_is_not_distinct_from_binaryc                 K      d| j ||fi | S NzNOT %s)r   r   r   r   r   visit_is_distinct_from_binary   s
   z3ClickHouseSQLCompiler.visit_is_distinct_from_binaryc                    s(   dd  fdd|pt gD f S )NzSELECT %s WHERE 1!=1, c                 3   s8    | ]}d  j jt|tjr|nt| V  qdS )zCAST(NULL AS %s)N)dialecttype_compilerr   
isinstancer   Nullable).0tr   r   r   	<genexpr>&   s    
z=ClickHouseSQLCompiler.visit_empty_set_expr.<locals>.<genexpr>)joinr   Int8)r   element_typesr   r&   r   visit_empty_set_expr$   s
   z*ClickHouseSQLCompiler.visit_empty_set_exprc                 C   s   | ddS )N%z%%)replace)r   textr   r   r   post_process_text/   s   z'ClickHouseSQLCompiler.post_process_textc                 K   s   d| j |jfi | S )Nzcount%s)r   clause_expr)r   fnr   r   r   r   visit_count_func2   s   z&ClickHouseSQLCompiler.visit_count_funcc                 K   s   d}|j d ur||j j| fi |d 7 }|jD ]\}}|d|j| fi | d |j| fi | d 7 }q|jd urL|d|jj| fi | d 7 }|d7 }|S )NzCASE  zWHEN z THEN zELSE END)value_compiler_dispatchwhenselse_)r   clausekwargsr.   condresultr   r   r   
visit_case6   s:   


z ClickHouseSQLCompiler.visit_casec                 K   sP   d| j |jjd fi || j |jjd fi || j |jjd fi |f S )Nz(%s) ? (%s) : (%s)r         )r   clauses)r   funcr   r   r   r   visit_if__funcH   s
   z$ClickHouseSQLCompiler.visit_if__funcc                 K   sx   d}|j }|r:|d7 }|jd ur|| j|jfi |d 7 }|| j|jfi |7 }|jj| fi |}|d| 7 }|S )N z LIMIT r   z BY )_limit_by_clauseoffsetr   limit
by_clausesr6   )r   selectr   r.   limit_by_clauselimit_by_exprsr   r   r   rI   O   s   
z%ClickHouseSQLCompiler.limit_by_clausec                 K   sp   d}|j d ur,|d7 }|jd ur|| j|jfi |d 7 }|| j|j fi |7 }|S |jd ur6td|S )NrC   z	 
 LIMIT r   z%OFFSET without LIMIT is not supported)_limit_clause_offset_clauser   r   CompileError)r   rH   r   r.   r   r   r   limit_clause^   s   



z"ClickHouseSQLCompiler.limit_clausec                 K   s   |j }t|}|jrtdz|j}W n ty    |j}Y nw |r(tdd|j	d }dd |j	D }|| j
|| fi |7 }|S )Nz$Lambdas with *args are not supportedz'Lambdas with **kwargs are not supportedr   z -> c                 S   s   g | ]}t |qS r   )r   )r$   argr   r   r   
<listcomp>~   s    z6ClickHouseSQLCompiler.visit_lambda.<locals>.<listcomp>)rA   r
   varargsr   rM   keywordsAttributeErrorvarkwr(   argsr   )r   lambda_r   rA   specrR   r.   rU   r   r   r   visit_lambdak   s   



z"ClickHouseSQLCompiler.visit_lambdac                 K   sZ   | j |j|j}| j|jfi |}|dkrd| S |dkr#d| S |dkr+d| S |S )Nyearz
toYear(%s)monthztoMonth(%s)dayztoDayOfMonth(%s))extract_mapgetfieldr   expr)r   extractr   r^   columnr   r   r   visit_extract   s   z#ClickHouseSQLCompiler.visit_extractFc           
      K   sn  |j j| fddi|}|d dkr|d dkr|dd }|j}t|ts*d|i}|d	}|d u rD|dr;d
}n|jrAd}nd}n| }|jrTd|v rTt	d|d}|rc| d | }|d}|rr| d | }|d ur|d|  d 7 }|j
}	||jj| fddi|7 }t|	tjr|d|	j| fddi| 7 }|S |d|	j| fi | 7 }|S )NasfromTr   ()r>   fulltypez
FULL OUTERz
LEFT OUTERINNERz=can't compile join with specified INNER type and isouter=True
strictnessr3   distributionz JOIN z USING include_tableFz ON )r   r6   rg   r"   dictr]   isouterupperr   rM   onclauser   r   Tuple)
r   r(   rc   r:   r.   flags	join_typerj   rk   rp   r   r   r   
visit_join   sN   





z ClickHouseSQLCompiler.visit_joinc                    ,   d d< dj d fdd|jD dS )NTwithin_columns_clausez 
ARRAY JOIN {columns}r   c                 3   &    | ]}|j fd di V  qdS within_label_clauseFNr6   r$   colr:   r   r   r   r'          

z9ClickHouseSQLCompiler.visit_array_join.<locals>.<genexpr>columnsformatr(   r@   r   
array_joinr:   r   r}   r   visit_array_join      z&ClickHouseSQLCompiler.visit_array_joinc                    ru   )NTrv   z 
LEFT ARRAY JOIN {columns}r   c                 3   rw   rx   rz   r{   r}   r   r   r'      r~   z>ClickHouseSQLCompiler.visit_left_array_join.<locals>.<genexpr>r   r   r   r   r}   r   visit_left_array_join   r   z+ClickHouseSQLCompiler.visit_left_array_joinc                    s0   |rt t| j||dS t t| j|fi |S )N)render_label_as_label)superr   visit_label)r   labelfrom_labeled_labelr   	__class__r   r   r      s   

z!ClickHouseSQLCompiler.visit_labelc	                    s"  |d |7 }jt@ rti t jt@ }	|r_nd d}	|rN|d7 }|jr=|d  fdd|D 7 }n|d fdd|D 7 }n|	 7 }t
|dd }
|
d uri|j|fi 7 }t
|dd d ur}||jjfi 7 }t
|d	d }|d ur| 7 }|jrj|jfd
i}|r|d| 7 }|	r  |jr|j|fi 7 }|jr͈j|jfi }|r|d| 7 }|jr|j|fi 7 }t
|dd }|d ur|j|fi 7 }|jr|j|fi 7 }|jd ur|j|fi 7 }|S )Nr   Fz 
FROM c                    s&   g | ]}|j fd  dqS )T)rc   	fromhintsfrom_linterrz   r$   fbyfromr   r:   r   r   r   rP   	  s    z>ClickHouseSQLCompiler._compose_select_body.<locals>.<listcomp>c                    s$   g | ]}|j fd  dqS )T)rc   r   rz   r   )r   r:   r   r   r   rP     s    _sample_clause_array_join_final_clauser   z 
WHERE z	 
HAVING rD   )r(   lintingr   r   
FromLintersetr   r   _hintsdefault_fromgetattrsample_clauser   r6   final_clause_where_criteria_generate_delimited_and_listwarn_group_by_clausesgroup_by_clause_having_criteria_order_by_clausesorder_by_clauserI   _has_row_limiting_clause_row_limit_clause_for_update_argfor_update_clause)r   r.   rH   compile_stateinner_columnsfromsr   toplevelr:   warn_lintingr   r   r%   rI   r   r   r   _compose_select_body   s~   

z*ClickHouseSQLCompiler._compose_select_bodyc                 K   s   d| j |jfi | S )Nz	 
SAMPLE )r   r   r   rH   r   r   r   r   r   T  s   z#ClickHouseSQLCompiler.sample_clausec                 C   s   dS )Nz 
FINALr   r&   r   r   r   r   W  s   z"ClickHouseSQLCompiler.final_clausec                 K   sd   d}|j j| fi |}|r0d| }t|ddr|d7 }t|ddr&|d7 }t|ddr0|d	7 }|S )
NrC   z
 GROUP BY 
_with_cubeFz
 WITH CUBE_with_rollupz WITH ROLLUP_with_totalsz WITH TOTALS)_group_by_clauser6   r   )r   rH   r   r.   group_byr   r   r   r   Z  s   z%ClickHouseSQLCompiler.group_by_clausec           	      K   s   | j js	td|j|| fi |}|j}|j}|jh|}| j	
|||d d}| ||j|}||d 7 }|jrR| j|jfddi|}|rQ|d| 7 }ntd| j	d	 |S )
Nz4ALTER DELETE is not supported by this server versioncorrelate_fromsasfrom_froms
selectableALTER TABLE z DELETErl   F WHERE WHERE clause is requiredre   )r    supports_deleter   rM   _compile_state_factory	statement_extra_fromstableunionstackappenddelete_table_clauser   r   pop)	r   delete_stmtr   r   extra_fromsr   r.   
table_textr%   r   r   r   visit_deleten  sJ   
z"ClickHouseSQLCompiler.visit_deletec           
      K   s   | j js	td|j|| fi |}|j}g }|jh}| j|||d d}| j	||j|fi |}t
j| ||dfi |}||7 }|d7 }|ddd |jD 7 }|jrm| j|jfd	d
i|}	|	rl|d|	 7 }ntd| jd |S )Nz4ALTER UPDATE is not supported by this server versionr   r   Tz UPDATE r   c                 s   s$    | ]\}}}}|d  | V  qdS )=Nr   )r$   cr_   r5   _r   r   r   r'     s    

z5ClickHouseSQLCompiler.visit_update.<locals>.<genexpr>rl   Fr   r   re   )r    supports_updater   rM   r   r   r   r   r   update_tables_clauser   _get_crud_paramsr(   single_paramsr   r   r   )
r   update_stmtr   r   render_extra_fromsr   r.   r   crud_paramsr%   r   r   r   visit_update  s`   

z"ClickHouseSQLCompiler.visit_updatec                    s<   t |trdd fdd|D  d S tt ||S )N[r   c                 3   s"    | ]}  |t|V  qd S N)render_literal_valuer	   _resolve_value_to_type)r$   xr&   r   r   r'     s    
z=ClickHouseSQLCompiler.render_literal_value.<locals>.<genexpr>])r"   listr(   r   r   r   )r   r5   type_r   r&   r   r     s   

z*ClickHouseSQLCompiler.render_literal_valuec                 C   s0   | j |jfi |}| j |jfi |}||fS r   r   )r   r   r   stringpatternr   r   r   _get_regexp_args  s   z&ClickHouseSQLCompiler._get_regexp_argsc                 K   s   |  ||\}}d||f S )Nzmatch(%s, %s))r   )r   r   r   r   r   r   r   r   r   visit_regexp_match_op_binary  s   z2ClickHouseSQLCompiler.visit_regexp_match_op_binaryc                 K   r   r   )r   r   r   r   r    visit_not_regexp_match_op_binary  s   z6ClickHouseSQLCompiler.visit_not_regexp_match_op_binaryc                 K   s   |j j| fi |S r   )elementr6   )r   r   r   r   r   r   $visit_ilike_case_insensitive_operand  s   z:ClickHouseSQLCompiler.visit_ilike_case_insensitive_operandc                 K   r   )Nz%s ILIKE %sr   r   r   r   r   visit_ilike_op_binary     z+ClickHouseSQLCompiler.visit_ilike_op_binaryc                 K   r   )Nz%s NOT ILIKE %sr   r   r   r   r   visit_not_ilike_op_binary  r   z/ClickHouseSQLCompiler.visit_not_ilike_op_binaryc                    s>   |j s|jr|jrdd fdd|jD  d S dS dS )NzDISTINCT ON (r   c                    s   g | ]}j |fi  qS r   )r   r{   r   r   r   r   rP      s    z?ClickHouseSQLCompiler.get_select_precolumns.<locals>.<listcomp>z) z	DISTINCT rC   )	_distinct_distinct_onr(   r   r   r   r   get_select_precolumns  s   z+ClickHouseSQLCompiler.get_select_precolumns)F)"__name__
__module____qualname__r   r   r   r+   r/   r2   r=   rB   rI   rN   rX   rb   rt   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r   r   r   r   r      s@    
6f+2r   )
sqlalchemyr   r   sqlalchemy.sqlr   r   r   r   r   r	   sqlalchemy.utilr
   #clickhouse_sqlalchemy.sql.functionsclickhouse_sqlalchemyrC   r   SQLCompilerr   r   r   r   r   <module>   s    