
    ɯei,                    X   d dl mZ d dlZd dlmZ d dlmZmZmZm	Z	 d dl
mZ d dlmZ d dlmZmZmZmZmZmZmZmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlm Z m!Z!m"Z"m#Z# ddl$m%Z% ddl&m'Z' erd dlm(Z( d dlm)Z) d dl*m+Z+  ee,      Z-	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ. G d dee/         Z0y)    )annotationsN)deque)ALL_COMPLETEDFutureProcessPoolExecutorwaitThreadPoolExecutor)	getLogger)TYPE_CHECKINGAnyCallableDequeIterableIteratorLiteraloverload   )IterUnit)NotSupportedError)pandas)pyarrow)ArrowResultBatchDownloadMetricsJSONResultBatchResultBatch)TelemetryField)get_time_millis)	DataFrame)Table)SnowflakeCursorc           
   +  &  K   j                  dd      }|rdfd}dd}	dfd}
dd<   ndfd}dd	}	dd
}
|r |       5 }t        j                  d       | E d{    |r`t        j                  d|d   j                           |j                   |	|j                               fi }|j                  |       |r`t        |t              \  }}d}|rdt        j                  d|         |
|j                         j                               E d{    t        j                  d|        |dz  }|rdddd        |        y |       5 }t        j                  d       t        t        t        |                  D ]]  }t        j                  d|d   j                          |j                   |j                   |	|j                               fi        _ | E d{    d}|rt        j                  d|        |r]t        j                  d|d   j                           |j                   |	|j                               fi }|j                  |       |j                         } |
|j                               }t        j                  d|        |E d{    t        j                  d|        |dz  }|rddd        |        y7 7 # 1 sw Y   xY w7 7 J# 1 sw Y   )xY ww)a  Creates an iterator over some other iterators.

    Very similar to itertools.chain but we need some keywords to be propagated to
    ``_download`` functions later.

    We need this to have ResultChunks fall out of usage so that they can be garbage
    collected.

    Just like ``ResultBatch`` iterator, this might yield an ``Exception`` to allow users
    to continue iterating through the rest of the ``ResultBatch``.
    is_fetch_allFc                     t               S N)r   prefetch_thread_nums   `/var/www/html/glpi_dashboard/venv/lib/python3.12/site-packages/snowflake/connector/result_set.pycreate_pool_executorz1result_set_iterator.<locals>.create_pool_executorA   s    &':;;    c                    | j                   S r%   )populate_databatchs    r(   create_fetch_taskz.result_set_iterator.<locals>.create_fetch_taskD   s    &&&r*   c                (     | j                   di S )N create_iter)future_resultkws    r(   get_fetch_resultz-result_set_iterator.<locals>.get_fetch_resultG   s    ,=,,2r22r*   N
connectionc                     t               S r%   r	   r&   s   r(   r)   z1result_set_iterator.<locals>.create_pool_executorM   s    %&9::r*   c                    | j                   S r%   r2   r-   s    r(   r/   z.result_set_iterator.<locals>.create_fetch_taskP   s    $$$r*   c                    | S r%   r1   )r4   s    r(   r6   z-result_set_iterator.<locals>.get_fetch_resultS   s      r*   z,beginning to schedule result batch downloadsz%queuing download of result batch id: r   )return_whenr   z"user began consuming result batch z(user requesting to consume result batch z%user finished consuming result batch )returnr   )r.   r   )r4   r   )r<   r
   )r4   r   )poploggerdebugidsubmitpopleftappendr   r   resultrangeminlen)first_batch_iterunconsumed_batchesunfetched_batchesfinalr'   use_mpr5   r#   r)   r/   r6   poolfuture_ibatch_iterators       ` `         r(   result_set_iteratorrR   )   s    ( 66.%0L	<	'	3  <	;	%	! !# 	tLLGH'''#;<Ma<P<S<S;TU %%&7&?&?&ABFH #))&1 $ *FDAqA$A!EF+,>,F,F,H,O,O,QRRRA!EFQ	 %	$ 	!# &	t LLGH32C8I4JKL ;<Ma<P<S<S;TU #))DKK 12C2K2K2M NURTU	 (''A$GsKL %LL?@QRS@T@W@W?XY )T[[)*;*C*C*EFJLF '--f5+335 "2&--/!BA!EF)))DQCHIQ- %!&	N 	s ( S	 	B (, *G&	 &	s   ALK3"K-#A%K3	AK3 K0!#K3LBL5L 6CL8L9#LL-K30K33K=8L LLL
Lc                      e Zd ZdZ	 	 	 	 	 	 	 	 	 	 ddZddZddZddZ	 	 ddZe	dd       Z
e	dd       Z
ddd	Z
dd
ZddZddZddZ	 	 ddZddZy)	ResultSeta  This class retrieves the results of a query with the historical strategy.

    It pre-downloads the first up to 4 ResultChunks (this doesn't include the 1st chunk
    as that is embedded in the response JSON from Snowflake) upon creating an Iterator
    on it.

    It also reports telemetry data about its ``ResultBatch``es once it's done iterating
    through them.

    Currently we do not support mixing multiple ``ResultBatch`` types and having
    different column definitions types per ``ResultBatch``.
    c                <    || _         || _        || _        || _        y r%   )batches_cursorr'   _use_mp)selfcursorresult_chunksr'   rL   s        r(   __init__zResultSet.__init__   s!     %#6 r*   c                   | j                   j                  Kt               | j                   j                  z
  }| j                   j                  t        j
                  |       | j                         }t        j                  j                  |v rQ| j                   j                  t        j                  |j                  t        j                  j                               t        j                  j                  |v rR| j                   j                  t        j                  |j                  t        j                  j                               yy)zReport all metrics totalled up.

        This includes TIME_CONSUME_LAST_RESULT, TIME_DOWNLOADING_CHUNKS and
        TIME_PARSING_CHUNKS in that order.
        N)rW   _first_chunk_timer   _log_telemetry_job_datar   TIME_CONSUME_LAST_RESULT_get_metricsr   downloadvalueTIME_DOWNLOADING_CHUNKSgetparseTIME_PARSING_CHUNKS)rY   time_consume_last_resultmetricss      r(   _report_metricszResultSet._report_metrics   s     <<))5!DLL$B$BB % LL00779Q ##%##))W4LL0066O44::;   &&'1LL0022O11778 2r*   c                $    | j                          y)z;Used for any cleanup after the result set iterator is done.N)rj   rY   s    r(   _finish_iteratingzResultSet._finish_iterating   s     	r*   c                d    t        | j                  d         }|t        k7  rt        d| d      y )Nr   z Trying to use arrow fetching on z which is not ArrowResultChunk)typerV   r   r   )rY   	head_types     r(   _can_create_arrow_iterz ResultSet._can_create_arrow_iter   sB     a)	((#29+ >* +  )r*   c                d    | j                          | j                  t        j                  d      S )zGFetches all the results as Arrow Tables, chunked by Snowflake back-end.arrow	iter_unit	structurerq   _create_iterr   
TABLE_UNITrl   s    r(   _fetch_arrow_batcheszResultSet._fetch_arrow_batches   s,     	##%  8+>+>' RRr*   c                     y r%   r1   rY   force_return_tables     r(   _fetch_arrow_allzResultSet._fetch_arrow_all   s    TWr*   c                     y r%   r1   r|   s     r(   r~   zResultSet._fetch_arrow_all   s    LOr*   c                    t        | j                               }|rt        j                  |      S |r| j                  d   j                         S dS )z=Fetches a single Arrow Table from all of the ``ResultBatch``.r   N)listrz   paconcat_tablesrV   to_arrow)rY   r}   tabless      r(   r~   zResultSet._fetch_arrow_all   sG    d//12##F++1C4<<?++-MMr*   c                h    | j                           | j                  dt        j                  dd|S )zFetches Pandas dataframes in batches, where batch refers to Snowflake Chunk.

        Thus, the batch size (the number of rows in dataframe) is determined by
        Snowflake's back-end.
        r   rt   r1   rw   )rY   kwargss     r(   _fetch_pandas_batcheszResultSet._fetch_pandas_batches   s=     	##% t   
))X
AG
 	
r*   c                ~   t        t        j                  t        j                        j
                        }t        |      D ci c]  }||v s||j                  |       }}t         | j                  dddi|      }|rt        j                  |fddi|S  | j                  d   j                  di |S c c}w )z"Fetches a single Pandas dataframe.r#   Tignore_indexr   r1   )r   inspect	signaturer   concat
parametersdictr=   r   rV   	to_pandas)rY   r   concat_argskconcat_kwargs
dataframess         r(   _fetch_pandas_allzResultSet._fetch_pandas_all   s    7,,V]];FFG37<Ta1CSFJJqM)TT4$44Q$Q&QR
==!    )t||A((2622 Us   	B:B:c                    i }| j                   D ]<  }|j                  j                         D ]  \  }}|j                  |d      |z   ||<    > |S )z6Sum up all the chunks' metrics and show them together.r   )rV   _metricsitemsre   )rY   overall_metricscnvs        r(   ra   zResultSet._get_metrics  sb    *, 	CA

((* C1%4%8%8A%>%B"C	C r*   c                "    | j                         S )z?Returns a new iterator through all batches with default values.)rx   rl   s    r(   __iter__zResultSet.__iter__  s      ""r*   c                   |j                  dd      }| j                  j                  |d<    | j                  d   j                  d
i |}t               }t        | j                  dd       }t        |      D ]-  \  }}t        j                  d|dz    d|j                          / t        |||| j                  | j                  f|| j                  d	|S )zSet up a new iterator through all batches with first 5 chunks downloaded.

        This function is a helper function to ``__iter__`` and it was introduced for the
        cases where we need to propagate some values to later ``_download`` calls.
        r#   Fr7   r   r   Nzresult batch z	 has id: )r#   rL   r1   )r=   rW   r7   rV   r3   r   	enumerater>   r?   r@   rR   rm   r'   rX   )rY   r   r#   rH   rI   rJ   numr.   s           r(   rx   zResultSet._create_iter  s     zz.%8  $||66|64<<?66@@ >CW "$,,qr"23#$56 	GJCLL=q	588*EF	G #""$$	
 &<<	
 	
 		
r*   c                J    d}| j                   D ]  }||j                  z  } |S )z1Returns the total rowcount of the ``ResultSet`` .r   )rV   rowcount)rY   totalps      r(   total_row_indexzResultSet.total_row_index:  s-     	 AQZZE	 r*   N)
rZ   r!   r[   z.list[JSONResultBatch] | list[ArrowResultBatch]r'   intrL   boolr<   None)r<   r   )r<   zIterator[Table])r}   zLiteral[False]r<   Table | None)r}   zLiteral[True]r<   r    )F)r}   r   r<   r   )r<   zIterator[DataFrame])r<   r   )r<   zdict[str, int])r<   Iterator[tuple])r<   z`Iterator[dict | Exception] | Iterator[tuple | Exception] | Iterator[Table] | Iterator[DataFrame])r<   r   )__name__
__module____qualname____doc__r\   rj   rm   rq   rz   r   r~   r   r   ra   r   rx   r   r1   r*   r(   rT   rT      s    

 F
 !	

 
 

2
S	S W WO ON	
3#'
		'
Rr*   rT   )rH   r   rI   zDeque[Future[Iterator[tuple]]]rJ   zDeque[ResultBatch]rK   zCallable[[], None]r'   r   rL   r   r5   r   r<   zJIterator[dict | Exception] | Iterator[tuple | Exception] | Iterator[Table])1
__future__r   r   collectionsr   concurrent.futuresr   r   r   r   concurrent.futures.threadr
   loggingr   typingr   r   r   r   r   r   r   r   	constantsr   errorsr   optionsr   r   r   result_batchr   r   r   r   	telemetryr   	time_utilr   r   r    snowflake.connector.cursorr!   r   r>   rR   r   rT   r1   r*   r(   <module>r      s    "   O O 8 	 	 	   %  "  & & :	8	i%i6i *i 	i
 i i i PiXj jr*   