o
    i0                     @  s   U d dl mZ d dlZd dlZd dlZd dlZd dlmZ d dlZ	d dl
mZ d dlZejr8d dlmZ d dlZejeejeedejf f Zded< dddZd ddZd!ddZd"ddZd#ddZdS )$    )annotationsN)Decimalregister_io_source)Iterator_ExpressionTreeztyping_extensions.TypeAlias	predicatepl.Exprreturnduckdb.Expression | Nonec                 C  s>   t | jjdd}z
t|}t|W S  ty   Y dS w )a  Convert a Polars predicate expression to a DuckDB-compatible SQL expression.

    Parameters:
        predicate (pl.Expr): A Polars expression (e.g., col("foo") > 5)

    Returns:
        SQLExpression: A DuckDB SQL expression string equivalent.
        None: If conversion fails.

    Example:
        >>> _predicate_to_expression(pl.col("foo") > 5)
        SQLExpression("(foo > 5)")
    json)formatN)r   loadsmeta	serialize_pl_tree_to_sqlduckdbSQLExpression	Exception)r   tree
sql_filter r   D/home/ubuntu/.local/lib/python3.10/site-packages/duckdb/polars_io.py_predicate_to_expression   s   r   opstrc              	   C  s4   zddddddddd	|  W S  t y   t| w )
z}Map Polars binary operation strings to SQL equivalents.

    Example:
        >>> _pl_operation_to_sql("Eq")
        '='
    <z<=>z>==%ANDOR)LtLtEqGtGtEqEqModulusAndOr)KeyErrorNotImplementedError)r   r   r   r   _pl_operation_to_sql0   s   	
r,   
identifierc                 C  s   |  dd}d| dS )zEscape SQL identifiers by doubling any double quotes and wrapping in double quotes.

    Example:
        >>> _escape_sql_identifier('column"name')
        '"column""name"'
    "z"")replace)r-   escapedr   r   r   _escape_sql_identifierF   s   r1   r   c           $      C  s&  |   \}|dkrq| | }t|tsJ d| dt| |d |d |d }}}t|ts=J d| dt| t|tsNJ d| d	t| t|ts_J d
| dt| dt| dt| dt| dS |dkr| | }t|tsJ d| d	t| t|S |dv r| | }t|tsJ d| dt| t|S |dkr| | }t|ttfsJ dt| t|S |dkr| | }	t|	t	ttfsJ dt|	 t|	S |dkrw| | }
t|
tsJ d| dt|
 |
d }t|t
sJ d| dt| |d }t|ts*J d| dt| |
d }t|ts@J d| dt| d|v rn|d }t|d }|dkrZd| dS |dkred| dS d | }t|d!| }t||d"kr| | }t|tsJ d| dt| |d#}|d$kr|d%i }t|trd&|vrd'}t|n|d(krd)|}t||d% }t|tsJ d| dt| t|S |d*kr| | }t|tsJ d| dt| d+|v rd,|v rt|d+ }|d, }n
tt|  }|}t|ts(J d| d-t| t|ts:J d| d.t| |d/sE|d0kr|d0 }t|t
s[J d| d1t| d2t|  krid3kswn J d| d1t| d4tt|d td5|d6   S |d7s|d8kr|d8 }t|t
sJ d| d9t| tjj|d d: tjjd;}d<|d=S |d>v rt|| S |d?kr|d? }t|tsJ d| d@t| |dA }|dA dB }tjjtj||dC  }d<| dDS |dEkr/|dE }t|t	tfsJ d| dFt| tdGdHdHtj|dI }d<| dJS |dKkr^|dK } t| t
sJJ d| dLt|  t| }!dMdNdO |!D }"d<|" dPS |dQksh|dRkry|dR|dQdS}#tt|#S dT|dU| }t|dV| dW| |  }t|)Xa  Recursively convert a Polars expression tree (as JSON) to a SQL string.

    Parameters:
        tree (dict): JSON-deserialized expression tree from Polars

    Returns:
        str: SQL expression string

    Example:
        Input tree:
        {
            "BinaryExpr": {
                "left": { "Column": "foo" },
                "op": "Gt",
                "right": { "Literal": { "Int": 5 } }
            }
        }
        Output: "(foo > 5)"
    
BinaryExprzA z should be a dict but got leftr   rightz	LHS of a zThe op of a z should be a str but got z	RHS of a ( )ColumnzThe col name of a )LiteralDynIntz4The value of an Int should be an int or str but got Floatz;The value of a Float should be a float, int or str but got Functioninputz. should have a list of dicts as input but got r   functionz. should have a function dict as input but got BooleanIsNullz	 IS NULL)	IsNotNullz IS NOT NULL)z Boolean function not supported: zUnsupported function type: CastoptionsStrictexprr9   z;Strict cast on non-literal expression cannot be pushed down	NonStrictz9Only NonStrict/Strict casts can be safely unwrapped, got Scalardtypevaluez" should have a str dtype but got  z" should have a dict value but got z
{'Decimal'r   z. should be a two or three member list but got       z member list
   z{'Datetime'Datetimez% should be a one member list but got i@B )tz'z'::TIMESTAMP)Int8Int16Int32Int64Int128UInt8UInt16UInt32UInt64UInt128Float32Float64r@   Timez should be an int but got i ʚ;i  )secondsmicrosecondsz'::TIMEDatez should be a number but got i     )daysz'::DATEBinaryz should be a list but got  c                 s  s    | ]	}d |dV  qdS )z\x02xNr   ).0br   r   r   	<genexpr>  s    z"_pl_tree_to_sql.<locals>.<genexpr>z'::BLOBStringStringOwnedNzUnsupported scalar type z, with value zNode type: z is not implemented. )keys
isinstancedicttyper   r   r,   r1   intfloatlistr+   getnextiter
startswithlenr   datetimefromtimestamptimezoneutcmin	timedeltatimedatebytesjoinr   ConstantExpression)$r   	node_typebin_expr_treelhsr   rhscol_nameval_treeint_literalfloat_literal	func_treeinputs
input_tree	func_dictfuncarg_sqlmsg	cast_treerD   	cast_exprscalar_treerI   rJ   decimal_valuemicrosdt_timestampnanosecondsr_   r`   dt_timedays_since_epochr   	bin_valuebinary_datar0   
string_valr   r   r   r   Q   s   
""""$""
"$





$



$
$
$$  $

$

$r   relationduckdb.DuckDBPyRelationschemapl.schema.Schemapl.LazyFramec                   s   d fd
d}t ||dS )zA polars IO plugin for DuckDB.with_columnslist[str] | Noner   pl.Expr | Nonen_rows
int | None
batch_sizer
   Iterator[pl.DataFrame]c           	      3  s    d } }| d urd tt| }||}|d ur||}|d ur=ttt t	|}W d    n1 s8w   Y  |d urF|
|}|d u rN| n||}t|jd D ]}|d urm|d u rmt|
|V  qYt|V  qYd S )N,)r   mapr1   projectlimit
contextlibsuppressAssertionErrorr*   r   filterto_arrow_readerru   read_next_batchpl
from_arrow)	r   r   r   r   duck_predicaterelation_finalcolsresultsrecord_batchr   r   r   source_generator  s(   



z'duckdb_source.<locals>.source_generator)r   N)
r   r   r   r   r   r   r   r   r
   r   r   )r   r   r   r   r   r   duckdb_source  s   r   )r   r	   r
   r   )r   r   r
   r   )r-   r   r
   r   )r   r   r
   r   )r   r   r   r   r
   r   )
__future__r   r   rx   r   typingdecimalr   polarsr   polars.io.pluginsr   r   TYPE_CHECKINGcollections.abcr   typing_extensionsDictr   Unionrp   Anyr   __annotations__r   r,   r1   r   r   r   r   r   r   <module>   s&    &



 G