
    ɯei8q                       U d dl Z d dlZd dlZd dlZd dlZd dl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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mZmZmZmZmZmZm Z m!Z! d dl"Z"d dl#Z$d d	l%m&Z& d d
l'm(Z) d dl*m+c m,c m-c m.c m/Z- d dl0m+c m1Z1 d dl2m3Z3m4Z4 d dl5m6Z6m7Z7m8Z8 d dl9m:Z: d dl;m<Z< d dl=m>Z> d dl?m@Z@ d dlAmBZBmCZC d dlDmEZE d dlFmGZG d dlHmIZImJZJmKZK d dlLmMZM d dlNmOZOmPZP d dlQmRZRmSZSmTZT d dlUmVZV d dlWmXZX d dlYmZZZm[Z[m\Z\m]Z]m^Z^m_Z_ d dl`maZa d dlbmcZc d dldmeZemfZfmgZgmhZhmiZimjZjmkZkmlZlmmZmmnZnmoZompZp d dlqmrZr d dlsmtZt d d lumvZv d d!lwmxZxmyZymzZzm{Z{m|Z|m}Z} d d"l~mZ d d#lmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ d d$lmZmZ d d%lmZ d d&l0mZmZ d d'lmZ d d(lmZ d d)lmZmZ d d*lmZ d d+lmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ d d,lmZ d d-lmZ d d.lmZ d d/lmZ d d0lmZ d d1lmZmZ d d2lmZ d d3lmZ d d4lmZ d d5lmZ d d6lmZ d d7lmZmZ d d8lmZ d d9lmZ d d:lmZ d d;lmZ d d<lmZ d d=lmZmZ d d>lmZmZmZmZmZmZmZmZmZmZmZmZm Z 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 dAlmZ erd dlZd dBlmZ ej$                  dCk  r	d dDlmZ n	d dDlmZ  ee      Z e       Z e       ZedE   edF<   dGZdHZdIZdJZdKZdLZ dMZ!dNZ"dOZ#dPZ$dQZ%dRZ&dSZ'dTZ(dUZ)dVZ*dWZ+dXZ,dYZ-dZZ.d[Z/d\Z0d]Z1d^Z2d_Z3 e       rd`ndZ4e5eda<    e       rd`ndZ6e5edb<   djddZ7dcedE   fdeZ8dkdfZ9dldgZ:dkdhZ; G di dE      Z<y)m    N)array)defaultdict)reduce)	getLogger)RLock)
ModuleType)TYPE_CHECKINGAnyCallableDefaultDictDictListLiteralOptionalSequenceSetTupleUnion)Requirement)parse)ProgrammingErrorSnowflakeConnection)installed_pandaspandaspyarrow)write_pandas)UDFProfiler)analyzer_utils)Analyzer)result_scan_statementwrite_arrow)
str_to_sql)	Attribute)	SelectSQLSelectStatementSelectTableFunction)SnowflakePlanBuilder)RangeSnowflakeValues)FlattenFunctionGeneratorTableFunctionTableFunctionRelation)Cast)AstBatch)add_intermediate_stmtbuild_expr_from_python_valbuild_indirect_table_fn_applybuild_proto_from_struct_typebuild_table_namewith_src_position)SnowparkClientExceptionMessages)EventTableTelemetry)DEFAULT_PACKAGESENVIRONMENT_METADATA_FILE_NAMEIMPLICIT_ZIP_FILE_NAME"delete_files_belonging_to_packagesdetect_native_dependenciesget_signatureidentify_supported_packages(map_python_packages_to_files_and_folders!parse_conda_environment_yaml_fileparse_requirements_text_file%pip_install_packages_to_target_folderzip_directory_contents)ServerConnection)set_api_call_source)TempTableAutoCleaner)ColumnOrNameconvert_sp_to_sf_typeinfer_schema
infer_type
merge_typetype_string_to_type_object)generate_call_python_sp_sql)*MODULE_NAME_TO_PACKAGE_NAME_MAPSTAGE_PREFIXSUPPORTED_TABLE_TYPESXPATH_HANDLERS_FILE_PATHXPATH_HANDLER_MAPPythonObjJSONEncoderTempObjectTypecalculate_checksumcheck_flatten_modecreate_rlockcreate_thread_local
deprecatedescape_quotesexperimentalexperimental_parameterget_connector_versionget_os_nameget_python_versionget_stage_file_prefix_lengthget_temp_type_for_objectget_versionimport_or_missing_modin_pandasis_in_stored_procedurenormalize_local_filenormalize_remote_file_or_dirparse_positional_args_to_list&parse_positional_args_to_list_variadic	publicapi
quote_namerandom_name_for_temp_object3strip_double_quotes_in_like_statement_in_table_nameunwrap_single_quote"unwrap_stage_location_single_quotevalidate_object_name0warn_session_config_update_in_multithreaded_modewarningzip_file_or_directory_to_streamset_ast_stateis_ast_enabledAstFlagSourceAstModeprivate_preview)AsyncJob_AsyncResultType)Column)._is_execution_environment_sandboxed_for_client_use_scoped_temp_objects)	DataFrameDataFrameReader)SnowparkClientExceptionSnowparkSessionException)FileOperation)to_file	array_aggcolcolumnlit
parse_jsonto_date
to_decimalto_geographyto_geometryto_timeto_timestampto_timestamp_ltzto_timestamp_ntzto_timestamp_tz
to_variant)Lineage)MockAnalyzerMockServerConnection)NopAnalyzer)NopConnection)_convert_dataframe_to_table'_extract_schema_and_data_from_pandas_df)MockSnowflakePlanBuilder)MockStoredProcedureRegistration)MockUDAFRegistration)MockUDFRegistration)MockUDTFRegistration)AstListenerQueryHistory)Row)StoredProcedureRegistration)StoredProcedureProfiler)DataframeProfiler)Table)TableFunctionCall!_create_table_function_expression)	ArrayTypeBooleanTypeDateTypeDayTimeIntervalTypeDecimalType	FloatTypeGeographyTypeGeometryTypeIntegerTypeMapType
StringTypeStructField
StructTypeTimestampTimeZoneTimestampTypeTimeTypeVariantType
VectorTypeYearMonthIntervalTypeFileType_AtomicType)UDAFRegistration)UDFRegistration)UDTFRegistration)UserDefinedFunction)   	   )IterableSession_active_sessions'PYTHON_SNOWPARK_USE_SCOPED_TEMP_OBJECTS"PYTHON_SNOWPARK_USE_SQL_SIMPLIFIER5PYTHON_SNOWPARK_USE_LOGICAL_TYPE_FOR_CREATE_DATAFRAME)PYTHON_SNOWPARK_COMPILATION_STAGE_ENABLED,PYTHON_SNOWPARK_USE_CTE_OPTIMIZATION_VERSION8PYTHON_SNOWPARK_ELIMINATE_NUMERIC_SQL_VALUE_CAST_ENABLED8PYTHON_SNOWPARK_AUTO_CLEAN_UP_TEMP_TABLE_ENABLED_VERSION-PYTHON_SNOWPARK_REDUCE_DESCRIBE_QUERY_ENABLED>PYTHON_SNOWPARK_USE_LARGE_QUERY_BREAKDOWN_OPTIMIZATION_VERSION<PYTHON_SNOWPARK_LARGE_QUERY_BREAKDOWN_COMPLEXITY_UPPER_BOUND<PYTHON_SNOWPARK_LARGE_QUERY_BREAKDOWN_COMPLEXITY_LOWER_BOUND*PYTHON_SNOWPARK_ENABLE_THREAD_SAFE_SESSION:PYTHON_SNOWPARK_COLLECT_TELEMETRY_AT_CRITICAL_PATH_VERSION2PYTHON_SNOWPARK_ENABLE_SCOPED_TEMP_READ_ONLY_TABLE0PYTHON_SNOWPARK_DATAFRAME_JOIN_ALIAS_FIX_VERSIONPYTHON_SNOWPARK_CLIENT_AST_MODE*PYTHON_SNOWPARK_CLIENT_MIN_VERSION_FOR_AST*PYTHON_SNOWPARK_GENERATE_MULTILINE_QUERIES%ENABLE_SNOWPARK_FIRST_PARTY_TELEMETRY2SNOWPARK_PANDAS_DUMMY_ROW_POS_OPTIMIZATION_ENABLED(SNOWPARK_PANDAS_HYBRID_EXECUTION_ENABLEDPYTHON_SNOWPARK_USE_ASTFi i  i WRITE_PANDAS_CHUNK_SIZEWRITE_ARROW_CHUNK_SIZEreturnc                     t         5  t        t              dk(  r!t        t	        t                    cd d d        S t        t              dkD  rt        j                         t        j                         # 1 sw Y   y xY wN   )_session_management_locklenr   nextiterr5   MORE_THAN_ONE_ACTIVE_SESSIONSSERVER_NO_DEFAULT_SESSION     \/var/www/html/glpi_dashboard/venv/lib/python3.12/site-packages/snowflake/snowpark/session.py_get_active_sessionr   E  sn    	! N A%-./N N !"Q&1OOQQ1KKMMN Ns   *A5:A55A>c                      t         5  t        t              dk\  rt        cd d d        S t        j                         # 1 sw Y   y xY wr   )r   r   r   r5   r   r   r   r   _get_active_sessionsr   O  sH    	! N A% $	N N 2KKMMN Ns   ==Ac                 d    t         5  t        j                  |        d d d        y # 1 sw Y   y xY wN)r   r   addsessions    r   _add_sessionr   Y  s(    	! &W%& & &s   &/c                 6    t         rd } | S | xs
 t               } | S r   )rz   r   r   s    r   '_get_sandbox_conditional_active_sessionr   ^  s&    5 N 202Nr   c                     t         5  	 t        j                  |        d d d        y # t        $ r Y w xY w# 1 sw Y   y xY wr   )r   r   removeKeyErrorr   s    r   _remove_sessionr   g  sF    	! 	##G,   		 s   6'	3636?c            &       Z   e Zd ZU dZ G d d      Z G d d      Z e       Zeed<   	 ddee	e
ef   d	eeeef      d
dfdZddZd Zd Zd Zd Zd Zded
efdZd
efdZed
efd       Zed
ed    fd       ZeZ e e!d      d               Z"ddZ#ed
efd       Z$ed
efd       Z%ed
efd       Z&e&jN                   e(d      ded
dfd               Z&ed
efd!       Z)ed
efd"       Z*ed
efd#       Z+ed
efd$       Z,ed
e-eef   fd%       Z.ed
efd&       Z/ed
efd'       Z0ed
efd(       Z1ed
efd)       Z2e%jN                  ded
dfd*       Z%e)jN                  ded
dfd+       Z)e*jN                   e(d,      ded
dfd-              Z*e+jN                   e(d.      ded
dfd/              Z+e,jN                   e(d0      ded
dfd1              Z,e.jN                  de-eef   d
dfd2       Z.e/jN                   e(d3      ded
dfd4              Z/e0jN                  ded
dfd5       Z0e1jN                  ded
dfd6       Z1e2jN                   e(d7      d8ed
dfd9              Z2dd:Z3d
e4e   fd;Z5	 	 	 dd=ed>ee   d?ed@ed
df
dAZ6d=ed
dfdBZ7ddCZ8e9	 	 	 dd=ed>ee   d?ed@ed
e-eee   ee   f   f
dD       Z:	 dddEdFedGedHeeee-ee   ee   f   f      dIeeeef      d
e4e   f
dJZ;	 dddEdKee   dIeeeef      d
e<e   fdLZ=ddMee   d
eeef   fdNZ>ddOdPeee?e@eee?f      f   dMee   d
dfdQZA	 ddRedMee   d
dfdSZB	 ddMee   d
dfdTZC	 ddUedMee   d
dfdVZD e!dW      	 ddXe<e   dYed
dfdZ       ZEe9dPe4eee?f      d
eee-eeeFf   f   fd[       ZG	 	 dd\eee-eeeFf   f   d]ed^ed_eeef   dIeeeef      d`ed
e4eF   fdaZHe9dbe4eee?f      dceeef   d
e4e   fdd       ZI	 	 	 	 	 ddPe4eee?f      dfeeeef      d]edgedIeeeef      dMee   d
e4e   fdhZJdPe4e   d^ed\eeef   dieeef   d
e4eF   f
djZKd
efdkZLdledmed
e4eF   fdnZM	 	 ddoe4e   dped]edIeeeef      d
eee4e   f   f
dqZNed
ee   fdr       ZOeOjN                  dsed
dfdt       ZOd
efduZPddsedved
dfdwZQdseRd
dfdxZSeT	 	 ddddddddydzeee@e   f   d{ed|ed}eeUd~      dee   dee   deeeeVj                  f      deeeeWf      dee   d
eXfd       ZYeTdeddeee4e   eZdef   e[f   de\d|ede\d
e]f
d       Z^eTdddedde_deded|ed
e]f
d       Z`eT	 	 	 ddedeeae      debj                  d|ed
e]f
d       Zdedd       Zeed
efd       Zfedd       Zg	 	 	 ddedededIeeeef      d
e4e   f
dZh	 ddedeeae      d
e4ei   fdZj	 ddIeeeef      d
efdZk e!d      eTddelddd<dded<d<dddeddddedee   dee   d?ee   dedededededededeUd   dee   d|edeeef   d
eXf"d              Zm	 	 	 	 	 	 	 	 dded   dededee   dee   dededededed   deUd   d
dfdZneTddeodddded<d<d<ddd<dedded   dedee   dee   d?ee   dedededededededeUd   dee   ded|edeeef   d
eXf$d       ZpeT	 	 d dee4e-ddf   deeeqe@e   ef      d|edeeef   d
e]f
d       ZreT	 	 	 d!dedee   ded|ed
e]f
dƄ       Zsded
etfdȄZud
ee   fdɄZvd
ee   fdʄZwd
ee   fd˄Zxd
ee   fd̄Zyd
efd̈́Zzdzed
efd΄Z{d
ee   fdτZ|d
ee   fdЄZ}ded
dfdфZ~ded
dfd҄Zded
dfdԄZded
dfdքZdeeUd      d
dfdلZdeded
dfd܄Zed
efd݄       ZejN                  dބ        Zed
efd߄       Zed
efd       Zed
efd       Zed
efd       Zed
efd       Zed
efd       Zed
efd       Ze ed      d
efd              Zed
efd       Zed
efd       Zd<ddededed
efdZeTdded<ddeddededIeeeef      dededee   d|ed
eeetf   fd       ZeTdd<ddeddededIeeeef      dedee   d|ed
etfd       Zddd<dededdededIeeeef      dee   ded|eded
eeetf   fdZ eddd      eT	 	 	 	 	 d"de\d=ee   dededed|ed
e]fd              Z	 	 	 	 d#d edededed
ef
dZd$ded
efdZde@e   fdZded
ee   fdZd	eUd
   d
dfdZerZ	 	 	 d%dedededIeeeef      ded
eeetf   fdZd&ded|ed
e]fdZeT	 d dzee   d|ed
dfd       ZeTd&d|ed
dfd       ZeTd&d|ed
dfd       Zy('  r   a  
    Establishes a connection with a Snowflake database and provides methods for creating DataFrames
    and accessing objects for working with files in stages.

    When you create a :class:`Session` object, you provide connection parameters to establish a
    connection with a Snowflake database (e.g. an account, a user name, etc.). You can
    specify these settings in a dict that associates connection parameters names with values.
    The Snowpark library uses `the Snowflake Connector for Python <https://docs.snowflake.com/en/user-guide/python-connector.html>`_
    to connect to Snowflake. Refer to
    `Connecting to Snowflake using the Python Connector <https://docs.snowflake.com/en/user-guide/python-connector-example.html#connecting-to-snowflake>`_
    for the details of `Connection Parameters <https://docs.snowflake.com/en/user-guide/python-connector-api.html#connect>`_.

    To create a :class:`Session` object from a ``dict`` of connection parameters::

        >>> connection_parameters = {
        ...     "user": "<user_name>",
        ...     "password": "<password>",
        ...     "account": "<account_name>",
        ...     "role": "<role_name>",
        ...     "warehouse": "<warehouse_name>",
        ...     "database": "<database_name>",
        ...     "schema": "<schema_name>",
        ... }
        >>> session = Session.builder.configs(connection_parameters).create() # doctest: +SKIP

    To create a :class:`Session` object from an existing Python Connector connection::

        >>> session = Session.builder.configs({"connection": <your python connector connection>}).create() # doctest: +SKIP

    :class:`Session` contains functions to construct a :class:`DataFrame` like :meth:`table`,
    :meth:`sql` and :attr:`read`, etc.
    c                   `    e Zd Zdddeeef   ddfdZddedefdZdedefd	Z	ded
eddfdZ
y)Session.RuntimeConfigr   r   confr   Nc                     || _         ddddd| _        | j                   j                  | _        |j                         D ])  \  }}| j	                  |      s| j                  ||       + y )NTF)use_constant_subquery_alias'flatten_select_after_filter_and_orderbycollect_stacktrace_in_query_taguse_simplified_query_generation)_session_conf_lockitems
is_mutableset)selfr   r   keyvals        r   __init__zSession.RuntimeConfig.__init__  sd    #DM/3;?3838	DJ ,,DJ JJL 'S??3'HHS#&'r   r
  c                    | j                   5  t        t        |      rt        | j                  |      cd d d        S t        | j                  j
                  j
                  |      r3t        | j                  j
                  j
                  |      cd d d        S | j                  j                  ||      cd d d        S # 1 sw Y   y xY wr   )r  hasattrr   getattrr  _connr  get)r	  r
  defaults      r   r  zSession.RuntimeConfig.get  s     47C("4==#64 4 4==..44c:"4==#6#6#<#<cB	4 4
 zz~~c734 4 4s   &B?AB?B??Cc                    | j                   5  t        t        |      rCt        t	        t        |      t
              r%t	        t        |      j                  d ucd d d        S t        t        |      rCt        t	        t        |      t
              r%t	        t        |      j                  d ucd d d        S || j                  v cd d d        S # 1 sw Y   y xY wr   )	r  r  r   
isinstancer  propertyfsetr   r  r	  r
  s     r   r  z Session.RuntimeConfig.is_mutable  s     	)7C(ZGS)8. #7C055TA		) 	)
 .4/5x: ##6<AAM	) 	) djj(	) 	) 	)s   A
C!A	C4CCvaluec                    | j                   5  | j                  |      rt        t        |      rt	        | j
                  ||       t        t        |      r+t	        | j
                  j                  j                  ||       || j                  v r|| j                  |<   nt        d| d      d d d        y # 1 sw Y   y xY w)NzConfiguration "z-" does not exist or is not mutable in runtime)
r  r  r  r   setattrr  r   r  r  AttributeErrorr	  r
  r  s      r   r  zSession.RuntimeConfig.set  s     ??3'w,sE:2C8 3 3 9 93Fdjj(*/

3()#.[\   s   B!B77C r   )__name__
__module____qualname__r   strr
   r  r  boolr  r  r   r   r   RuntimeConfigr     sd    	'I 	'T#s(^ 	' 	'	43 	4 	4
	)# 
	)$ 
	)	3 	s 	t 	r   r"  c                       e Zd ZdZddZdedd fdZ	 ddededd fd	Zded
e	e
ef   dd fdZdeee	e
ef   f   dd fdZddZddZ	 ddee   ddfdZeZddZy)Session.SessionBuilderz^
        Provides methods to set connection parameters and create a :class:`Session`.
        r   Nc                 .    i | _         d | _        d | _        y r   )_options	_app_name_format_jsonr	  s    r   r  zSession.SessionBuilder.__init__  s    DM!DN $Dr   r
  c                 >    | j                   j                  |d       | S )zOnly used in test.N)r&  popr  s     r   _remove_configz%Session.SessionBuilder._remove_config  s    MMc4(Kr   app_nameformat_jsonc                 "    || _         || _        | S )a  
            Adds the app name to the :class:`SessionBuilder` to set in the query_tag after session creation

            Args:
                app_name: The name of the application.
                format_json: If set to `True`, it will add the app name to the session query tag in JSON format,
                    otherwise, it will add it using a key=value format.

            Returns:
                A :class:`SessionBuilder` instance.

            Example::
                >>> session = Session.builder.app_name("my_app").configs(db_parameters).create() # doctest: +SKIP
                >>> print(session.query_tag) # doctest: +SKIP
                APPNAME=my_app
                >>> session = Session.builder.app_name("my_app", format_json=True).configs(db_parameters).create() # doctest: +SKIP
                >>> print(session.query_tag) # doctest: +SKIP
                {"APPNAME": "my_app"}
            )r'  r(  )r	  r-  r.  s      r   r-  zSession.SessionBuilder.app_name  s    , &DN +DKr   r  c                 $    || j                   |<   | S )zo
            Adds the specified connection parameter to the :class:`SessionBuilder` configuration.
            r&  r  s      r   configzSession.SessionBuilder.config  s     "'DMM#Kr   optionsc                 0    i | j                   || _         | S )a3  
            Adds the specified :class:`dict` of connection parameters to
            the :class:`SessionBuilder` configuration.

            Note:
                Calling this method overwrites any existing connection parameters
                that you have already set in the SessionBuilder.
            r1  )r	  r3  s     r   configszSession.SessionBuilder.configs  s     9t}}88DMKr   r   c                    | j                   j                  dd      rRt        t        | j                         | j                         }d| j                   v rd| j                   d<   t	        |       n| j                   j                  dd      rRt        t        | j                         | j                         }d| j                   v rd| j                   d<   t	        |       n*| j                  | j                   j                  d            }| j                  rM| j                  r!d| j                  i}|j                  |       |S d| j                   }|j                  |       |S )	zCreates a new Session.local_testingFpasswordNnop_testing
connectionAPPNAMEzAPPNAME=)r&  r  r   r   r   r   _create_internalr'  r(  update_query_tagappend_query_tag)r	  r   app_name_tags      r   createzSession.SessionBuilder.create  s   }}  %8!"6t}}"Et}}U.04DMM*-W%""=%8!-">N.04DMM*-W%//0A0A,0OP~~$$$-t~~#>L,,\:
 N &.dnn-=#>L,,\:Nr   c                     	 t               }|j                  j                  j                  rt        |       | j	                         S |S # t
        $ r*}|j                  dk(  r| j	                         cY d}~S  d}~ww xY w)z=Gets the last created session or creates a new one if needed.1403N)r   r  expiredr   r@  r   
error_code)r	  r   exs      r   getOrCreatez"Session.SessionBuilder.getOrCreate  sf    	-/==&&..#G,;;=(* ==F*;;=(s*   AA	 A	 		A<A70A<6A77A<connc                 R   t               s |s| j                  sddlm}  |       | _        d| j                  vrd| j                  d<   t	        |rt        i |      nt        | j                        | j                        }d| j                  v rd | j                  d<   t        |       |S )Nr   )_get_default_connection_params
paramstyleqmarkr8  )rc   r&  "snowflake.connector.config_managerrI  r   rC   r   )r	  rG  rI  new_sessions       r   r<  z'Session.SessionBuilder._create_internal%  s     *+D !? @ 4==0.5l+!.2 T*8H8WK
 T]]*,0j)%r   c                 *    t         j                         S r   )r   SessionBuilder)r	  objobjtypes      r   __get__zSession.SessionBuilder.__get__A  s    ))++r   r   NFr   r   r   )r  r  r  __doc__r  r   r,  r!  r-  r   intr2  r   r5  r@  rF  r   r   r<  appNamerR  r   r   r   rO  r$    s    		%
	c 	.F 	 6;		.2	%	4	c 	%S/ 	>V 		U38_ 45	%		2	 37	./	 	4 	,r   rO  builderNrG  r3  r   c                    t        t              dk\  r0t               r&|j                  dd      st	        j
                         || _        d | _        i | _        i | _	        t        t              | _        | j                  j                         | _        dt                dt!                dt#                d| j                   dt%                d	| _        t               | _        d | _        t-        |t.              rAt1        |       | _        t5        |       | _        t9        |       | _        t=        |       | _        n@tA        |       | _        tC        |       | _        tE        |       | _        tG        |       | _        t-        | j                  tH              rtK        |       n
tM        |       | _'        d
| _(        d
| _)        tT        xr  | j                  j                  tV        d      | _*        | j                  j                  tX        d      | _-        t]        |       | _/        ta        |       | _1        | j                  j                  td        d      | _3        | ji                  tj              | _6        | j                  j                  tn        d      | _8        | j                  j                  tr        d      | _:        | ji                  tv              | _<        | j                  j                  tz        d      | _>        | j                  j                  t~        d      | _@        | j                  j                  t        d      | _B        | j                  r| j                          n| j                          | j                  j                  t        d      | _F        | ji                  t              | _H        | j                  j                  t        d       }|!t-        |t              rt        |      | _L        nd | _L        | j                  L| j                  j                  t        t              }|rt        j                  nt        j                  | _L        nd| j                  t        j                  k(  r*t        j                  d       t        j                  | _L        | j                  t        j                  k(  }| j                  t        j                  k7  rd| j                  j                  t        d       	 C| ji                  t              }|s,t        j                  d       t        j                  | _L        d}t        t        j                  |       | j                  j                  t        t              | j                  j                  t        t              f| _\        | ji                  t              | _^        | j                  j                  t        d      | _`        dt        j                  v r:	 d
dlcmd} | j                  j                  t        d       }||j                  |       t        | j                  j                        | _j        t        | j                  j                        | _l        t        | j                  j                        | _m        t        | j                  j                        | _n        t        | j                  j                        | _o        i | _p        i | _q        | ji                  t              | _s        | j                  | |xs i       | _u        d | _v        t        |       | _x        t        |       | _z        t        |       | _|        t        |       | _~        d | _        t        |       | _        t        |       | _        t        j	                  d| j&                         t        j                  | j                         y # t        $ r Y w xY w)Nr   %ENABLE_CREATE_SESSION_IN_STORED_PROCSFz
"version" : z,
"python.version" : z,
"python.connector.version" : z",
"python.connector.session.id" : z,
"os.name" : 
r   TzWSnowpark python client does not support dataframe requests, downgrading to SQL_AND_AST.zNServer side dataframe support requires minimum snowpark-python client version.modinAutoSwitchBackendr   z Snowpark Session information: %s)r   r   rc   "_get_client_side_session_parameterr5   DONT_CREATE_SESSION_IN_SPr  
_query_tag_import_paths	_packagesr   dict_artifact_repository_packagesget_session_id_session_idra   r^   r\   r]   _session_infoversion_session_stager  r   r   _udf_registrationr   _udtf_registrationr   _udaf_registrationr   _sp_registrationr   r   r   r   rC   r'   r   _plan_builder_last_action_id_last_canceled_idr{   /_PYTHON_SNOWPARK_USE_SCOPED_TEMP_OBJECTS_STRING3_PYTHON_SNOWPARK_ENABLE_SCOPED_TEMP_READ_ONLY_TABLE _use_scoped_temp_read_only_tabler   _filer   _lineage*_PYTHON_SNOWPARK_USE_SQL_SIMPLIFIER_STRING_sql_simplifier_enabledis_feature_enabled_for_version-_PYTHON_SNOWPARK_USE_CTE_OPTIMIZATION_VERSION_cte_optimization_enabled=_PYTHON_SNOWPARK_USE_LOGICAL_TYPE_FOR_CREATE_DATAFRAME_STRING_use_logical_type_for_create_df9_PYTHON_SNOWPARK_ELIMINATE_NUMERIC_SQL_VALUE_CAST_ENABLED)_eliminate_numeric_sql_value_cast_enabled9_PYTHON_SNOWPARK_AUTO_CLEAN_UP_TEMP_TABLE_ENABLED_VERSION!_auto_clean_up_temp_table_enabled._PYTHON_SNOWPARK_REDUCE_DESCRIBE_QUERY_ENABLED_reduce_describe_query_enabled/_PYTHON_SNOWPARK_ENABLE_QUERY_COMPILATION_STAGE _query_compilation_stage_enabled+_PYTHON_SNOWPARK_GENERATE_MULTILINE_QUERIES_generate_multiline_queries_enable_multiline_queries_disable_multiline_queries+_PYTHON_SNOWPARK_INTERNAL_TELEMETRY_ENABLED_internal_telemetry_enabled?_PYTHON_SNOWPARK_USE_LARGE_QUERY_BREAKDOWN_OPTIMIZATION_VERSION_large_query_breakdown_enabled _PYTHON_SNOWPARK_CLIENT_AST_MODErW  ru   	_ast_mode_PYTHON_SNOWPARK_USE_AST&_PYTHON_SNOWPARK_USE_AST_DEFAULT_VALUESQL_AND_ASTSQL_ONLYAST_ONLY_loggerrp   +_PYTHON_SNOWPARK_CLIENT_MIN_VERSION_FOR_ASTrr   rt   SERVER=_PYTHON_SNOWPARK_LARGE_QUERY_BREAKDOWN_COMPLEXITY_LOWER_BOUND$DEFAULT_COMPLEXITY_SCORE_LOWER_BOUND=_PYTHON_SNOWPARK_LARGE_QUERY_BREAKDOWN_COMPLEXITY_UPPER_BOUND$DEFAULT_COMPLEXITY_SCORE_UPPER_BOUND(_large_query_breakdown_complexity_bounds1_PYTHON_SNOWPARK_DATAFRAME_JOIN_ALIAS_FIX_VERSION_join_alias_fix3_SNOWPARK_PANDAS_DUMMY_ROW_POS_OPTIMIZATION_ENABLED#_dummy_row_pos_optimization_enabledsysmodulesmodin.configr_  )_SNOWPARK_PANDAS_HYBRID_EXECUTION_ENABLEDput	ExceptionrW   _thread_safe_session_enabled_thread_storerV   r  _package_lock
_plan_lock_xpath_udf_cache_lock_custom_package_usage_config_xpath_udf_cache;_PYTHON_SNOWPARK_COLLECT_TELEMETRY_AT_CRITICAL_PATH_VERSION2_collect_snowflake_plan_telemetry_at_critical_pathr"  r  !_runtime_version_from_requirementrE   _temp_table_auto_cleanerr   _sp_profilerr   _udf_profilerr   _dataframe_profiler_catalogr6   _client_telemetryr.   
_ast_batchinfoatexitregister_close_at_exit)r	  rG  r3  ast_mode_valueast_enabledast_supported_versionr_  pandas_hybrid_execution_enableds           r   r  zSession.__init__H  s     !Q&&(;;7 2KKMM
MO)+  	*  ::446"]O &() *356 7!!%!1!1 2 3]O  #}"d01%8%>D"&:4&@D#&:4&@D#$CD$ID!%4T%:D"$?$ED!&6t&<D#&6t&<D# $**&67 !&)$/ 	
  !!"$ 

==? 	% JJ99CU 	-
 #4(
JJ99:D 	$
 04/R/R90
& JJ99Mt 	, JJ99I5 	6 //I 	. JJ99> 	+ JJ99? 	- JJ99;U 	(
 ++**,++- JJ99;U 	( 594W4WK5
+ #jjKK,d
 %*^S*I$^4DN!DN >>! $

 M M(*P!K 5@W00WEUEUDN~~!1!11m ")!4!4..G,?,??K>>W---

==? 
 /3.Q.Q?/% -OOh &-%5%5DN"'Km**K8 JJ99M4 JJ99M4	J
5 &*%H%H=&

 JJ99CU 	0 ckk!: JJAA=t 0 3>%))*IJ
 1JJ33
 "$**"I"IJ

 *$***Q*QR 'tzz'N'NO &2JJ33&
" 35) 13 //K 	?
 ''gm<
6:.>RSW>X%3DA(6#4T#B !4T!B"4.79K9KL 	++,a  s   -9_ 	_"!_"c                     t         5  	 | j                  j                          | j                          ddd       y# t        $ r Y w xY w# 1 sw Y   yxY w)a  
        This is the helper function to close the current session at interpreter shutdown.
        For example, when a jupyter notebook is shutting down, this will also close
        the current session and make sure send all telemetry to the server.
        N)r   r  _opentelemetry_shutdowncloser  r)  s    r   r  zSession._close_at_exit:  sU     & 	&&>>@

	 	  		 	s&   A*<	AAAAAc                     | S r   r   r)  s    r   	__enter__zSession.__enter__G  s    r   c                 :    t               s| j                          y y r   )rc   r  )r	  exc_typeexc_valexc_tbs       r   __exit__zSession.__exit__J  s    %'JJL (r   c                    d| j                   j                   d| j                   j                   d| j                          d| j	                          d| j                          d| j                          d| j                          dS )	N<.z
: account=z, role=z, database=z	, schema=z, warehouse=>)	__class__r  r  get_current_accountget_current_roleget_current_databaseget_current_schemaget_current_warehouser)  s    r   __str__zSession.__str__N  s    ))*!DNN,C,C+DJtOgOgOiNj k))+,K8Q8Q8S7T U--/0T=W=W=Y<ZZ[]	
r   c                 L    dd l mc mc mc m} d| _        d|_        d|_        y )Nr   Tr\  z    4snowflake.snowpark._internal.analyzer.analyzer_utilssnowpark	_internalanalyzerr   r  NEW_LINETABr	  r   s     r   r  z!Session._enable_multiline_queriesU  s     UU+/("&#r   c                 L    dd l mc mc mc m} d| _        d|_        d|_        y )Nr   F r  r  s     r   r  z"Session._disable_multiline_queries\  s     UU+0("$r   parameter_namec                     | j                   j                  |d      }t        |t              xr( |dk7  xr! t	        | j
                        t	        |      k\  S )z
        This method checks if a feature is enabled for the current session based on
        the server side parameter.
        r  )r  r`  r  r   parse_versionrj  )r	  r  rj  s      r   rz  z&Session.is_feature_enabled_for_versionc  sS    
 **??PRSw$ F2Fdll+}W/EE	
r   c                     | j                   5  | xj                  dz  c_        | j                  cd d d        S # 1 sw Y   y xY wr   )r  rq  r)  s    r   _generate_new_action_idzSession._generate_new_action_ido  s8    ZZ 	(  A% ''	( 	( 	(s	   !8Ac                 .   t        | j                  d      sjd }t        | j                  t              rt        |       }n1t        | j                  t              rt        |       }nt        |       }|| j                  _	        | j                  j                  S )Nr  )
r  r  r  r  r   r   r   r   r   r  )r	  r  s     r   	_analyzerzSession._analyzert  sq    t)):6IMH$**m4&t,DJJ(<='-#D>*2D'!!***r   c                 f    	 t               S # t        $ r}|j                  dk(  rY d}~y|d}~ww xY w)zRGets the active session if one is created. If no session is created, returns None.rB  N)r   r   rD  )clsrE  s     r   get_active_sessionzSession.get_active_session  s4    	&((& 	}}&H		s   	 	0++0z1.27.0)rj  c                     ddl m} | j                  Ht        | j                  t
              r!| j                  j                  dt                ||       | _        | j                  S )z<Returns a :class:`Catalog` object rooted on current session.r   )CatalogzSession.catalogexternal_feature_nameraise_error)snowflake.snowpark.catalogr  r  r  r  r   log_not_supported_errorNotImplementedError)r	  r  s     r   catalogzSession.catalog  sT     	7== $**&:;

22*; 3 3  $DMDM}}r   c                    t               rt        j                  d       y	 | j                  j	                         r!t        j                  d| j                         n0t        j                  d| j                         | j                          	 | j                  j                          | j                  j!                          | j                  j#                          t        j                  d| j                         t%        |        y# t        $ r#}t        j                  t        |            d}~ww xY w# t%        |        w xY w# 	 | j                  j                          | j                  j!                          | j                  j#                          t        j                  d| j                         t%        |        w # t%        |        w xY wxY w)zClose this session.z3Closing a session in a stored procedure is a no-op.Nz4No-op because session %s had been previously closed.zClosing session: %szClosed session: %s)rc   r  rp   r  	is_closeddebugrh  r  
cancel_allr  r5   SERVER_FAILED_CLOSE_SESSIONr   r  stopr  clearr  r   )r	  rE  s     r   r  zSession.close  sL   !#OOQR	&zz##%J$$
 2D4D4DE!&--224%%'

  "143C3CD%  	W1MMcRTgVV	W  %&--224%%'

  "143C3CD%%sJ   A+D A.D7 	D4D//D44E 7EG	A.G7GGGc                     | j                   S r   )r  r)  s    r   r   zSession.conf  s    zzr   c                     | j                   S )zSet to ``True`` to use the SQL simplifier (defaults to ``True``).
        The generated SQLs from ``DataFrame`` transformations would have fewer layers of nested queries if the SQL simplifier is enabled.
        )ry  r)  s    r   sql_simplifier_enabledzSession.sql_simplifier_enabled  s    
 +++r   c                     t               S )a+  
        Set to ``True`` to enable the AST (Abstract Syntax Tree) capture for ``DataFrame`` operations.

        This is an internal, experimental feature that is not yet fully supported. The value of the parameter is controlled by the Snowflake service.

        It is not possible to re-enable this feature if the system or a user explicitly disables it. Setting this property to ``True`` can result in no change if the setting was already set explicitly to ``False`` internally.

        Returns:
            The current value of the property.
        )rs   r)  s    r   r  zSession.ast_enabled  s     r   z1.33.0r  c                     |r(| j                   rt        j                  d       d| _         t        t        j
                  |       y )NzTODO SNOW-1770278: Ensure auto temp table cleaner works with AST. Disabling auto temp cleaner for full test suite due to buggy behavior.F)r  r  rp   rr   rt   USERr	  r  s     r   r  zSession.ast_enabled  s;    " T;;OOZ 6;D2m((%0r   c                     | j                   S )zSet to ``True`` to enable the CTE optimization (defaults to ``False``).
        The generated SQLs from ``DataFrame`` transformations would have duplicate subquery as CTEs if the CTE optimization is enabled.
        )r|  r)  s    r   cte_optimization_enabledz Session.cte_optimization_enabled  s    
 ---r   c                     | j                   S r   )r  r)  s    r   (eliminate_numeric_sql_value_cast_enabledz0Session.eliminate_numeric_sql_value_cast_enabled  s    ===r   c                     | j                   S )a   
        When setting this parameter to ``True``, Snowpark will automatically clean up temporary tables created by
        :meth:`DataFrame.cache_result` in the current session when the DataFrame is no longer referenced (i.e., gets garbage collected).
        The default value is ``False``.

        Note:
            Temporary tables will only be dropped if this parameter is enabled during garbage collection.
            If a temporary table is no longer referenced when the parameter is on, it will be dropped during garbage collection.
            However, if garbage collection occurs while the parameter is off, the table will not be removed.
            Note that Python's garbage collection is triggered opportunistically, with no guaranteed timing.
        )r  r)  s    r    auto_clean_up_temp_table_enabledz(Session.auto_clean_up_temp_table_enabled  s     555r   c                     | j                   S r   )r  r)  s    r   large_query_breakdown_enabledz%Session.large_query_breakdown_enabled  s    222r   c                     | j                   S r   )r  r)  s    r   'large_query_breakdown_complexity_boundsz/Session.large_query_breakdown_complexity_bounds  s    <<<r   c                     | j                   S )a  
        When setting this parameter to ``True``, Snowpark will infer the schema of DataFrame locally if possible,
        instead of issuing an internal `describe query
        <https://docs.snowflake.com/en/developer-guide/python-connector/python-connector-example#retrieving-column-metadata>`_
        to get the schema from the Snowflake server. This optimization improves the performance of your workloads by
        reducing the number of describe queries issued to the server.
        The default value is ``False``.
        )r  r)  s    r   reduce_describe_query_enabledz%Session.reduce_describe_query_enabled  s     222r   c                     | j                   S )zSet to ``True`` to enable the dummy row position optimization (defaults to ``True``).
        The generated SQLs from pandas transformations would potentially have fewer expensive window functions to compute the row position column.
        )r  r)  s    r   "dummy_row_pos_optimization_enabledz*Session.dummy_row_pos_optimization_enabled  s    
 777r   c                     t         j                  j                  d      st        d      ddlm}  |       j                         S )aL  Set to ``True`` to enable hybrid execution mode (has the same default as AutoSwitchBackend).
        When enabled, certain operations on smaller data will automatically execute in native pandas in-memory.
        This can significantly improve performance for operations that are more efficient in pandas than in Snowflake.
        r]  PThe 'modin' package is required to enable this feature. Please install it first.r   r^  )	importlibutil	find_specImportErrorr  r_  r  )r	  r_  s     r   r  z'Session.pandas_hybrid_execution_enabled  s=     ~~''0b  	3 "&&((r   c                     | j                   S )a
  Get or set configuration parameters related to usage of custom Python packages in Snowflake.

        If enabled, pure Python packages that are not available in Snowflake will be installed locally via pip and made available
        as an import (see :func:`add_import` for more information on imports). You can speed up this process by mentioning
        a remote stage path as ``cache_path`` where unsupported pure Python packages will be persisted. To use a specific
        version of pip, you can set the environment variable ``PIP_PATH`` to point to your pip executable. To use custom
        Python packages which are not purely Python, specify the ``force_push`` configuration parameter (*note that using
        non-pure Python packages is not recommended!*).

        This feature is **experimental**, please do not use it in production!

        Configurations:
            - **enabled** (*bool*): Turn on usage of custom pure Python packages.
            - **force_push** (*bool*): Use Python packages regardless of whether the packages are pure Python or not.
            - **cache_path** (*str*): Cache custom Python packages on a stage directory. This parameter greatly reduces latency of custom package import.
            - **force_cache** (*bool*): Use this parameter if you specified a ``cache_path`` but wish to create a fresh cache of your environment.

        Args:
            config (dict): Dictionary containing configuration parameters mentioned above (defaults to empty dictionary).

        Example::

            >>> from snowflake.snowpark.functions import udf
            >>> session.custom_package_usage_config = {"enabled": True, "cache_path": "@my_permanent_stage/folder"} # doctest: +SKIP
            >>> session.add_packages("package_unavailable_in_snowflake") # doctest: +SKIP
            >>> @udf
            ... def use_my_custom_package() -> str:
            ...     import package_unavailable_in_snowflake
            ...     return "works"
            >>> session.clear_packages()
            >>> session.clear_imports()

        Note:
            - These configurations allow custom package addition via :func:`Session.add_requirements` and :func:`Session.add_packages`.
            - These configurations also allow custom package addition for all UDFs or stored procedures created later in the current session. If you only want to add custom packages for a specific UDF, you can use ``packages`` argument in :func:`functions.udf` or :meth:`session.udf.register() <snowflake.snowpark.udf.UDFRegistration.register>`.
        )r  r)  s    r   custom_package_usage_configz#Session.custom_package_usage_config-  s    L 000r   c                 H   t        d       | j                  5  | j                  j                  j	                  | j
                  |       	 | j                  j                  j                  dt         d|        || _
        d d d        y # t        $ r Y w xY w# 1 sw Y   y xY w)Nr  zalter session set z = )ro   r  r  _telemetry_clientsend_sql_simplifier_telemetryrh  _cursorexecuterx  r  ry  r  s     r   r  zSession.sql_simplifier_enabledU  s    89QRZZ 
	1JJ((FF  %

""**()S(TTWX]W^_
 ,1D(
	1 
	1  
	1 
	1s/   1B
/B	9B		BBBBB!c                     t        d       | j                  5  |r/| j                  j                  j	                  | j
                         || _        d d d        y # 1 sw Y   y xY w)Nr  )ro   r  r  r  send_cte_optimization_telemetryrh  r|  r  s     r   r  z Session.cte_optimization_enablede  sU    89STZZ 	3

,,LL$$ .3D*	3 	3 	3s   9AA#z1.20.0c                     t        d       |dv rM| j                  5  | j                  j                  j	                  | j
                  |       || _        ddd       yt        d      # 1 sw Y   yxY w)z:Set the value for eliminate_numeric_sql_value_cast_enabledr  TFNzIvalue for eliminate_numeric_sql_value_cast_enabled must be True or False!)ro   r  r  r  /send_eliminate_numeric_sql_value_cast_telemetryrh  r  
ValueErrorr  s     r   r  z0Session.eliminate_numeric_sql_value_cast_enabledp  s     	96	
 M! G

,,\\$$e BG>	G G [ G G   8A((A1z1.21.0c                     t        d       |dv rM| j                  5  | j                  j                  j	                  | j
                  |       || _        ddd       yt        d      # 1 sw Y   yxY w)z2Set the value for auto_clean_up_temp_table_enabledr  r   NzAvalue for auto_clean_up_temp_table_enabled must be True or False!)ro   r  r  r  'send_auto_clean_up_temp_table_telemetryrh  r  r"  r  s     r   r  z(Session.auto_clean_up_temp_table_enabled  sy     	9.	
 M! ?

,,TT$$e :?6	? ? S ? ?r#  z1.22.0c                     t        d       |dv rM| j                  5  | j                  j                  j	                  | j
                  |       || _        ddd       yt        d      # 1 sw Y   yxY w)a*  Set the value for large_query_breakdown_enabled. When enabled, the client will
        automatically detect large query plans and break them down into smaller partitions,
        materialize the partitions, and then combine them to execute the query to improve
        overall performance.
        r	  r   Nz>value for large_query_breakdown_enabled must be True or False!)ro   r  r  r  $send_large_query_breakdown_telemetryrh  r  r"  r  s     r   r	  z%Session.large_query_breakdown_enabled  sy     	9+	
 M! <

,,QQ$$e 7<3	< < P < <r#  c                 f   t        d       t        |      dk7  rt        dt        |             |d   |d   k\  rt        d|d   |d   f d      | j                  5  | j                  j
                  j                  | j                  |d   |d          || _        ddd       y# 1 sw Y   yxY w)	zcSet the lower and upper bounds for the complexity score used in large query breakdown optimization.r     z9Expecting a tuple of two integers. Got a tuple of length r   r   zqExpecting a tuple of lower and upper bound with the lower bound less than the upper bound. Got (lower, upper) = ()N)	ro   r   r"  r  r  r  3send_large_query_breakdown_update_complexity_boundsrh  r  r  s     r   r  z/Session.large_query_breakdown_complexity_bounds  s     	95	
 u:?KCPUJ<X  8uQx D  EJ  KL  EM  OT  UV  OW  EW  DX  XY  Z  ZZ 	BJJ((\\  %(E!H =BD9	B 	B 	Bs   ?B''B0z1.24.0c                     |dv r8| j                   j                  j                  | j                  |       || _        yt        d      )z/Set the value for reduce_describe_query_enabledr   z>value for reduce_describe_query_enabled must be True or False!N)r  r  $send_reduce_describe_query_telemetryrh  r  r"  r  s     r   r  z%Session.reduce_describe_query_enabled  sI     M!JJ((MM  % 38D/P r   c                 0    |dv r|| _         yt        d      )z4Set the value for dummy_row_pos_optimization_enabledr   zCvalue for dummy_row_pos_optimization_enabled must be True or False!N)r  r"  r  s     r   r  z*Session.dummy_row_pos_optimization_enabled  s$     M!7<D4U r   c                     t         j                  j                  d      st        d      ddlm} |dv r|j                  |       yt        d      )z1Set the value for pandas_hybrid_execution_enabledr]  r  r   r^  r   z@value for pandas_hybrid_execution_enabled must be True or False!N)r  r  r  r  r  r_  r  r"  )r	  r  r_  s      r   r  z'Session.pandas_hybrid_execution_enabled  sQ     ~~''0b  	3M!!!%(R r   z1.6.0r2  c                     | j                   5  |j                         D ci c]  \  }}|j                         | c}}| _        d d d        y c c}}w # 1 sw Y   y xY wr   )r  r  lowerr  )r	  r2  kvs       r   r  z#Session.custom_package_usage_config  sV     ZZ 	)/1!%A	11D-	 	1	 	s   AA	AAAc                    t         j                  d       | j                  5  | j                  | _        ddd       t        | j                  t              s*| j                  j                  d| j                   d       yy# 1 sw Y   NxY w)z
        Cancel all action methods that are running currently.
        This does not affect any action methods called in the future.
        zCanceling all running queriesNz!select system$cancel_all_queries(r*  )
r  r  r  rq  rr  r  r  r   	run_queryrh  r)  s    r   r  zSession.cancel_all  st    
 	45ZZ 	:%)%9%9D"	:$**&:;JJ  3D4D4D3EQG <	: 	:s   BB
c                     | j                   5  t        | j                  j                               cddd       S # 1 sw Y   yxY w)z
        Returns a list of imports added for user defined functions (UDFs).
        This list includes any Python or zip files that were added automatically by the library.
        N)r  listrc  keysr)  s    r   get_importszSession.get_imports  s7    
 ZZ 	3**//12	3 	3 	3s	   #:AFpathimport_path
chunk_sizewhole_file_hashc                 @   t        | j                  t              r:| j                  j	                  ||       | j
                  j	                  ||       | j                  ||||      \  }}}| j                  5  ||f| j                  |<   ddd       y# 1 sw Y   yxY w)ax  
        Registers a remote file in stage or a local file as an import of a user-defined function
        (UDF). The local file can be a compressed file (e.g., zip), a Python file (.py),
        a directory, or any other file resource. You can also find examples in
        :class:`~snowflake.snowpark.udf.UDFRegistration`.

        Args:
            path: The path of a local file or a remote file in the stage. In each case:

                * if the path points to a local file, this file will be uploaded to the
                  stage where the UDF is registered and Snowflake will import the file when
                  executing that UDF.

                * if the path points to a local directory, the directory will be compressed
                  as a zip file and will be uploaded to the stage where the UDF is registered
                  and Snowflake will import the file when executing that UDF.

                * if the path points to a file in a stage, the file will be included in the
                  imports when executing a UDF.

            import_path: The relative Python import path for a UDF.
                If it is not provided or it is None, the UDF will import the package
                directly without any leading package/module. This argument will become
                a no-op if the path  points to a stage file or a non-Python local file.

            chunk_size: The number of bytes to hash per chunk of the uploaded files.

            whole_file_hash: By default only the first chunk of the uploaded import is hashed to save
                time. When this is set to True each uploaded file is fully hashed instead.

        Example::

            >>> from snowflake.snowpark.types import IntegerType
            >>> from resources.test_udf_dir.test_udf_file import mod5
            >>> session.add_import("tests/resources/test_udf_dir/test_udf_file.py", import_path="resources.test_udf_dir.test_udf_file")
            >>> mod5_and_plus1_udf = session.udf.register(
            ...     lambda x: mod5(x) + 1,
            ...     return_type=IntegerType(),
            ...     input_types=[IntegerType()]
            ... )
            >>> session.range(1, 8, 2).select(mod5_and_plus1_udf("id")).to_df("col1").collect()
            [Row(COL1=2), Row(COL1=4), Row(COL1=1), Row(COL1=3)]
            >>> session.clear_imports()

        Note:
            1. In favor of the lazy execution, the file will not be uploaded to the stage
            immediately, and it will be uploaded when a UDF is created.

            2. The Snowpark library calculates a sha256 checksum for every file/directory.
            Each file is uploaded to a subdirectory named after the checksum for the
            file in the stage. If there is an existing file or directory, the Snowpark
            library will compare their checksums to determine whether it should be re-uploaded.
            Therefore, after uploading a local file to the stage, if the user makes
            some changes to this file and intends to upload it again, just call this
            function with the file path again, the existing file in the stage will be
            overwritten by the re-uploaded file.

            3. Adding two files with the same file name is not allowed, because UDFs
            can't be created with two imports with the same name.

            4. This method will register the file for all UDFs created later in the current
            session. If you only want to import a file for a specific UDF, you can use
            ``imports`` argument in :func:`functions.udf` or
            :meth:`session.udf.register() <snowflake.snowpark.udf.UDFRegistration.register>`.
        )r;  N)	r  r  r   udf_import_filesproc_resolve_import_pathr  rc  )r	  r:  r;  r<  r=  checksumleading_paths          r   
add_importzSession.add_import	  s    P djj"67HH!!$K!@JJ##Dk#B'+'@'@+z?(
$h ZZ 	@(0,'?Dt$	@ 	@ 	@s   9BBc                 B   |j                         }|j                  t              st        j                  j                  |      n|}| j                  5  || j                  vrt        | d      | j                  j                  |       	 ddd       y# 1 sw Y   yxY w)a\  
        Removes a file in stage or local file from the imports of a user-defined function (UDF).

        Args:
            path: a path pointing to a local file or a remote file in the stage

        Examples::

            >>> session.clear_imports()
            >>> len(session.get_imports())
            0
            >>> session.add_import("tests/resources/test_udf_dir/test_udf_file.py")
            >>> len(session.get_imports())
            1
            >>> session.remove_import("tests/resources/test_udf_dir/test_udf_file.py")
            >>> len(session.get_imports())
            0
        z% is not found in the existing importsN)
strip
startswithrN   osr:  abspathr  rc  r   r+  )r	  r:  trimmed_pathabs_paths       r   remove_importzSession.remove_import[  s    & zz|  **<8 GGOOL) 	
 ZZ 	1t111(+PQRR""&&x0		1 	1 	1s   8BBc                    t        | j                  t              r4| j                  j	                          | j
                  j	                          | j                  5  | j                  j                          ddd       y# 1 sw Y   yxY w)zo
        Clears all files in a stage or local files from the imports of a user-defined function (UDF).
        N)	r  r  r   r?  _clear_session_importsrA  r  rc  r  r)  s    r   clear_importszSession.clear_importsz  sa     djj"67HH++-JJ--/ZZ 	'$$&	' 	' 	's   A??Bc                    | j                         }|r|j                         nd }|j                  t              st        j                  j                  |      st        | d      t        j                  j                  |      s-t        j                  j                  |      st        d|       t        j                  j                  |      }|t        j                  j                  |      r+|j                  dt        j                  j                        }n`t        j                  j                  |      r?|j                  d      r.|j                  dt        j                  j                         d}nd }|r2|j                  |      r|d t        |        }nt        d| d|       d }nd }|t        ||||      |fS |d d fS )Nz is not foundzSadd_import() only accepts a local file or directory, or a file in a stage, but got r  .pyzimport_path z, is invalid because it's not a part of path )additional_infor<  r=  )rG  rH  rN   rI  r:  existsFileNotFoundErrorisfileisdirr"  rJ  replacesependswithr   rT   )	r:  r;  r<  r=  rK  trimmed_import_pathrL  import_file_pathrD  s	            r   rB  zSession._resolve_import_path  s    zz|5@k//1d&&|477>>,/'<.(FGG77>>,/9
 !55AND  ww|4H
 #.77==*':'B'B3'T$WW^^H-(2C2CE2J.66sBGGKKHIM % (,$#(()9:'/0H37G3H2H'I(*+>*? @??GjJ 
 $(L# "$0)$3	 	 	  t++r   statement_paramsimport_only_stageupload_and_import_stageudf_level_import_pathsr^  c                @   g }| j                  ||      }t        |      }t        |      }| j                  5  |xs | j                  j	                         }	ddd       	j                         D ]  \  }
\  }}|
j                  t              r|j                  |
       1t        j                  j                  |
      s|
j                  d      r"t        j                  j                  |
       dnt        j                  j                  |
      }| d| }||v r;t        j                  | d| d       |j                  t!        | d|              t        j                  j                  |
      s|
j                  d      r;t#        |
|      5 }| j$                  j'                  ||||dd	d
d
d
|
       ddd       n!| j$                  j)                  |
||d	d
d
       |j                  t!        | d|               |S # 1 sw Y   xY w# 1 sw Y   :xY w)zAResolve the imports and upload local files (if any) to the stage.r]  NrR  .zip/z exists on z	, skippedDEFLATEFT)
input_streamstage_locationdest_filenamedest_prefixsource_compressioncompress_data	overwrite	is_in_udfskip_upload_on_content_matchr^  )r:  rg  ri  rk  rl  rn  )_list_files_in_stagerm   r  rc  copyr  rH  rN   appendrI  r:  rW  rZ  basenamer  r  re   rq   r  upload_streamupload_file)r	  r_  r`  ra  r^  resolved_stage_filesstage_file_listnormalized_import_only_location%normalized_upload_and_import_locationimport_pathsr:  prefixrD  filenamefilename_with_prefixrf  s                   r   _resolve_importszSession._resolve_imports  sL     "330@ 4 
 +M+
' 1S#1
- ZZ 	O1NT5G5G5L5L5NL	O,8,>,>,@ 4	(D(6<|,$++D1 ww}}T*dmmE.B ww''-.d3))$/ 
 +18*'=$'?:MM#*K0O/PPYZ )//4>?qAU@VW ww}}T*dmmE.B< , ) JJ44-9/T.6,23<.3*.*.=A1A 5  " 

..!%+P(.*/&*9= /  )//4DEQG[F\]a4	l $#q	O 	O2 s   H&HHH	rg  c                   t        |rt        |      n| j                        }| j                  d| d      j	                  dd      j                  |      }t        |      }|D ch c]  }t        |d         |d   c}S c c}w )Nzls F	_emit_astz"name"r]  r   )re   rl   rk  sqlselect_internal_collect_with_tagr_   r   )r	  rg  r^  
normalized	file_listprefix_lengthrows          r   ro  zSession._list_files_in_stage  s     2  /$$

 HHs:,'5H9VHV.''9I'J 	
 5^D7@ACFMN+AAAs   )Bartifact_repositoryc                     | j                   5  |r&| j                  |   j                         cddd       S | j                  j                         cddd       S # 1 sw Y   yxY w)aj  
        Returns a ``dict`` of packages added for user-defined functions (UDFs).
        The key of this ``dict`` is the package name and the value of this ``dict``
        is the corresponding requirement specifier.

        Args:
            artifact_repository: When set this will function will return the packages for a specific artifact repository.
        N)r  rf  rp  rd  r	  r  s     r   get_packageszSession.get_packages*  sY      	)"99:MNSSU	) 	) >>&&(	) 	) 	)s   AAA"r  packagesc                L    | j                  t        | | j                  |       y)a  
        Adds third-party packages as dependencies of a user-defined function (UDF).
        Use this method to add packages for UDFs as installing packages using
        `conda <https://docs.conda.io/en/latest/>`_. You can also find examples in
        :class:`~snowflake.snowpark.udf.UDFRegistration`. See details of
        `third-party Python packages in Snowflake <https://docs.snowflake.com/en/developer-guide/udf/python/udf-python-packages.html>`_.

        To use Python packages that are not available in Snowflake, refer to :meth:`~snowflake.snowpark.Session.custom_package_usage_config`.

        Args:
            packages: A `requirement specifier <https://packaging.python.org/en/latest/glossary/#term-Requirement-Specifier>`_,
                a ``module`` object or a list of them for installing the packages. An exception
                will be raised if two conflicting requirement specifiers are provided.
                The syntax of a requirement specifier is defined in full in
                `PEP 508 <https://www.python.org/dev/peps/pep-0508/>`_, but currently only the
                `version matching clause <https://www.python.org/dev/peps/pep-0440/#version-matching>`_ (``==``)
                is supported as a `version specifier <https://packaging.python.org/en/latest/glossary/#term-Version-Specifier>`_
                for this argument. If a ``module`` object is provided, the package will be
                installed with the version in the local environment.
            artifact_repository: When set this parameter specifies the artifact repository that packages will be added from. Only functions
                using that repository will use the packages. (Default None)

        Example::

            >>> import numpy as np
            >>> from snowflake.snowpark.functions import udf
            >>> import numpy
            >>> import pandas
            >>> import dateutil
            >>> # add numpy with the latest version on Snowflake Anaconda
            >>> # and pandas with the version "2.1.*"
            >>> # and dateutil with the local version in your environment
            >>> session.custom_package_usage_config = {"enabled": True}  # This is added because latest dateutil is not in snowflake yet
            >>> session.add_packages("numpy", "pandas==2.2.*", dateutil)
            >>> @udf
            ... def get_package_name_udf() -> list:
            ...     return [numpy.__name__, pandas.__name__, dateutil.__name__]
            >>> session.sql(f"select {get_package_name_udf.name}()").to_df("col1").show()
            ----------------
            |"COL1"        |
            ----------------
            |[             |
            |  "numpy",    |
            |  "pandas",   |
            |  "dateutil"  |
            |]             |
            ----------------
            <BLANKLINE>
            >>> session.clear_packages()

        Note:
            1. This method will add packages for all UDFs created later in the current
            session. If you only want to add packages for a specific UDF, you can use
            ``packages`` argument in :func:`functions.udf` or
            :meth:`session.udf.register() <snowflake.snowpark.udf.UDFRegistration.register>`.

            2. We recommend you to `setup the local environment with Anaconda <https://docs.snowflake.com/en/developer-guide/udf/python/udf-python-packages.html#local-development-and-testing>`_,
            to ensure the consistent experience of a UDF between your local environment
            and the Snowflake server.
        r  N)_resolve_packagesrf   rd  )r	  r  r  s      r   add_packageszSession.add_packages8  s*    B 	)84NN 3 	 	
r   packagec                 ^   t        |      j                  }| j                  5  |=|| j                  j	                  |i       v r| j                  |   j                  |       n8|| j                  v r| j                  j                  |       nt        | d      ddd       y# 1 sw Y   yxY w)a  
        Removes a third-party package from the dependency list of a user-defined function (UDF).

        Args:
            package: The package name.
            artifact_repository: When set this parameter specifies that the package should be removed
                from the default packages for a specific artifact repository.

        Examples::

            >>> session.clear_packages()
            >>> len(session.get_packages())
            0
            >>> session.add_packages("numpy", "pandas==2.2.*")
            >>> len(session.get_packages())
            2
            >>> session.remove_package("numpy")
            >>> len(session.get_packages())
            1
            >>> session.remove_package("pandas")
            >>> len(session.get_packages())
            0
        Nz is not in the package list)r   namer  rf  r  r+  rd  r"  )r	  r  r  package_names       r   remove_packagezSession.remove_package  s    8 #7+00 	O#/ 5599:MrRS 223FGKK  /""<0 L>1L!MNN	O 	O 	Os   A8B##B,c                     | j                   5  |+| j                  j                  |i       j                          n| j                  j                          ddd       y# 1 sw Y   yxY w)z
        Clears all third-party packages of a user-defined function (UDF). When artifact_repository
        is set packages are only clear from the specified repository.
        N)r  rf  r  r  rd  r  s     r   clear_packageszSession.clear_packages  sX      	'".22667JBOUUW$$&		' 	' 	's   AAA'	file_pathc                     |j                  d      s|j                  d      rt        |      \  }}|| _        n&t        |      \  }}|D ]  }| j	                  |        | j                  ||       y)az	  
        Adds a `requirement file <https://pip.pypa.io/en/stable/user_guide/#requirements-files>`_
        that contains a list of packages as dependencies of a user-defined function (UDF). This function also supports
        addition of requirements via a `conda environment file <https://conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html#create-env-file-manually>`_.

        To use Python packages that are not available in Snowflake, refer to :meth:`~snowflake.snowpark.Session.custom_package_usage_config`.

        Args:
            file_path: The path of a local requirement file.
            artifact_repository: When set this parameter specifies the artifact repository that packages will be added from. Only functions
                using that repository will use the packages. (Default None)

        Example::

            >>> from snowflake.snowpark.functions import udf
            >>> import numpy
            >>> import pandas
            >>> import sys
            >>> # test_requirements.txt contains "numpy" and "pandas"
            >>> file = "test_requirements.txt" if sys.version_info < (3, 13) else "test_requirements_py313.txt"
            >>> session.add_requirements(f"tests/resources/{file}")
            >>> @udf
            ... def get_package_name_udf() -> list:
            ...     return [numpy.__name__, pandas.__name__]
            >>> session.sql(f"select {get_package_name_udf.name}()").to_df("col1").show()
            --------------
            |"COL1"      |
            --------------
            |[           |
            |  "numpy",  |
            |  "pandas"  |
            |]           |
            --------------
            <BLANKLINE>
            >>> session.clear_packages()

        Note:
            1. This method will add packages for all UDFs created later in the current
            session. If you only want to add packages for a specific UDF, you can use
            ``packages`` argument in :func:`functions.udf` or
            :meth:`session.udf.register() <snowflake.snowpark.udf.UDFRegistration.register>`.

            2. We recommend you to `setup the local environment with Anaconda <https://docs.snowflake.com/en/developer-guide/udf/python/udf-python-packages.html#local-development-and-testing>`_,
            to ensure the consistent experience of a UDF between your local environment
            and the Snowflake server.
        z.ymlz.yamlr  N)rZ  r?   r  r@   rE  r  )r	  r  r  r  runtime_versionnew_importsr;  s          r   add_requirementszSession.add_requirements  su    f f%););G)D(I)(T%Ho5DD2$@$K!Hk* -,-(8KLr   z1.7.0ignore_packagesrelaxc                 n   |i n|}g }t         j                  j                         D ]  }|j                  d   j                         |v r4t        j                  |j                  d   j                          d       V|j                  d   j                         t        v r4t        j                  |j                  d   j                          d       |j                  r|sd|j                  z   nd}|j                  |j                  d   j                          |         | j                  |       y)au  
        Adds all third-party packages in your local environment as dependencies of a user-defined function (UDF).
        Use this method to add packages for UDFs as installing packages using `conda <https://docs.conda.io/en/latest/>`_.
        You can also find examples in :class:`~snowflake.snowpark.udf.UDFRegistration`. See details of `third-party Python packages in Snowflake <https://docs.snowflake.com/en/developer-guide/udf/python/udf-python-packages.html>`_.

        If you find that certain packages are causing failures related to duplicate dependencies, try adding
        duplicate dependencies to the ``ignore_packages`` parameter. If your local environment contains Python packages
        that are not available in Snowflake, refer to :meth:`~snowflake.snowpark.Session.custom_package_usage_config`.

        This function is **experimental**, please do not use it in production!

        Example::

            >>> import sys
            >>> from snowflake.snowpark.functions import udf
            >>> import numpy
            >>> import pandas
            >>> # test_requirements.txt contains "numpy" and "pandas"
            >>> session.custom_package_usage_config = {"enabled": True, "force_push": True} # Recommended configuration
            >>> session.replicate_local_environment(ignore_packages={"snowflake-snowpark-python", "snowflake-connector-python", "urllib3", "tzdata", "numpy"}, relax=True)  # doctest: +SKIP
            >>> @udf
            ... def get_package_name_udf() -> list:
            ...     return [numpy.__name__, pandas.__name__]
            >>> if sys.version_info <= (3, 11):
            ...     session.sql(f"select {get_package_name_udf.name}()").to_df("col1").show()  # doctest: +SKIP
            --------------
            |"COL1"      |
            --------------
            |[           |
            |  "numpy",  |
            |  "pandas"  |
            |]           |
            --------------
            <BLANKLINE>
            >>> session.clear_packages()  # doctest: +SKIP
            >>> session.clear_imports()  # doctest: +SKIP

        Args:
            ignore_packages: Set of package names that will be ignored.
            relax: If set to True, package versions will not be considered.

        Note:
            1. This method will add packages for all UDFs created later in the current
            session. If you only want to add packages for a specific UDF, you can use
            ``packages`` argument in :func:`functions.udf` or
            :meth:`session.udf.register() <snowflake.snowpark.udf.UDFRegistration.register>`.

            2. We recommend you to `setup the local environment with Anaconda <https://docs.snowflake.com/en/developer-guide/udf/python/udf-python-packages.html#local-development-and-testing>`_,
            to ensure the consistent experience of a UDF between your local environment
            and the Snowflake server.
        NNamez" found in environment, ignoring...z% is available by default, ignoring...==r  )
r  metadatadistributionsr1  r  r  r7   rj  rq  r  )r	  r  r  r  r  version_texts         r   replicate_local_environmentz#Session.replicate_local_environment  s(   n !0 7"_ ))779 	QG'--/?B''/55788Z[ '--/3CC''/55788]^ *1//%w&R  OOw//7==?@OP	Q  	(#r   c                    t               }| D ]  }t        |t              rQt        j                  |j
                  |j
                        }| dt        j                  j                  |       }d}n2|j                         j                         }|j                  d      rd}t        |      }|j                  j                         }|s1d|v r-t        j                  d|      }|r|d |j!                          n|}|||f||<    |S )Nr  T#F_z[^0-9a-zA-Z\-_.])re  r  r   rM   r  r  r  r  rj  rG  r1  rH  r   r  researchstart)r  package_dictr  r  use_local_versionpackage_req	reg_matchs          r   _parse_packageszSession._parse_packages@  s    v 	SG':.>BB$$g&6&6  *N"Y-?-?-G-G-U,VW$(!!--///1%%c*$)!%g.K '++113L$II&97C	?Hw':):;g%13Dk$RL!9	S: r   r  validate_packagepackage_tablecurrent_packagessuppress_local_package_warningsc           
         g }| j                  |j                         D cg c]  }|d   	 c}|||      }	| j                  5  | j                  j	                         }
d d d        g }|j                         D ]|  \  }}|\  }}}|j                  r|j                  nd |r||	vsrt        fd|	|   D              sd dnd}t               r!|j                  t        d| | d             |||	vr1| j                         s!|j                  t        d| | d	             
j                  d
d      s|j                  t        d| d             |j                  |       |sN	 t        j                  j                  |      }d } ||||	      s!|st         j#                  d| d| d| d       ||v r0||   |k7  sR|j                  t)        d| d||    d             x|||<    t+        |      dk(  r|d   t+        |      dkD  rt        |      g }t+        |      dk7  rt         j#                  d| d       
j                  dd      rS|
j                  dd      sA|
d   }	 t-        |      }| j/                  ||
d         }|t         j#                  d| d       |s| j3                  ||||
      }|S c c}w # 1 sw Y   sxY w# t        j                  j$                  $ r |st         j#                  d| d       Y [t&        $ r$}|st         j#                  d||       Y d }~d }~ww xY w# t&        $ r3}t         j#                  d| d|j1                                 Y d }~d }~ww xY w) Nr   )package_namespackage_table_namer  r^  c              3   @   K   | ]  }j                  |        y wr   )contains).0r3  package_specifiers     r   	<genexpr>z3Session._get_dependency_packages.<locals>.<genexpr>  s$        *2215 s   z	(version r*  r  zCannot add package ai   because it is not available in Snowflake and it cannot be installed via pip as you are executing this code inside a stored procedure. You can find the directory of these packages and add it via Session.add_import. See details at https://docs.snowflake.com/en/developer-guide/snowpark/python/creating-udfs.html#using-third-party-packages-from-anaconda-in-a-udf.z because Anaconda terms must be accepted by ORGADMIN to use Anaconda 3rd party packages. Please follow the instructions at https://docs.snowflake.com/en/developer-guide/udf/python/udf-python-packages.html#using-third-party-packages-from-anaconda.enabledFa   because it is not available in Snowflake and Session.custom_package_usage_config['enabled'] is not set to True. To upload these packages, you can set it to True or find the directory of these packages and add it via Session.add_import. See details at https://docs.snowflake.com/en/developer-guide/snowpark/python/creating-udfs.html#using-third-party-packages-from-anaconda-in-a-udf.c                     | dk(  rqt        t        |j                  d            \  }}}|j                  | g       D ch c]-  }t	        t        t        |j                  d      d d             / }}||f|v S ||j                  | g       v S c c}w )Nsnowflake-snowpark-pythonr  r)  )maprW  splitr  tuple)r  package_client_versionvalid_packagesclient_majorclient_minorr  r3  valid_versionss           r   is_valid_versionz:Session._get_dependency_packages.<locals>.is_valid_version  s      ,/JJ@C$')?)E)Ec)JA" =lA
 .<-?-?b-Q2"() %*#c1773<3C*D$E2" 2" )5l'C~'U U#9^=O=O ,b> $ 2"s   2BzThe version of package 'z' in the local environment is z7, which does not fit the criteria for the requirement 'zo'. Your UDF might not work when the package version is different between the server and your local environment.z	Package 'z' is not installed in the local environment. Your UDF might not work when the package is installed on the server but not on your local environment.z6Failed to get the local distribution of package %s: %sCannot add package '
' because  is already added.r   z7The following packages are not available in Snowflake: r  
cache_pathforce_cachez-Unable to load environments from remote path z', creating a fresh environment instead.z/, creating a fresh environment instead. Error: )$_get_available_versions_for_packagesvaluesr  r  rp  r  	specifieranyrc   rq  RuntimeError_is_anaconda_terms_acknowledgedr  r  r  rj  r  rp   PackageNotFoundErrorr  r"  r   r<   %_load_unsupported_packages_from_stage__repr___upload_unsupported_packages)r	  r  r  r  r  r^  r  errorsr3  r  r  unsupported_packagesr  package_infor  r  r  r  r  r  rE  dependency_packagesr  environment_signatureer  s                            @r   _get_dependency_packagesz Session._get_dependency_packagesd  s]    BB)5)<)<)>?A1Q4?,--	 C 
 ZZ 	S*.*K*K*P*P*R'	S +-%1%7%7%9 o	9!G\;G8L+[ :E9N9N 5 5TX~5%  !/!=   -8 $$5#6a8 !
 ./("5l^L> Rf !g !$N: $ D D F("5l^L> R^ !^ !6::9eL("5k] Cf !g !(//8*-1:1C1C1K1K(2."  0(*@.  $C '&>|nLj'=&> ?44;9 =b%c!"* //#L1W<MM"27):FVWcFdEe f0 0 29 ._o	9d v;!)O[1_v&&13#$)OOIJ^I__`a +..e155mUK8F
,9:N,O)*.*T*T-/J</X+' +2KJ< X3 4 '&*&G&G(!$/	'# #"E @	S 	Sv %--BB >#OO"+L> :E !F
 % >#OO X , "X ! OOG
| T778zz|nF sH   KK0AK8;M K8MM L??M	N)M>>Nr  result_dictc                     g }| D ]r  }t        |t              r||vr|j                  |       )t        |t              s:|j                  |vsI|j                  |j                   d|j
                          t |S )Nr  )r  r   rq  r   r  __version__)r  r  resms       r   _get_req_identifiers_listz!Session._get_req_identifiers_list  so      	=A!S!a{&:

1Az*qzz/L

ajj\AMM?;<		= 
r   Texisting_packages_dictinclude_pandasc                    t         g}|r|j                  d       | j                  |      }	t        | j                  t
              s|g }
| j                  5  || j                  }n| j                  |   }|	j                         D ]W  \  }}}||v r?t        |      ||   k7  r.|
j                  t        dt        |       d||    d             Jt        |      ||<   Y t        |
      dk(  r|
d   t        |
      dkD  rt        |
      	 ddd       t        j                               | j                  ||      z   S d}| j!                         sd	| }| j                  5  ||ni }| j#                  |	|||||j%                  d
d            }|D ]  }|j&                  }|j(                  D cg c]  }|j*                  |j,                  f }}|r|d   d   nd}||v rD|Qd||   v }|r)||   t        |      k7  rt        d| d| d||    d      t        |      ||<   t        |      ||<    t        |j                               | j                  ||      z   cddd       S # 1 sw Y   `xY wc c}w # 1 sw Y   yxY w)a  
        Given a list of packages to add, this method will
        1. Check if the packages are supported by Snowflake
        2. Check if the package version if provided is supported by Snowflake
        3. Check if the package is already added
        4. Update existing packages dictionary with the new packages (*this is required for python sp to work*)

        When auto package upload is enabled, this method will also try to upload the packages
        unavailable in Snowflake to the stage.

        This function will raise error if any of the above conditions are not met.

        Returns:
            List[str]: List of package specifiers
        r   Nr  r  r  r   r   zinformation_schema.packagesz
snowflake. _suppress_local_package_warningsF)r^  r  r  zCannot add dependency package ')cloudpicklerq  r  r  r  r   r  rd  rf  r  r   r"  r   r  r7  r  r  r  r  r  r  operatorrj  )r	  r  r  r  r  r^  r  kwargsextra_modulesr  r  r  pkg_namer  pkg_reqr  r  r  r  specpackage_specsrj  added_package_has_versions                          r   r  zSession._resolve_packages"  s   4 %  * ++H5tzz#78". F## /&."&..K"&"D"D+#K -9,?,?,A =(Ha K/LK,AA&"6s7|nJ{[cOdNe f4 !4 14GH-= v;!# )O[1_&v.. %//4 **,-0N0N{1   6((*(8M  )	*@*L&RT 
 #'"?"? !106

61 #@ 	# / 5||>E>O>O!6:T]]DLL1! ! 2?-*1-D;&*48K<M4M14T9Jc#O : #-"A$r' S++6t+<*==O!Q#  -0LD)(+GK%'5* **,-0N0N{1 O)	 )	U/ /|!))	 )	s3   B5I*#AI<0I7I<$A<I<*I47I<<Jr  c                    |j                  dd      st        j                  d       	 t        j                         }|j
                  }t        j                  j                  |d      }t        j                  j                  |      st        j                  |       t        ||       t        |      }| j                  |j                         D 	cg c]  }	|	j
                   c}	|      }
t        ||      }t!        t#        |j                               |
||      \  }}}t%        |      dkD  r|j                  dd      st'        d      t)        ||z   ||       t+        |      }t,         d	| d
}t        j                  j                  ||      }t/        ||       | j1                         }|j                  dd      rD|d   }t2         d}t5        | d|       }| j7                  d| dd      j9                         D ci c]  }|d   |d   r|d   ng  }}t        j;                  d|        dj                  ||z   D cg c]  }t=        |       c}      ||<   t        j                  j                  |j
                  |      }t?        |d      5 }|jA                         D ]  \  }}|jC                  | d| d        	 ddd       | jD                  jG                  tI        |      t5        |      dd       | jD                  jG                  tI        |      t5        |      dd       | d| }| jK                  |jM                  tN              r|n	tN         |        	 |r|jU                          ||z   S c c}	w c c}w c c}w # 1 sw Y   xY w# tP        $ r}tS        d| d| d      d}~ww xY w# r|jU                          w w xY w)a+  
        Uploads a list of Pypi packages, which are unavailable in Snowflake, to session stage.

        Args:
            packages (List[str]): List of package names requested by the user, that are not present in Snowflake.
            package_table (str): Name of Snowflake table containing information about Anaconda packages.
            package_dict (Dict[str, str]): A dictionary of package name -> package spec of packages that have
                been added explicitly so far using add_packages() or other such methods.

        Returns:
            List[packaging.requirements.Requirement]: List of package dependencies (present in Snowflake) that would need to be added
            to the package dictionary.

        Raises:
            RuntimeError: If any failure occurs in the workflow.

        r  FzIf you are adding package(s) unavailable in Snowflake, it is highly recommended that you include the 'cache_path' configuration parameter in order to reduce latency.r  )r  r  r   
force_pushzYour code depends on packages that contain native code, it may not work on Snowflake! Set Session.custom_package_usage_config['force_push'] to True if you wish to proceed with using them anyway.r  rc  .txtrd  0SELECT t.$1 as signature, t.$2 as packages from  tr  r   z
METADATA: |w,r\  NT)r:  rg  rk  rl  z Unable to auto-upload packages: z	, Error: z | NOTE: Alternatively, you can find the directory of these packages and add it via Session.add_import. See details at https://docs.snowflake.com/en/developer-guide/snowpark/python/creating-udfs.html#using-third-party-packages-from-anaconda-in-a-udf.)+r  r  rp   tempfileTemporaryDirectoryr  rI  r:  joinrT  makedirsrA   r>   r  r8  r;   r=   r7  r   r"  r:   r<   r9   rB   get_session_stager8   re   r  r  r  r   openr  writer  rt  rd   rE  rH  rN   r  r  cleanup)r	  r  r  r  r  tmpdir_handlertmpdirtargetdownloaded_packages_dictr  valid_downloaded_packagesnative_packagessupported_dependenciesdropped_dependenciesnew_dependenciesr  zip_filezip_path
stage_namemetadata_filenormalized_metadata_pathr  r  requirementmetadata_local_pathfiler
  r  stage_zip_pathr  s                                 r   r  z$Session._upload_unsupported_packages  s/   0 +..|UCOO_
~	)%88:N#((FWW\\&*@AF77>>&)F#1(FC (PPV'W$ )-(Q(Q0H0M0M0O%,GLL $1	 )R )% 90O ,-2245)		&$  ?#a'0K0O0Oe1 !E  /&)==( *7x)@!013H2INHww||FH5H"684 //1J*..|UC8F
 $B"B$ G+G!l!M?3,( NOgNhhjk&+ !  546 Fc!fCF"4  z(45 36(( ,BDT+T' K(3./ ')ggll>3F3F&V#-s3 7t&.nn&6 7
U

cU!E7"#5677 

&&-.AB#?
#K"'"	 '  JJ"")(3;JG"	 #  !+|1XJ7NOO!,,\: $~n%56 &&(%(888cp7 76  	28*IaS I@ A 	 &&( si   B(N" N$D$N" N,N" NA N" 0NB!N" N" NN" "	O+N==OO Oc                 0    | j                  d      d   d   S )Nz/select system$are_anaconda_terms_acknowledged()r   )
_run_queryr)  s    r   r  z'Session._is_anaconda_terms_acknowledged=	  s    PQRSTUVWWr   r  r  c                    t          d}| j                  |      }||vrt        j                  d| d| d       yt         d| d}||vrt        j                  d| d       y| d	| }| j                  d
t        |       dd      j                  t        d      |k(  d      j                         D ci c]!  }|d   |d   r|d   j                  d      ng # }}||   D 	cg c]  }	t        |	       }
}	t        j                  d||    d       | d	t         d| d}| j                  |j                  t              r|       |
S t         |        |
S c c}w c c}	w )a  
        Uses specified stage path to auto-import a group of unsupported packages, along with its dependencies. This
        saves time spent on pip install, native package detection and zip upload to stage.

        A cached environment on a stage consists of two files:
        1. A metadata dictionary, pickled using cloudpickle, which maps environment signatures to a list of
        Anaconda-supported dependency packages required for that environment.
        2. Zip files named '{PACKAGES_ZIP_NAME}_<environment_signature>.zip.gz which contain the unsupported packages.

        Note that a cached environment is only useful if you wish to use packages unsupported in Snowflake! Supported
        packages will not be cached (and need not be cached).

        Also note that any changes to your package list, which does not involve changing the versions or names
        of unsupported packages, will not necessarily affect your environment signature. Your environment signature
        corresponds only to packages currently not supported in the Anaconda channel.

        Args:
            environment_signature (str): Unique hash signature for a set of unsupported packages, computed by hashing
            a sorted tuple of unsupported package requirements (package versioning included).
        Returns:
            Optional[List[packaging.requirements.Requirement]]: A list of package dependencies for the set of unsupported packages requested.
        r  zMetadata file named z not found at stage path r  Nr  z.zip.gzz2Matching environment file not found at stage path rd  r  r  Fr  	signaturer   r   r  z#Loading dependency packages list - )r8   ro  r  r  r9   r  re   filterr   r  r  r   rE  rH  rN   )r	  r  r  r  filesrequired_filemetadata_file_pathr  r  r  r  r;  s               r   r  z-Session._load_unsupported_packages_from_stage@	  s   4 ::$?33J?%LL&}o5NzlZ[\  22!4I3J'R%LLDZLPQR  !+|1]O< FGcdvGwFxxz{#   K(,AAUS++-

 FQCFLL%R7

 

 199N0O
%,K 
 
 	1(;P2Q1RRST	

 l!2315J4K7S 	 	%%l3 	

 #" !>+/	

 #"7


s   :&E )E%r  r  c                    |rt        |      dkD  r| j                  |d      j                  t        dd      dk(  t        dd      j	                  |d      z  d      j                  dd      j                  t        dd      d      j                  |      D ci c]  }|d   t        j                  |d	           c}}|S d }|S c c}w )
Nr   Fr  languagepythonr  rj  r]  r   )r   tabler  r   in_group_byaggr   r  jsonloads)r	  r  r  r  r^  ppackage_to_version_mappings          r   r  z,Session._get_available_versions_for_packages	  s    0  C$6$: $6%Hu5ANe<@@)U A  $   .E:YyE:eL++=M+N !djj1&& 	#( *) % 	#( *)'s   !#Cc                     | j                   S )a  
        The query tag for this session.

        :getter: Returns the query tag. You can use the query tag to find all queries
            run for this session in the History page of the Snowflake web interface.

        :setter: Sets the query tag. If the input is ``None`` or an empty :class:`str`,
            the session's query_tag will be unset. If the query tag is not set, the default
            will be the call stack when a :class:`DataFrame` method that pushes down the SQL
            query to the Snowflake Database is called. For example, :meth:`DataFrame.collect`,
            :meth:`DataFrame.show`, :meth:`DataFrame.create_or_replace_view` and
            :meth:`DataFrame.create_or_replace_temp_view` will push down the SQL query.

        Note:
            The setter calls ``ALTER SESSION SET QUERY_TAG = <tag>`` which may be restricted
            in some environments such as Owner's rights stored procedures. Refer to
            `Owner's rights stored procedures <https://docs.snowflake.com/en/developer-guide/stored-procedure/stored-procedures-rights#owner-s-rights-stored-procedures>`_.
            for more details.

        )rb  r)  s    r   	query_tagzSession.query_tag	  s    , r   tagc                     | j                   5  |r(| j                  j                  dt        |              n| j                  j                  d       || _        d d d        y # 1 sw Y   y xY w)Nzalter session set query_tag = zalter session unset query_tag)r  r  r5  r"   rb  )r	  r)  s     r   r(  zSession.query_tag	  s[    ZZ 	"

$$'EjQToEV%WX

$$%DE!DO	" 	" 	"s   AA##A,c                     | j                  dd      j                         }t        |      dk7  st        |d   d      st	        d      |d   j
                  S )z9
        Fetches the current sessions query tag.
        z SHOW PARAMETERS LIKE 'QUERY_TAG'Fr  r   r   r  z@Snowflake server side query tag parameter has unexpected schema.)r  '_internal_collect_with_tag_no_telemetryr   r  r"  r  )r	  remote_tag_rowss     r   _get_remote_query_tagzSession._get_remote_query_tag	  sh     ((.% # 

1
1
3 	 1$GOA4F,PR  q!'''r   	separatorc                 l    |r2| j                         }|j                  d ||fD              }|| _        yy)a  
        Appends a tag to the current query tag. The input tag is appended to the current sessions query tag with the given separator.

        Args:
            tag: The tag to append to the current query tag.
            separator: The string used to separate values in the query tag.
        Note:
            Assigning a value via session.query_tag will remove any appended query tags.

        Example::
            >>> session.query_tag = "tag1"
            >>> session.append_query_tag("tag2")
            >>> print(session.query_tag)
            tag1,tag2
            >>> session.query_tag = "new_tag"
            >>> print(session.query_tag)
            new_tag

        Example::
            >>> session.query_tag = ""
            >>> session.append_query_tag("tag1")
            >>> print(session.query_tag)
            tag1

        Example::
            >>> session.query_tag = "tag1"
            >>> session.append_query_tag("tag2", separator="|")
            >>> print(session.query_tag)
            tag1|tag2

        Example::
            >>> session.sql("ALTER SESSION SET QUERY_TAG = 'tag1'").collect()
            [Row(status='Statement executed successfully.')]
            >>> session.append_query_tag("tag2")
            >>> print(session.query_tag)
            tag1,tag2
        c              3   &   K   | ]	  }|s|  y wr   r   )r  ts     r   r  z+Session.append_query_tag.<locals>.<genexpr>	  s     $G1QQ$Gs   N)r.  r  r(  )r	  r)  r/  
remote_tagnew_tags        r   r>  zSession.append_query_tag	  s;    L 335Jnn$GS0A$GGG$DN r   c                     |rV| j                         xs d}	 t        j                  |      }|j                  |       t        j                  |      | _        yy# t        j                  $ r t        d|       w xY w)aI  
        Updates a query tag that is a json encoded string. Throws an exception if the sessions current query tag is not a valid json string.


        Args:
            tag: The dict that provides updates to the current query tag dict.
        Note:
            Assigning a value via session.query_tag will remove any current query tag state.

        Example::
            >>> session.query_tag = '{"key1": "value1"}'
            >>> session.update_query_tag({"key2": "value2"})
            >>> print(session.query_tag)
            {"key1": "value1", "key2": "value2"}

        Example::
            >>> session.sql("ALTER SESSION SET QUERY_TAG = '{\"key1\": \"value1\"}'").collect()
            [Row(status='Statement executed successfully.')]
            >>> session.update_query_tag({"key2": "value2"})
            >>> print(session.query_tag)
            {"key1": "value1", "key2": "value2"}

        Example::
            >>> session.query_tag = ""
            >>> session.update_query_tag({"key1": "value1"})
            >>> print(session.query_tag)
            {"key1": "value1"}
        z{}z8Expected query tag to be valid json. Current query tag: N)r.  r#  r$  updatedumpsr(  JSONDecodeErrorr"  )r	  r)  tag_strtag_dicts       r   r=  zSession.update_query_tag
  s|    : 002:dG::g.$!%H!5  ''  NwiX s   A A "A<)time_travel_mode	statementoffset	timestamptimestamp_typestreamr  is_temp_table_for_cleanupr  r;  )atbeforer<  r=  r>  r?  r@  c                   |r| j                   j                         }
t        |
j                  j                  |
      }t        |j                  |       d|j                  _        ||_	        |||j                  _        |||j                  _        |||j                  _        |t        |j                  |       |t!        |      |j"                  _        |	|	|j$                  _        nd}
t'        |t               s!t'        |t(              rdj+                  |      }t-        |       t/        || ||
|||||||	      }t1        |d       |S )aL  
        Returns a Table that points the specified table.

        Args:
            name: A string or list of strings that specify the table name or
                fully-qualified object identifier (database name, schema name, and table name).

            _emit_ast: Whether to emit AST statements.

            time_travel_mode: Time travel mode, either 'at' or 'before'.
                Exactly one of statement, offset, timestamp, or stream must be provided when time_travel_mode is set.
            statement: Query ID for time travel.
            offset: Negative integer representing seconds in the past for time travel.
            timestamp: Timestamp string or datetime object.
            timestamp_type: Type of timestamp interpretation ('NTZ', 'LTZ', or 'TZ').
            stream: Stream name for time travel.

            Note:
                If your table name contains special characters, use double quotes to mark it like this, ``session.table('"my table"')``.
                For fully qualified names, you need to use double quotes separately like this, ``session.table('"my db"."my schema"."my.table"')``.
                Refer to `Identifier Requirements <https://docs.snowflake.com/en/sql-reference/identifiers-syntax.html>`_.

        Examples::

            >>> df1 = session.create_dataframe([[1, 2], [3, 4]], schema=["a", "b"])
            >>> df1.write.save_as_table("my_table", mode="overwrite", table_type="temporary")
            >>> session.table("my_table").collect()
            [Row(A=1, B=2), Row(A=3, B=4)]
            >>> current_db = session.get_current_database()
            >>> current_schema = session.get_current_schema()
            >>> session.table([current_db, current_schema, "my_table"]).collect()
            [Row(A=1, B=2), Row(A=3, B=4)]

            >>> df_at_time = session.table("my_table", time_travel_mode="at", timestamp="2023-01-01 12:00:00", timestamp_type="LTZ") # doctest: +SKIP
            >>> df_before = session.table("my_table", time_travel_mode="before", statement="01234567-abcd-1234-5678-123456789012") # doctest: +SKIP
            >>> df_offset = session.table("my_table", time_travel_mode="at", offset=-3600) # doctest: +SKIP
            >>> df_stream = session.table("my_table", time_travel_mode="at", stream="my_stream") # doctest: +SKIP

            # timestamp_type automatically set to "TZ" due to timezone info
            >>> import datetime, pytz  # doctest: +SKIP
            >>> tz_aware = datetime.datetime(2023, 1, 1, 12, 0, 0, tzinfo=pytz.UTC)  # doctest: +SKIP
            >>> table1 = session.read.table("my_table", time_travel_mode="at", timestamp=tz_aware)  # doctest: +SKIP

            # timestamp_type remains "NTZ" (user's explicit choice respected)
            >>> table2 = session.read.table("my_table", time_travel_mode="at", timestamp=tz_aware, timestamp_type="NTZ")  # doctest: +SKIP
        TNr  )
r   rA  	_ast_stmtr  r;  r<  r=  r>  r?  r@  zSession.table)r  bindr4   exprr  r3   r  variantsession_tablerA  r;  r  r<  r=  r0   r>  r   r?  r@  r  r   r  rn   r   rD   )r	  r  rA  r  r;  r<  r=  r>  r?  r@  stmtastr2  s                r   r  zSession.table*
  s0   x ??'')D#DIIOOT:CSXXt,(,CKK%,EC)+-=$$*$&/#!#)

 $*3==)D)+.~+>""(!#)

 D$$D()C88D>DT"&?-)
 	A/r   r  	func_name.func_argumentsfunc_named_argumentsc          
         d}|rjt        | j                  |       | j                  j                         }t        |j                  j
                  |      }t        |j                  |g|i | t        | j                  t              rvt        | j                  t              s\| j                  j                  rE| j                  g t        t        dt!                     g      d      }|r|j"                  |_        |S 	 t'        |g|i |}| j(                  rJt+        | | j,                  j/                  t1        || j,                        | j,                        ||      }	nt+        | t3        |      ||      }	t5        |	d       |	S )	a$
  Creates a new DataFrame from the given snowflake SQL table function.

        References: `Snowflake SQL functions <https://docs.snowflake.com/en/sql-reference/functions-table.html>`_.

        Example 1
            Query a table function by function name:

            >>> import sys, pytest; _ = (sys.version_info[:2] != (3, 9)) or pytest.skip()
            >>> from snowflake.snowpark.functions import lit
            >>> session.table_function("split_to_table", lit("split words to table"), lit(" ")).collect()
            [Row(SEQ=1, INDEX=1, VALUE='split'), Row(SEQ=1, INDEX=2, VALUE='words'), Row(SEQ=1, INDEX=3, VALUE='to'), Row(SEQ=1, INDEX=4, VALUE='table')]

        Example 2
            Define a table function variable and query it:

            >>> from snowflake.snowpark.functions import table_function, lit
            >>> split_to_table = table_function("split_to_table")
            >>> session.table_function(split_to_table(lit("split words to table"), lit(" "))).collect()
            [Row(SEQ=1, INDEX=1, VALUE='split'), Row(SEQ=1, INDEX=2, VALUE='words'), Row(SEQ=1, INDEX=3, VALUE='to'), Row(SEQ=1, INDEX=4, VALUE='table')]

        Example 3
            If you want to call a UDTF right after it's registered, the returned ``UserDefinedTableFunction`` is callable:

            >>> from snowflake.snowpark.types import IntegerType, StructField, StructType
            >>> from snowflake.snowpark.functions import udtf, lit
            >>> class GeneratorUDTF:
            ...     def process(self, n):
            ...         for i in range(n):
            ...             yield (i, )
            >>> generator_udtf = udtf(GeneratorUDTF, output_schema=StructType([StructField("number", IntegerType())]), input_types=[IntegerType()])
            >>> session.table_function(generator_udtf(lit(3))).collect()
            [Row(NUMBER=0), Row(NUMBER=1), Row(NUMBER=2)]

        Args:
            func_name: The SQL function name.
            func_arguments: The positional arguments for the SQL function.
            func_named_arguments: The named arguments for the SQL function, if it accepts named arguments.

        Returns:
            A new :class:`DataFrame` with data from calling the table function.

        See Also:
            - :meth:`DataFrame.join_table_function`, which lateral joins an existing :class:`DataFrame` and a SQL function.
            - :meth:`Session.generator`, which is used to instantiate a :class:`DataFrame` using Generator table function.
                Generator functions are not supported with :meth:`Session.table_function`.
        Nr  Fschemar  r  from_r  rE  r  zSession.table_function)r/   r  rF  r4   rG  session_table_functionr1   fnr  r  r   r   _suppress_not_implemented_errorcreateDataFramer   r   r   uid_ast_idr   r  r|   r  create_select_statementr&   r,   rD   )
r	  rL  r  rM  rN  rJ  rK  ans	func_exprds
             r   table_functionzSession.table_function
  s}   n !$//9=??'')D#DII$D$DdKC)   '	 djj"67
JJA
 zz99 **%{5+-'H&IJ# + 
 "&((CK
 5
&
*>
	 &&66-i$..Q!^^ 7  #A %i0#	A 	A78r   r   )rowcount	timelimitr  columnsra  rb  c          
         d}|r| j                   j                         }t        |j                  j                  |      }t        | \  }|j                  _        |D ]1  }|j                  j                  j                  |j                         3 ||_        ||_        ddlm}	 t        | j                   |	      r[| j                   j"                  rE| j%                  g t'        t)        dt+                     g      d      }
|r|j,                  |
_        |
S t        | j                   |	      r!| j                   j1                  dt2               |st5        d	      i }|dk7  rt7        |      j8                  |d
<   |dk7  rt7        |      j8                  |d<   |D cg c](  }| j:                  j=                  |j8                  i       * }}t?        ||      }| j@                  r:tC        | tE        tG        || j:                        | j:                        ||      }ntC        | tI        |      ||      }tK        |d       |S c c}w )a  Creates a new DataFrame using the Generator table function.

        References: `Snowflake Generator function <https://docs.snowflake.com/en/sql-reference/functions/generator.html>`_.

        Args:
            columns: List of data generation function that work in tandem with generator table function.
            rowcount: Resulting table with contain ``rowcount`` rows if only this argument is specified. Defaults to 0.
            timelimit: The query runs for ``timelimit`` seconds, generating as many rows as possible within the time frame. The
                exact row count depends on the system speed. Defaults to 0.

        Usage Notes:
                - When both ``rowcount`` and ``timelimit`` are specified, then:

                    + if the ``rowcount`` is reached before the ``timelimit``, the resulting table with contain ``rowcount`` rows.
                    + if the ``timelimit`` is reached before the ``rowcount``, the table will contain as many rows generated within this time.
                - If both ``rowcount`` and ``timelimit`` are not specified, 0 rows will be generated.

        Example 1
            >>> from snowflake.snowpark.functions import seq1, seq8, uniform
            >>> df = session.generator(seq1(1).as_("sequence one"), uniform(1, 10, 2).as_("uniform"), rowcount=3)
            >>> df.show()
            ------------------------------
            |"sequence one"  |"UNIFORM"  |
            ------------------------------
            |0               |3          |
            |1               |3          |
            |2               |3          |
            ------------------------------
            <BLANKLINE>

        Example 2
            >>> df = session.generator(seq8(0), uniform(1, 10, 2), timelimit=1).order_by(seq8(0)).limit(3)
            >>> df.show()
            -----------------------------------
            |"SEQ8(0)"  |"UNIFORM(1, 10, 2)"  |
            -----------------------------------
            |0          |3                    |
            |1          |3                    |
            |2          |3                    |
            -----------------------------------
            <BLANKLINE>

        Returns:
            A new :class:`DataFrame` with data from calling the generator table function.
        Nr   r   r  FrP  zDataFrame.generatorr  z4Columns cannot be empty for generator table functionra  rb  )args	operators)r^  r  rS  rU  zSession.generator)&r  rF  r4   rG  	generatorrg   rc  variadicre  rq  _ast	row_counttime_limit_seconds#snowflake.snowpark.mock._connectionr   r  r  rX  rY  r   r   r   rZ  r[  r  r  r"  r   _expressionr  analyzer+   r  r|   r%   r&   r,   rD   )r	  ra  rb  r  rc  rJ  rK  	col_namescol_namer   r]  
named_argsr   rf  r^  r_  s                   r   rg  zSession.generator  s   l ??'')D#DII$7$7>C.T/+Is{{+ & 7  ''67$CM%.C" 	M tzz#78

:: &&!;ukm#D"EF ' C
 "hhJdjj"67JJ..&;/ /  STT
q=%(]%>%>Jz">&))n&@&@J{#LSTST^^++COOR@T	T*
iP	&&-"+dnn "^^	 #
A %i0#	A 	A23/ Us   -I queryparamsrE  c           
         d}|rs|o| j                   j                         }t        |j                  j                  |      }||_        |.|D ]&  }t        |j                  j                         |       ( n|}t        | j                  t              r^| j                  j                  sH| j                  j                         rt        dd      | j                  j                  dt                | j"                  rKt%        | | j&                  j)                  t+        || j&                  |      | j&                        ||	      }n5t%        | | j&                  j,                  j                  |d|
      ||	      }t/        |d       |S )a  
        Returns a new DataFrame representing the results of a SQL query.

        Note:
            You can use this method to execute a SQL query lazily,
            which means the SQL is not executed until methods like :func:`DataFrame.collect`
            or :func:`DataFrame.to_pandas` evaluate the DataFrame.
            For **immediate execution**, chain the call with the collect method: `session.sql(query).collect()`.

        Args:
            query: The SQL statement to execute.
            params: binding parameters. We only support qmark bind variables. For more information, check
                https://docs.snowflake.com/en/developer-guide/python-connector/python-connector-example#qmark-or-numeric-binding
            _ast_stmt: when invoked internally, supplies the AST to use for the resulting dataframe.

        Example::

            >>> # create a dataframe from a SQL query
            >>> df = session.sql("select 1/2")
            >>> # execute the query
            >>> df.collect()
            [Row(1/2=Decimal('0.500000'))]

            >>> # Use params to bind variables
            >>> session.sql("select * from values (?, ?), (?, ?)", params=[1, "a", 2, "b"]).sort("column1").collect()
            [Row(COLUMN1=1, COLUMN2='a'), Row(COLUMN1=2, COLUMN2='b')]
        NzBCannot perform this operation because the session has been closed.1404)rD  zSession.sqlr  )r  rs  rS  rU  )source_planrs  )r  rF  r4   rG  r  rr  r0   rs  r   r  r  r   rX  r  r   r  r  r  r|   r  r\  r$   plan_builderrD   )	r	  rr  rs  rE  r  rJ  rG  r%  r_  s	            r   r  zSession.sqlz  sm   H  ++-(="
%# I24;;??3DaHI ! tzz#78JJ>>zz##%.X%  JJ..&3/ / 
 &&66#EDNN6R!^^ 7  #A ++11tF 2  #A 	A}-r   c                     t        |       S )zReturns a :class:`DataFrameReader` that you can use to read data from various
        supported sources (e.g. a file in a stage) as a DataFrame.r}   r)  s    r   readzSession.read  s     t$$r   c                     | j                   S )zBReturns an integer that represents the session ID of this session.)rh  r)  s    r   
session_idzSession.session_id  s     r   c                 .    | j                   j                   S )zReturns a :class:`SnowflakeConnection` object that allows you to access the connection between the current session
        and Snowflake server.)r  r)  s    r   r:  zSession.connection  s     zzr   is_ddl_on_temp_objectlog_on_exceptionc                 F    | j                   j                  ||||      d   S )N)r}  r~  _statement_paramsdata)r  r5  )r	  rr  r}  r~  r^  s        r   r  zSession._run_query  s6     zz##"7-.	 $ 

  	r   query_paramsc                 :    | j                   j                  ||      S r   )r  get_result_attributes)r	  rr  r  s      r   _get_result_attributeszSession._get_result_attributes  s     zz//|DDr   c                 >   | j                   5  | j                  s]| j                  t        t        j
                              }| j                  dt        | j                  d       d| d|       || _        ddd       t         | j                   S # 1 sw Y   xY w)at  
        Returns the name of the temporary stage created by the Snowpark library
        for uploading and storing temporary artifacts for this session.
        These artifacts include libraries and packages for UDFs that you define
        in this session via :func:`add_import`.

        Note:
            This temporary stage is created once under the current database and schema of a Snowpark session.
            Therefore, if you switch database or schema during the session, the stage will not be re-created
            in the new database or schema, and still references the stage in the old database or schema.
        zcreate Tz)                     stage if not exists )r}  r^  N)
r  rk  $get_fully_qualified_name_if_possiblerj   rS   STAGEr  r`   r{   rN   )r	  r^  full_qualified_stage_names      r   r  zSession.get_session_stage  s     ZZ 	@&&,0,U,U/0D0DE-) 6t7T7TVZ[\ ]))B(CE*.%5	    '@#	@  3 3455	@ 	@s   A*BBz1.28.0gzipabort_statement   r  )databaserQ  r<  compressionon_erroruse_vectorized_scannerparallelquote_identifiersauto_create_tablerl  
table_typeuse_logical_typer  r  zpyarrow.Table
table_namer  rQ  r  r  r  r  r  r  rl  r  )r  temp	temporary	transientr  r  c                   | j                   j                   j                         }|
r#|rd|z   dz   nd|rd|z   dz   ndz   d|z   dz   z   }n|r|dz   nd|r|dz   ndz   |z   }t        di d|d|d|d|d	|d
|d|d|d|d|	d|
d|d|d|d|d| j                  xr
 t	               \  }}}}|r!| j                  |d      }t        |d       |S t        d|       )aG  Writes a pyarrow.Table to a Snowflake table.

        The pyarrow Table is written out to temporary files, uploaded to a temporary stage, and then copied into the final location.

        This function requires the optional dependenct snowflake-snowpark-python[pandas] be installed.

        Returns a Snowpark Table that references the table referenced by table_name.

        Args:
            table: The pyarrow Table that is written.
            table_name: Table name where we want to insert into.
            database: Database schema and table is in, if not provided the default one will be used (Default value = None).
            schema: Schema table is in, if not provided the default one will be used (Default value = None).
            chunk_size: Number of rows to be inserted once. If not provided, all rows will be dumped once.
                Default to None normally, 100,000 if inside a stored procedure.
                Note: If auto_create_table or overwrite is set to True, the chunk size may affect schema
                inference because different chunks might contain varying data types,
                especially when None values are present. This can lead to inconsistencies in inferred types.
            compression: The compression used on the Parquet files, can only be gzip, or snappy. Gzip gives a
                better compression, while snappy is faster. Use whichever is more appropriate (Default value = 'gzip').
            on_error: Action to take when COPY INTO statements fail, default follows documentation at:
                https://docs.snowflake.com/en/sql-reference/sql/copy-into-table.html#copy-options-copyoptions
                (Default value = 'abort_statement').
            use_vectorized_scanner: Boolean that specifies whether to use a vectorized scanner for loading Parquet files. See details at
                `copy options <https://docs.snowflake.com/en/sql-reference/sql/copy-into-table.html#copy-options-copyoptions>`_.
            parallel: Number of threads to be used when uploading chunks, default follows documentation at:
                https://docs.snowflake.com/en/sql-reference/sql/put.html#optional-parameters (Default value = 4).
            quote_identifiers: By default, identifiers, specifically database, schema, table and column names
                (from df.columns) will be quoted. If set to False, identifiers are passed on to Snowflake without quoting.
                I.e. identifiers will be coerced to uppercase by Snowflake.  (Default value = True)
            auto_create_table: When true, will automatically create a table with corresponding columns for each column in
                the passed in DataFrame. The table will not be created if it already exists
            table_type: The table type of to-be-created table. The supported table types include ``temp``/``temporary``
                and ``transient``. Empty means permanent table as per SQL convention.
            use_logical_type: Boolean that specifies whether to use Parquet logical types. With this file format option,
                Snowflake can interpret Parquet logical types during data loading. To enable Parquet logical types,
                set use_logical_type as True. Set to None to use Snowflakes default. For more information, see:
                https://docs.snowflake.com/en/sql-reference/sql/create-file-format
        "".r  r  cursorr  r  r  rQ  r<  r  r  r  r  r  r  rl  r  r  use_scoped_temp_objectFr  zSession.write_arrowz;Failed to write arrow table to Snowflake. COPY INTO output r   )r  r  r!   r{   rc   r  rD   r   )r	  r  r  r  rQ  r<  r  r  r  r  r  r  rl  r  r  r  r  r  locationsuccessr  	ci_outputs                         r   r!   zSession.write_arrow  s   z !!((*,4#.4'",2C&L4'<#c)+  $,C#)6C<r3  $/ $
$
$
 "$
 	$

 $
 "$
 $$
 $
 $:$
 $
 0$
 0$
  $
 "$
 .$
  $(#@#@ $)&(#$
 Ay( JJx5J9E'<=L*Mi[Y r   df)modin.pandas.DataFramemodin.pandas.Seriesr  indexindex_label
IndexLabelc                     |st        d      dt        dt        fd}|g}|r ||      g|z   }|r ||      g|z   }|s | j                  |      st        d| d      |rdnd}|j	                  |||	|
|	       y
)a
  A helper method used by `write_pandas` to write Snowpark pandas DataFrame or Series to a table by using
        :func:`modin.pandas.DataFrame.to_snowflake <modin.pandas.DataFrame.to_snowflake>` or
        :func:`modin.pandas.Series.to_snowflake <modin.pandas.Series.to_snowflake>` internally

        Args:
            df: The Snowpark pandas DataFrame or Series we'd like to write back.
            table_name: Name of the table we want to insert into.
            location: the location of the table in string.
            database: Database that the table is in. If not provided, the default one will be used.
            schema: Schema that the table is in. If not provided, the default one will be used.
            quote_identifiers: By default, identifiers, specifically database, schema, table and column names
                (from :attr:`DataFrame.columns`) will be quoted. `to_snowflake` always quote column names so
                quote_identifiers = False is not supported here.
            auto_create_table: When true, automatically creates a table to store the passed in pandas DataFrame using the
                passed in ``database``, ``schema``, and ``table_name``. Note: there are usually multiple table configurations that
                would allow you to upload a particular pandas DataFrame successfully. If you don't like the auto created
                table, you can always create your own table before calling this function. For example, auto-created
                tables will store :class:`list`, :class:`tuple` and :class:`dict` as strings in a VARCHAR column.
            overwrite: Default value is ``False`` and the pandas DataFrame data is appended to the existing table. If set to ``True`` and if auto_create_table is also set to ``True``,
                then it drops the table. If set to ``True`` and if auto_create_table is set to ``False``,
                then it truncates the table. Note that in both cases (when overwrite is set to ``True``) it will replace the existing
                contents of the table with that of the passed in pandas DataFrame.
            index: default True
                If true, save DataFrame index columns as table columns.
            index_label:
                Column label for index column(s). If None is given (default) and index is True,
                then the index names are used. A sequence should be given if the DataFrame uses MultiIndex.
            table_type: The table type of table to be created. The supported values are: ``temp``, ``temporary``,
                and ``transient``. An empty string means to create a permanent table. Learn more about table types
                `here <https://docs.snowflake.com/en/user-guide/tables-temp-transient.html>`_.
        z=quote_identifiers = False is not supported by `to_snowflake`.idr   c                     d| z   dz   S )Nr  r   )r  s    r   quote_idz4Session._write_modin_pandas_helper.<locals>.quote_id  s    8c>!r   z:Cannot write Snowpark pandas DataFrame or Series to table z} because it does not exist. Use auto_create_table = True to create table before writing a Snowpark pandas DataFrame or SeriesrX  rq  )r  	if_existsr  r  r  N)r  r   _table_existsr   to_snowflake)r	  r  r  r  r  rQ  r  r  rl  r  r  r  r  r  r  s                  r   _write_modin_pandas_helperz"Session._write_modin_pandas_helpery  s    ` !%O 	" 	" 	" |V$%,DX&'$.D ););D)A)LXJ Wp q  "+I	
#! 	 	
r   )r  rQ  r<  r  r  r  r  r  create_temp_tablerl  r  r  r  r  )pandas.DataFramer  r  r  c                   t        | j                  t              r!| j                  j                  dt               |rt        dd       d}|r(|j                         t        vrt        dt               t        |d      r#t        |j                        dk(  rt        d	      d
}	 |	r#|rd|z   dz   nd|rd|z   dz   ndz   d|z   dz   z   }n|r|dz   nd|r|dz   ndz   |z   }|Ft        j                  t              }d|j                   v }|r||d<   nt#        j$                  dd       t'               \  }}|rVt        ||j(                  |j*                  f      r4|j-                  dd
        | j.                  |||f|||	|
||d| d\  }}nRt        | j                  t              rdg }}n3t        | j                  j                  ||f|||||||	|
|||d|\  }}}}|r| j9                  |d      }t;        |d       |r| j<                  j?                         }tA        |jB                  j                  |      }|
|_"        ||tF        k7  r||jH                  _%        ||_&        ||_'        t        |tP        j(                        r?tS        |jT                  jV                  jX                  jZ                  |j\                         nt	        dt_        |             |rO|ja                         D ]<  \  }}|jb                  je                         } || _3        ti        | jj                  |       > ||_6        ||_7        ||_8        |	|_9        |}!|||!g}!||t        d      |g|!z   }!tS        |j\                  |!       ||_:        |jv                  |_<        |S t5        jz                  t}        |            # t        $ r8}|j0                  j3                  d      rt5        j6                        ||d
}~ww xY w)a  Writes a pandas DataFrame to a table in Snowflake and returns a
        Snowpark :class:`DataFrame` object referring to the table where the
        pandas DataFrame was written to.

        Args:
            df: The pandas DataFrame or Snowpark pandas DataFrame or Series we'd like to write back.
            table_name: Name of the table we want to insert into.
            database: Database that the table is in. If not provided, the default one will be used.
            schema: Schema that the table is in. If not provided, the default one will be used.
            chunk_size: Number of rows to be inserted once. If not provided, all rows will be dumped once.
                Default to None normally, 100,000 if inside a stored procedure.
                Note: If auto_create_table or overwrite is set to True, the chunk size may affect schema
                inference because different chunks might contain varying data types,
                especially when None values are present. This can lead to inconsistencies in inferred types.
            compression: The compression used on the Parquet files: gzip or snappy. Gzip gives supposedly a
                better compression, while snappy is faster. Use whichever is more appropriate.
            on_error: Action to take when COPY INTO statements fail. See details at
                `copy options <https://docs.snowflake.com/en/sql-reference/sql/copy-into-table.html#copy-options-copyoptions>`_.
            parallel: Number of threads to be used when uploading chunks. See details at
                `parallel parameter <https://docs.snowflake.com/en/sql-reference/sql/put.html#optional-parameters>`_.
            quote_identifiers: By default, identifiers, specifically database, schema, table and column names
                (from :attr:`DataFrame.columns`) will be quoted. If set to ``False``, identifiers
                are passed on to Snowflake without quoting, i.e. identifiers will be coerced to uppercase by Snowflake.
            auto_create_table: When true, automatically creates a table to store the passed in pandas DataFrame using the
                passed in ``database``, ``schema``, and ``table_name``. Note: there are usually multiple table configurations that
                would allow you to upload a particular pandas DataFrame successfully. If you don't like the auto created
                table, you can always create your own table before calling this function. For example, auto-created
                tables will store :class:`list`, :class:`tuple` and :class:`dict` as strings in a VARCHAR column.
            create_temp_table: (Deprecated) The to-be-created table will be temporary if this is set to ``True``. Note
                that to avoid breaking changes, currently when this is set to True, it overrides ``table_type``.
            overwrite: Default value is ``False`` and the pandas DataFrame data is appended to the existing table. If set to ``True`` and if auto_create_table is also set to ``True``,
                then it drops the table. If set to ``True`` and if auto_create_table is set to ``False``,
                then it truncates the table. Note that in both cases (when overwrite is set to ``True``) it will replace the existing
                contents of the table with that of the passed in pandas DataFrame.
            table_type: The table type of table to be created. The supported values are: ``temp``, ``temporary``,
                and ``transient``. An empty string means to create a permanent table. Learn more about table types
                `here <https://docs.snowflake.com/en/user-guide/tables-temp-transient.html>`_.
            use_logical_type: Boolean that specifies whether to use Parquet logical types when reading the parquet files
                for the uploaded pandas dataframe. With this file format option, Snowflake can interpret Parquet logical
                types during data loading. To enable Parquet logical types, set use_logical_type as True. Set to None to
                use Snowflakes default. For more information, see:
                `file format options: <https://docs.snowflake.com/en/sql-reference/sql/create-file-format#type-parquet>`_.
            use_vectorized_scanner: Boolean that specifies whether to use a vectorized scanner for loading Parquet files. See details at
                `copy options <https://docs.snowflake.com/en/sql-reference/sql/copy-into-table.html#copy-options-copyoptions>`_.

        Example::

            >>> import pandas as pd
            >>> pandas_df = pd.DataFrame([(1, "Steve"), (2, "Bob")], columns=["id", "name"])
            >>> snowpark_df = session.write_pandas(pandas_df, "write_pandas_table", auto_create_table=True, table_type="temp")
            >>> snowpark_df.sort('"id"').to_pandas()
               id   name
            0   1  Steve
            1   2    Bob

            >>> pandas_df2 = pd.DataFrame([(3, "John")], columns=["id", "name"])
            >>> snowpark_df2 = session.write_pandas(pandas_df2, "write_pandas_table", auto_create_table=False)
            >>> snowpark_df2.sort('"id"').to_pandas()
               id   name
            0   1  Steve
            1   2    Bob
            2   3   John

            >>> pandas_df3 = pd.DataFrame([(1, "Jane")], columns=["id", "name"])
            >>> snowpark_df3 = session.write_pandas(pandas_df3, "write_pandas_table", auto_create_table=False, overwrite=True)
            >>> snowpark_df3.to_pandas()
               id  name
            0   1  Jane

            >>> pandas_df4 = pd.DataFrame([(1, "Jane")], columns=["id", "name"])
            >>> snowpark_df4 = session.write_pandas(pandas_df4, "write_pandas_transient_table", auto_create_table=True, table_type="transient")
            >>> snowpark_df4.to_pandas()
               id  name
            0   1  Jane

        Note:
            1. Unless ``auto_create_table`` is ``True``, you must first create a table in
            Snowflake that the passed in pandas DataFrame can be written to. If
            your pandas DataFrame cannot be written to the specified table, an
            exception will be raised.

            2. If the dataframe is Snowpark pandas :class:`~modin.pandas.DataFrame`
            or :class:`~modin.pandas.Series`, it will call
            :func:`modin.pandas.DataFrame.to_snowflake <modin.pandas.DataFrame.to_snowflake>`
            or :func:`modin.pandas.Series.to_snowflake <modin.pandas.Series.to_snowflake>`
            internally to write a Snowpark pandas DataFrame into a Snowflake table.

            3. If the input pandas DataFrame has `datetime64[ns, tz]` columns and `auto_create_table` is set to `True`,
            they will be converted to `TIMESTAMP_LTZ` in the output Snowflake table by default.
            If `TIMESTAMP_TZ` is needed for those columns instead, please manually create the table before loading data.
        zSession.write_pandasr  zwrite_pandas.create_temp_tablezcreate_temp_table is deprecated. We still respect this parameter when it is True but please consider using `table_type="temporary"` instead.r  z.Unsupported table type. Expected table types: rc  r   >The provided schema or inferred schema cannot be None or emptyNr  r  r  r  r  zuse_logical_type will be ignored because current python connector version does not support it. Please upgrade snowflake-connector-python to 3.4.0 or above.r   
stacklevel)r  rQ  r  r  rl  r  )Tr  T)r  rQ  r<  r  r  r  r  r  rl  r  r  zdoes not existFr  z)Only pandas DataFrame supported, but not z'Need to set schema when using database.)?r  r  r   r  r  rp   r1  rO   r"  r  r   rc  r   inspectr  r   
parameterswarningswarnrb   r|   Seriesr+  r  msgrZ  r5   (DF_PANDAS_TABLE_DOES_NOT_EXIST_EXCEPTIONr  rD   r  rF  r4   rG  r  r   r<  r  r  r  r   r3   r  dataframe_data__pandasr3  
temp_tabler  typer  r  r   _1r0   _2r  rl  r  r  r  rZ  r[  DF_PANDAS_GENERAL_EXCEPTIONr   )"r	  r  r  r  rQ  r<  r  r  r  r  r  r  rl  r  r  r  r  r  r  r  r  use_logical_type_supportedmodin_pandasmodin_is_importedr  r  per  rJ  rK  r2  r3  r2  table_locations"                                     r   r   zSession.write_pandas  s\   l djj"67JJ..&</ / 
 0J
 %J***,4II@AV@WX  2y!c"**o&:"P  K	 08cHnt+b06ft+B@Z'#-/  (0X^R'-v|27!#   +#--l;	-?9CWCW-W*-1AF-. MMH $%	 /M.N+L+ Z\++\-@-@A& 

-t4/// &!&7&7')  &."djj*>?)-rYG/;

(("0 "*%#-$/!)!)*;*;"+#-/E0 !0,GQ92 JJx5J9E'=> ++-'		(>(>E(9%)j<S.S+5CNN("-(9%b&"2"23$5577BBEDTDT .CDH:N   & <1JJNN, 2144;<  ( )'(9% ",%&,n%=N'~()RSS&.Z.%@N @!+ $L1MMI u   	vv/05^^ 	s   (D:N: :	O;3O66O;r  r  c                 #  $ |t        d      t        |t              rt        d      t        |t        t
        f      sAt        r0t        r5t        |t        j                  t        j                  f      st        d      t        rHt        |t        j                  t        j                  f      r|t        j                  dt        d       |}t        rt        |t        j                  t        j                  f      rt        t        t         j"                              }t        | j$                  t&              rt)        |      \  }}np| j$                  j+                  dd	
      }| j$                  j+                  dd	
      }t        |t        j                        r3 | j,                  ||f||ddd| j.                  d	d|}	t1        |	d       n2 | j2                  ||f||ddd| j.                  d	d|}	t1        |	d       |r| j4                  j7                         }
t9        |
j:                  j<                  |
      }t?        |j@                  jB                  jD                  jF                  |       tI        |	jJ                  |jJ                  jL                  jD                         |
jN                  |	_(        |	S d$d}t        |tR              r*tU        |      }t        |tV              st        d| d      d	}t        |tV              r|}d}nA|st        d      t        |tX              rt	        |      $t[        t\        $fd|D              }t_        |j`                        dk(  rt        d      dtb        tX        td           td        f   dtf        tR           dtf        fd}$s$|j`                  D cg c]  }|jh                   c}$$D cg c]  }tk        |       }}|D cg c]  } |||       }}g g }}tm        |j`                  |      D ]  \  }}t        |jn                  tp        tr        tt        tv        tx        tz        tV        t|        t~        t        t        t        t        f      r
t               n|jn                  }|j                  t        |||j                               |j                  |jn                          |rt        | j$                  t&              st        |j`                  D cg c]  }|j                  d	u  c}      rt        |j`                  D cg c]  }|jn                  j                          c}      r[t        t         j"                        }t        j                  |      }	 | j                  d| d| d       d| j                  |       }g }|D ]  }g }tm        ||      D ]  \  }}||j                  d       t        |t        j                        r"t        |t              r|j                  |       Wt        |t        j                        r+t        |t~              r|j                  tS        |             t        |t        j                        r+t        |t|              r|j                  tS        |             t        |t        j                        r,t        |tr              r|j                  tS        |             't        |t              r|j                  |       Jt        |tt              r|j                  |       mt        |t              r|j                  |       t        |t        t
        t        f      r<t        |tp              r,|j                  t        j                  |t                      t        |t              rBt        |tz        tV        f      r,|j                  t        j                  |t                      9t        |t              r^t        |tV              rNt        j                         r:|j                  t        j                  |j                         t                      t        |t              r,|j                  t        j                  |t                      t        |tv              r|j                  |       t        |tx              r|j                  |       )t        |t              r|j                  |       Lt        |t              r,|j                  t        j                  |t                      t        d!t        |       d"| d#tS        |       d$       |j                  t        |         g } tm        |j`                  $      D ]  \  }}t        |jn                  t              r]| j                  t        t        |      |jn                  j                  |jn                  j                        j                  |             ~t        |jn                  t~              r|jn                  j                  }!|!t        j                  k(  rt        }"n:|!t        j                  k(  rt        }"n |!t        j                  k(  rt        }"nt        }"| j                   |"t        |            j                  |             3t        |jn                  t|              r4| j                  t        t        |            j                  |             t        |jn                  tr              r4| j                  t        t        |            j                  |             t        |jn                  t              r=| j                  t        t        t        |                  j                  |             &t        |jn                  tv              r4| j                  t        t        |            j                  |             tt        |jn                  tx              r4| j                  t        t        |            j                  |             t        |jn                  tp        tz        tV        f      rM| j                  t        t        |            j                  |jn                        j                  |             4t        |jn                  t              rM| j                  t        t        |            j                  |jn                        j                  |             t        |jn                  t              r4| j                  t        t        |            j                  |             t        |jn                  t              rD| j                  t        |      j                  |jn                        j                  |             Gt        |jn                  tt              rD| j                  t        |      j                  |jn                        j                  |             | j                  t        |              |r| j4                  j7                         nd}
| j                  rut        | | j                  j                  | j                  j                  t        |||%      | j                  &      | j                  '      d	(      j                  | d	(      n*t        | t        |||%      d	(      j                  | d	(      }#t1        |#d)       |r|
jN                  |#_(        t        rt        |t        j                        rt        | j$                  t&              rt        |#|       }	|rt9        |
j:                  j<                  |
      }t?        |j@                  jB                  jD                  jF                  |       tI        |	jJ                  |jJ                  jL                  jD                         |
jN                  |	_(        |	S |rtt9        |
j:                  j<                  |
      }t        |t
              rC|D ]=  }t        |j@                  j                   j                  j                         |       ? nkt        |t              rC|D ]=  }t        |j@                  j                  j                  j                         |       ? nt        d*t        |       d+      |t        |t              r9|D ]3  }|jJ                  j                  j                  j                  |       5 n:t        |tV              r*tI        ||jJ                  jL                  jD                         |
jN                  |#_(        |#S c c}w c c}w c c}w c c}w c c}w # t        $ r,}t        j                  dtS        |              Y d}~Id}~ww xY w),a  Creates a new DataFrame containing the specified values from the local data.

        If creating a new DataFrame from a pandas Dataframe or a PyArrow Table, we will store
        the data in a temporary table and return a DataFrame pointing to that temporary
        table for you to then do further transformations on. This temporary table will be
        dropped at the end of your session. If you would like to save the pandas DataFrame or PyArrow Table,
        use the :meth:`write_pandas` or :meth:`write_arrow` method instead.
        Note: When ``data`` is a pandas DataFrame or pyarrow Table, schema inference may be affected by chunk size.
        You can control it by passing the ``chunk_size`` keyword argument. For details, see :meth:`write_pandas`
        or :meth:`write_arrow`, which are used internally by this function.

        Args:
            data: The local data for building a :class:`DataFrame`. ``data`` can only
                be a :class:`list`, :class:`tuple` or pandas DataFrame. Every element in
                ``data`` will constitute a row in the DataFrame.
            schema: A :class:`~snowflake.snowpark.types.StructType` containing names and
                data types of columns, or a list of column names, or ``None``.

                - When passing a **string**, it can be either an *explicit* struct
                  (e.g. ``"struct<a: int, b: string>"``) or an *implicit* struct
                  (e.g. ``"a: int, b: string"``). Internally, the string is parsed and
                  converted into a :class:`StructType` using Snowpark's type parsing.
                - When ``schema`` is a list of column names or ``None``, the schema of the
                  DataFrame will be inferred from the data across all rows.

                To improve performance, provide a schema. This avoids the need to infer data types
                with large data sets.
            **kwargs: Additional keyword arguments passed to :meth:`write_pandas` or :meth:`write_arrow`
                when ``data`` is a pandas DataFrame or pyarrow Table, respectively. These can include
                options such as chunk_size or compression.

        Examples::

            >>> # create a dataframe with a schema
            >>> from snowflake.snowpark.types import IntegerType, StringType, StructField
            >>> schema = StructType([StructField("a", IntegerType()), StructField("b", StringType())])
            >>> session.create_dataframe([[1, "snow"], [3, "flake"]], schema).collect()
            [Row(A=1, B='snow'), Row(A=3, B='flake')]

            >>> # create a dataframe by inferring a schema from the data
            >>> from snowflake.snowpark import Row
            >>> # infer schema
            >>> session.create_dataframe([1, 2, 3, 4], schema=["a"]).collect()
            [Row(A=1), Row(A=2), Row(A=3), Row(A=4)]
            >>> session.create_dataframe([[1, 2, 3, 4]], schema=["a", "b", "c", "d"]).collect()
            [Row(A=1, B=2, C=3, D=4)]
            >>> session.create_dataframe([[1, 2], [3, 4]], schema=["a", "b"]).collect()
            [Row(A=1, B=2), Row(A=3, B=4)]
            >>> session.create_dataframe([Row(a=1, b=2, c=3, d=4)]).collect()
            [Row(A=1, B=2, C=3, D=4)]
            >>> session.create_dataframe([{"a": 1}, {"b": 2}]).collect()
            [Row(A=1, B=None), Row(A=None, B=2)]

            >>> # create a dataframe from a pandas Dataframe
            >>> import pandas as pd
            >>> session.create_dataframe(pd.DataFrame([(1, 2, 3, 4)], columns=["a", "b", "c", "d"])).collect()
            [Row(a=1, b=2, c=3, d=4)]

            >>> # create a dataframe using an implicit struct schema string
            >>> session.create_dataframe([[10, 20], [30, 40]], schema="x: int, y: int").collect()
            [Row(X=10, Y=20), Row(X=30, Y=40)]

        Note:
            When `data` is a pandas DataFrame, `snowflake.connector.pandas_tools.write_pandas` is called, which
            requires permission to (1) CREATE STAGE (2) CREATE TABLE and (3) CREATE FILE FORMAT under the current
            database and schema.
        Nzdata cannot be None.z9create_dataframe() function does not accept a Row object.zUcreate_dataframe() function only accepts data as a list, tuple or a pandas DataFrame.zbdata is a pandas DataFrame, parameter schema is ignored. To silence this warning pass schema=None.r)  r  r  F)quotedrQ  Tr  )r  rQ  r  r  r  r  r  zSession.create_dataframe[arrow]z Session.create_dataframe[pandas]zInvalid schema string: zF. You should provide a valid schema string representing a struct type.z#Cannot infer schema from empty datac              3   6   K   | ]  }t        |        y wr   )rH   )r  r  namess     r   r  z+Session.create_dataframe.<locals>.<genexpr>  s     :cc5):s   r   r  r  r  r   c                 H   d }| d g} n~t        | t        t        f      rD| sd g} nbt        | dd       rUt        | t              r| j                         n| j                         }n$t        | t              r| j                         }n| g} |rK|j                         D ci c]  \  }}t        |      | }}}|D cg c]  }|j                  |       c}S t        |       t        |      k7  r#t        t        |       dt        |        d      t        |       S c c}}w c c}w )N_fieldsz# fields are required by schema but z values are provided. This might be because data consists of rows with different lengths, or mixed rows with column names or without column names)r  r  r7  r  r   as_dict_asdictre  rp  r  ri   r  r   r"  )r  r  row_dictr2  r3  r  s         r   convert_row_to_listz5Session.create_dataframe.<locals>.convert_row_to_list  s    H{fC%/&CS)T20:30Ds{{}#++-HC&88:e9A9IJAJqM1,JJ7<=tT*== s8s5z)$u:, '"3xj )DE  Cy  K=s   D9DzCREATE SCOPED TEMP TABLE z (r*  zSELECT * FROM z{Cannot create temp table for specified non-nullable schema, fall back to using schema string from select query. Exception: )r  zCannot cast (z) to r  )schema_queryrR  rS  r  z Session.create_dataframe[values]zUnsupported type z in create_dataframe.)r"  r  r   	TypeErrorr7  r  r   r   r|   r   r   r  r  UserWarningrY   rj   rS   TABLEr  r   r   _get_current_parameterr!   r~  rD   r   r  rF  r4   rG  create_dataframer3   r  r  r3  r  r2   rQ  dataframe_schema__structrZ  r[  r   rK   r   r   r   rJ   r   fieldsr   r
   r   r  ri   zipdatatyper   r   r   r   r   r   r   r   r   r   r   r   r   rq  r#   nullabler  allis_primitiver   attribute_to_schema_stringr  r  r   r  r  decimalDecimalr   datetimetimedater   r   r#  r7  rR   re  context%_should_use_structured_type_semanticsr  r  r   r   	precisionscaleas_tzr   NTZr   LTZr   TZr   r   r   r   r   r   r   r   castr   r  r  r\  create_select_snowflake_planr)   r  r   r0   dataframe_data__tuplevsr   dataframe_data__listdataframe_schema__list)%r	  r  rQ  r  r  origin_datatemp_table_namesf_database	sf_schemar  rJ  rK  r  r  
new_schemar  fr  quoted_namesr  rowsattrs
data_typesfieldquoted_namesf_typeschema_stringr  	convertedconverted_rowr  	data_typeproject_columnsr  to_timestamp_funcr  r  s%                                       @r   r  zSession.create_dataframe  s5   V <344 dC WXX$u.  "4&*:*:GMM)JK g  4&"2"2GMM!BC"MMt 
4&2B2BGMM1R S++N,@,@AO $**&:;FtL #jj??u @  !JJ==hu=U	dGMM2,D,,' "-(*.*.#.)-)M)M"' !E (/PQ-D--' "-(*.*.#.)-)M)M"' !E (/QR??//1D+DII,F,FMC$7799DDo 1cjj&I&I&K&K %)HHEM fc"/7Ffj1 -fX 6[ \  "fj)J $ !FGG&(+V:T:J z  !Q&P 	!x}c)*	!379	!	!@ %/%6%67QVV7E5:;T
4(;;BFG3#C6GG z"%j&7&7"F 	.E; NN! +%$" %#"-  & ^^) , LL;HIenn-1	.4 
 tzz+?@fmmLU50LMFMMR5446RS"=n>R>R"S . I I% P	OO3O3DB}oUVW &4D4]4]^m4n3o#pL 	 9	2CM$'Z$8 6 y=!((.w7J{= "((/x'8'89j}? "((U4x}}5*x; "((U4x}}5*x; "((U4	+@A!((/	+>?!((/	;7!((/eU';<yB "((E?S)TUt,42 "((E?S)TUuc*"9j9EEG!((

5==?8LM  	;7!((E?S)TU	=9!((/	<8!((/	84!((/	:6!((E?S)TU#&tE{m1UG5Y@PPQR i6n S-01s9	2x z00%8 -	5KE4%..+6&&t00,, c$i ENNM:^^&&*...(8%,000(8%,///(7%(4%&&'8'F'J'J4'PQENNH5&&wvd|'<'@'@'FGENNH5&&wvd|'<'@'@'FGENNK8&&z*VD\2J'K'O'OPT'UVENNM:&&|F4L'A'E'Ed'KLENNL9&&{6$<'@'D'DT'JKENNY,LM&&vd|,11%..AEEdK ENNJ7&&vd|,11%..AEEdK ENNH5&&wvd|'<'@'@'FGENN,AB&&vd|'8'8'H'L'LT'RSENN,?@&&vd|'8'8'H'L'LT'RS&&vd|4[-	5` *3t##% ** 66..EE'y|T!% F  "^^ 7   
 f_f6y|L f_f6# 	& 	B BCBJ ;(8(894::';< 0OTJE '		(B(BDI !HH3355@@/ -LL#**"E"E"G"G !%L #DII$>$>EC+u-& C.6699==? K.& C.5588<<>  '[(9'::OP  !fd+ & J

99<<CCDIJ
30

 C C E E BJ	m 8;GH MR ( MM@@CAxI sB   9AF.AF3+AF8<AF=+!AG,AG G	AG<G!AG7G7AG<r  endstepc           	         |t        d||      nt        |||      }d}|re| j                  j                         }t        |j                  j
                  |      }||_        |r||j                  _        ||j                  _        | j                  rZt        | | j                  j                  | j                  j                  || j                        | j                        ||      }nt        | |||      }t        |d       |S )a  
        Creates a new DataFrame from a range of numbers. The resulting DataFrame has
        single column named ``ID``, containing elements in a range from ``start`` to
        ``end`` (exclusive) with the step value ``step``.

        Args:
            start: The start of the range. If ``end`` is not specified,
                ``start`` will be used as the value of ``end``.
            end: The end of the range.
            step: The step of the range.

        Examples::

            >>> session.range(10).collect()
            [Row(ID=0), Row(ID=1), Row(ID=2), Row(ID=3), Row(ID=4), Row(ID=5), Row(ID=6), Row(ID=7), Row(ID=8), Row(ID=9)]
            >>> session.range(1, 10).collect()
            [Row(ID=1), Row(ID=2), Row(ID=3), Row(ID=4), Row(ID=5), Row(ID=6), Row(ID=7), Row(ID=8), Row(ID=9)]
            >>> session.range(1, 10, 2).collect()
            [Row(ID=1), Row(ID=3), Row(ID=5), Row(ID=7), Row(ID=9)]
        Nr   rR  rS  rU  zSession.range)r(   r  rF  r4   rG  ranger  r  r  r	  r  r|   r  r\  r  rD   )	r	  r  r  r	  r  
range_planrJ  rK  r  s	            r   r  zSession.range  s    8 /2kU1eT*uUCQU?V
 ??'')D#DIIOOT:CCI #!CHHN&&66..EE"T^^ F  "^^	 7  #
B 4tyQBB0	r   query_idc                     t               r'| j                  j                  dd      st        d      t	        | j                  t
              r!| j                  j                  dt               t        |d|       S )zp
        Creates an :class:`AsyncJob` from a query ID.

        See also:
            :class:`AsyncJob`
        )ENABLE_ASYNC_QUERY_IN_PYTHON_STORED_PROCSFz4Async query is not supported in stored procedure yetzSession.create_async_jobr  N)rc   r  r`  r  r  r   r  rw   )r	  r  s     r   create_async_jobzSession.create_async_job  sr     #$JJAA;U &F  djj"67JJ..&@/ /  $--r   c                 8    | j                   j                  d      S )z|
        Returns the name of the current account for the Python connector session attached
        to this session.
        accountr  r  r)  s    r   r  zSession.get_current_account  s    
 zz00;;r   c                 8    | j                   j                  d      S )zo
        Returns the name of the user in the connection to Snowflake attached
        to this session.
        userr  r)  s    r   get_current_userzSession.get_current_user  s    
 zz0088r   c                 8    | j                   j                  d      S )z
        Returns the name of the current database for the Python connector session attached
        to this session. See the example in :meth:`table`.
        r  r  r)  s    r   r  zSession.get_current_database  s    
 zz00<<r   c                 8    | j                   j                  d      S )z
        Returns the name of the current schema for the Python connector session attached
        to this session. See the example in :meth:`table`.
        rQ  r  r)  s    r   r  zSession.get_current_schema  s    
 zz00::r   c                 *    | j                  d      dd S )zGReturns the fully qualified name of the current schema for the session.r  N)r  r)  s    r   "get_fully_qualified_current_schemaz*Session.get_fully_qualified_current_schema  s    
 88<SbAAr   c                     | j                   5  | j                         }| j                         }ddd       rr
| d| d| S t               s|sdnd}t	        j
                  |||      |S # 1 sw Y   @xY w)z~
        Returns the fully qualified object name if current database/schema exists, otherwise returns the object name
        Nr  DATABASESCHEMA)r  r  r  rc   r5   'SERVER_CANNOT_FIND_CURRENT_DB_OR_SCHEMA)r	  r  r  rQ  missing_items        r   r  z,Session.get_fully_qualified_name_if_possible$  s     ZZ 	/002H,,.F	/ Zq$00 &'-5:8L1YYlL  	/ 	/s   !A--A6c                 8    | j                   j                  d      S )zS
        Returns the name of the warehouse in use for the current session.
        	warehouser  r)  s    r   r  zSession.get_current_warehouse6  s     zz00==r   c                 8    | j                   j                  d      S )zV
        Returns the name of the primary role in use for the current session.
        roler  r)  s    r   r  zSession.get_current_role<  s     zz0088r   c                 (    | j                  |d       y)zwSpecifies the active/current database for the session.

        Args:
            database: The database name.
        r  N_use_object)r	  r  s     r   use_databasezSession.use_databaseB  s     	:.r   c                 (    | j                  |d       y)zqSpecifies the active/current schema for the session.

        Args:
            schema: The schema name.
        rQ  Nr&  )r	  rQ  s     r   
use_schemazSession.use_schemaJ  s     	*r   r"  c                 (    | j                  |d       y)zzSpecifies the active/current warehouse for the session.

        Args:
            warehouse: the warehouse name.
        r"  Nr&  )r	  r"  s     r   use_warehousezSession.use_warehouseR  s     	K0r   r$  c                 (    | j                  |d       y)zsSpecifies the active/current primary role for the session.

        Args:
            role: the role name.
        r$  Nr&  )r	  r$  s     r   use_rolezSession.use_roleZ  s     	v&r   roles)r  nonec                 P    | j                  d|dn|j                                 y)a  
        Specifies the active/current secondary roles for the session.
        The currently-active secondary roles set the context that determines whether
        the current user has the necessary privileges to perform SQL actions.

        Args:
            roles: "all" or "none". ``None`` means "none".

        References: `Snowflake command USE SECONDARY ROLES <https://docs.snowflake.com/en/sql-reference/sql/use-secondary-roles.html>`_.
        zuse secondary roles Nr0  )r  r1  )r	  r/  s     r   use_secondary_roleszSession.use_secondary_rolesb  s'     	"U]6"NO	
r   object_nameobject_typec                    |rt        |       d| d| }t        | j                  t              rd}t	        j
                  ||      x}rb|j                  d      }|j                  d      }| j                  j                         }|5  t        | j                  d| |       d d d        y | j                  |       y | j                  |       y t        d| d      # 1 sw Y   y xY w)	Nzuse  z5^\s*use\s+(warehouse|database|schema|role)\s+(.+)\s*$r   r)  _active_'z' must not be empty or None.)rn   r  r  r   r  matchgroupget_lockr  r  r"  )r	  r3  r4  rr  use_ddl_patternr9  mock_conn_locks          r   r'  zSession._use_objectq  s     -;-q6E$**&:;L   HH_e<<5< #(++a.K"'++a.K%)ZZ%8%8%:N' S

h{m,DkRS S OOE*&q-IJKKS Ss   CC(c                 B    | j                   j                  j                  S )as  Controls whether or not the Snowpark client sends usage telemetry to Snowflake.
        This typically includes information like the API calls invoked, libraries used in conjunction with Snowpark,
        and information that will let us better diagnose and fix client side errors.

        The default value is ``True``.

        Example::

            >>> session.telemetry_enabled
            True
            >>> session.telemetry_enabled = False
            >>> session.telemetry_enabled
            False
            >>> session.telemetry_enabled = True
            >>> session.telemetry_enabled
            True
        )r  r  _enabledr)  s    r   telemetry_enabledzSession.telemetry_enabled  s    & zz++444r   c                    |rdd| j                   j                  _        t               r>| j                  s1t
        j                  d       d| j                   j                  _        y y y d| j                   j                  _        y )NTzkClient side parameter ENABLE_SNOWPARK_FIRST_PARTY_TELEMETRY is set to False, telemetry could not be enabledF)r  r  r?  rc   r  r  r  r  s     r   r@  zSession.telemetry_enabled  sj     48DJJ((1%'0P0P B 9>

,,5	 1Q' 5:DJJ((1r   c                     | j                   S )z
        Returns a :class:`FileOperation` object that you can use to perform file operations on stages.
        See details of how to use this object in :class:`FileOperation`.
        )rv  r)  s    r   r  zSession.file  s     zzr   c                     | j                   S )z
        Returns a :class:`Lineage` object that you can use to explore lineage of snowflake entities.
        See details of how to use this object in :class:`Lineage`.
        )rw  r)  s    r   lineagezSession.lineage  s     }}r   c                     | j                   S )z
        Returns a :class:`udf.UDFRegistration` object that you can use to register UDFs.
        See details of how to use this object in :class:`udf.UDFRegistration`.
        )rl  r)  s    r   r?  zSession.udf  s     %%%r   c                     | j                   S )z
        Returns a :class:`udtf.UDTFRegistration` object that you can use to register UDTFs.
        See details of how to use this object in :class:`udtf.UDTFRegistration`.
        )rm  r)  s    r   udtfzSession.udtf  s     &&&r   c                     | j                   S )z
        Returns a :class:`udaf.UDAFRegistration` object that you can use to register UDAFs.
        See details of how to use this object in :class:`udaf.UDAFRegistration`.
        )rn  r)  s    r   udafzSession.udaf  s     &&&r   c                     | j                   S )z
        Returns a :class:`stored_procedure.StoredProcedureRegistration` object that you can use to register stored procedures.
        See details of how to use this object in :class:`stored_procedure.StoredProcedureRegistration`.
        )ro  r)  s    r   rA  zSession.sproc  s     $$$r   c                     | j                   S )z
        Returns a :class:`stored_procedure_profiler.StoredProcedureProfiler` object that you can use to profile stored procedures.
        See details of how to use this object in :class:`stored_procedure_profiler.StoredProcedureProfiler`.
        )r  r)  s    r   stored_procedure_profilerz!Session.stored_procedure_profiler  s        r   z1.43.0c                     | j                   S )a
  
        Returns a :class:`event_table_telemetry.EventTableTelemetry` object that you can use to send telemetry to snowflake event table.
        See details of how to use this object in :class:`event_table_telemetry.EventTableTelemetry`.

        `Session.client_telemetry` object enable user to send telemetry to designated event table
        when necessary dependencies are installed. Only traces and logs between
        `client_telemetry.enable_event_table_telemetry_collection` and `client_telemetry.disable_event_table_telemetry_collection`
        will be sent to event table. You can call `client_telemetry.enable_event_table_telemetry_collection` again to re-enable external
        telemetry after it is turned off.

        Note:
            This function requires the `opentelemetry` extra from Snowpark.
            Install it via pip:
                .. code-block:: bash

                pip install "snowflake-snowpark-python[opentelemetry]"

        Examples 1
            .. code-block:: python

            ext = session.client_telemetry
            ext.enable_event_table_telemetry_collection("snowflake.telemetry.events", logging.INFO, True)
            tracer = trace.get_tracer("my_tracer")
            with tracer.start_as_current_span("code_store") as span:
                span.set_attribute("code.lineno", "21")
                span.set_attribute("code.content", "session.sql(...)")
                logging.info("Trace being sent to event table")
            ext.disable_event_table_telemetry_collection()

        Examples 2
            .. code-block:: python

            ext = session.client_telemetry
            logging.info("log before enable external telemetry") # this log is not sent to event table
            ext.enable_event_table_telemetry_collection("snowflake.telemetry.events", logging.INFO, True)
            tracer = trace.get_tracer("my_tracer")
            with tracer.start_as_current_span("code_store") as span:
                 span.set_attribute("code.lineno", "21")
                span.set_attribute("code.content", "session.sql(...)")
                logging.info("Trace being sent to event table")
            ext.disable_event_table_telemetry_collection()
            logging.info("out of scope log")  # this log is not sent to event table
            ext.enable_event_table_telemetry_collection("snowflake.telemetry.events", logging.DEBUG, True)
            logging.debug("debug log") # this log is sent to event table because external telemetry is re-enabled
            ext.disable_event_table_telemetry_collection()

        )r  r)  s    r   client_telemetryzSession.client_telemetry  s    d %%%r   c                     | j                   S )z
        Returns a :class:`udf_profiler.UDFProfiler` object that you can use to profile UDFs.
        See details of how to use this object in :class:`udf_profiler.UDFProfiler`.
        )r  r)  s    r   udf_profilerzSession.udf_profiler  s     !!!r   c                     | j                   S )z
        Returns a :class:`dataframe_profiler.DataframeProfiler` object that you can use to profile dataframe operations.
        See details of how to use this object in :class:`dataframe_profiler.DataframeProfiler`.
        )r  r)  s    r   dataframe_profilerzSession.dataframe_profiler!  s     '''r   r~  
sproc_namere  c                   |j                         j                         j                  d      ryd}	 g }|D ]  }t        |t              rf|j
                  }t        |t              r%|j                  t        |j                               T|j                  t        |j                               y|j                  t        t        |                    |j                          ddj                  |       d}| j                  d| |      }|d	   d	   }	|	j                         j                  d
      S # t        $ r%}
t        j!                  d| d|
        Y d }
~
yd }
~
ww xY w)NzSYSTEM$Fr  r  z, r*  zdescribe procedure rS  r   r  zCould not describe procedure z due to exception )rG  upperrH  r  ry   rm  r-   rq  rG   tor  rI   r  r  r  r  r  )r	  rT  r~  re  func_signature	arg_typesargrG  
sproc_descreturn_typeexcs              r   _infer_is_return_tablezSession._infer_is_return_table)  s]    ##%00; 	I Mc6*??D!$-!(()>tww)GH!(()>t}})MN$$%::c?%KLM !+ 0 0 231TYYy5I4J!LN
 %n%56!1 ) J %Q-*K$$&11':: 	LL//??QRUQVW  		s   DD6 6	E$?EE$r^  blockr~  return_dataframer  r`  ra  c          	      6     | j                   |g||||||dS )a	  Calls a stored procedure by name.

        Args:
            sproc_name: The name of stored procedure in Snowflake.
            args: Arguments should be basic Python types.
            statement_params: Dictionary of statement level parameters to be set while executing this action.
            block: Whether to block until the result is available. When it is ``False``, this function
                executes the stored procedure asynchronously and returns an :class:`AsyncJob`.
            log_on_exception: Log warnings if they arise when trying to determine if the stored procedure
                as a table return type.
            return_dataframe: When set to True, the return value of this function is a DataFrame object.
                This is useful when the given stored procedure's return type is a table.

        Returns:
            When block=True: The stored procedure result (scalar value or DataFrame)
            When block=False: An AsyncJob object for retrieving results later

        Example::

            >>> import snowflake.snowpark
            >>> from snowflake.snowpark.functions import sproc
            >>>
            >>> session.add_packages('snowflake-snowpark-python')
            >>>
            >>> @sproc(name="my_copy_sp", replace=True)
            ... def my_copy(session: snowflake.snowpark.Session, from_table: str, to_table: str, count: int) -> str:
            ...     session.table(from_table).limit(count).write.save_as_table(to_table)
            ...     return "SUCCESS"
            >>> _ = session.sql("create or replace table test_from(test_str varchar) as select randstr(20, random()) from table(generator(rowCount => 100))").collect()
            >>> _ = session.sql("drop table if exists test_to").collect()
            >>> session.call("my_copy_sp", "test_from", "test_to", 10)
            'SUCCESS'
            >>> session.table("test_to").count()
            10

        Example::

            >>> from snowflake.snowpark.dataframe import DataFrame
            >>>
            >>> @sproc(name="my_table_sp", replace=True)
            ... def my_table(session: snowflake.snowpark.Session, x: int, y: int, col1: str, col2: str) -> DataFrame:
            ...     return session.sql(f"select {x} as {col1}, {y} as {col2}")
            >>> session.call("my_table_sp", 1, 2, "a", "b").show()
            -------------
            |"A"  |"B"  |
            -------------
            |1    |2    |
            -------------
            <BLANKLINE>
        )r^  r`  r~  is_return_tabler  )_call)r	  rT  r^  r`  r~  ra  r  re  s           r   callzSession.callM  s9    z tzz

 .-,
 	
r   )r^  r~  ra  r  c          	      6     | j                   |g||d|||dS )a  Calls a stored procedure by name asynchronously and returns an AsyncJob.
        It is equivalent to ``call(block=False)``.

        Args:
            sproc_name: The name of stored procedure in Snowflake.
            args: Arguments should be basic Python types.
            statement_params: Dictionary of statement level parameters to be set while executing this action.
            log_on_exception: Log warnings if they arise when trying to determine if the stored procedure
                as a table return type.
            return_dataframe: When set to True, the return value of this function is a DataFrame object.
                This is useful when the given stored procedure's return type is a table.

        Returns:
            An AsyncJob object that can be used to retrieve results or check status.

        Example::

            >>> import snowflake.snowpark
            >>> from snowflake.snowpark.functions import sproc
            >>> import time
            >>>
            >>> session.add_packages('snowflake-snowpark-python')
            >>>
            >>> @sproc(name="simple_add_sp", replace=True)
            ... def simple_add(session: snowflake.snowpark.Session, a: int, b: int) -> int:
            ...     return a + b
            >>> async_job = session.call_nowait("simple_add_sp", 1, 2)
            >>> while not async_job.is_done():
            ...     time.sleep(1.0)
            >>> async_job.is_done()
            True
            >>> async_job.is_failed()
            False
            >>> async_job.status()
            'SUCCESS'
            >>> result = async_job.result()
            >>> print(result)
            3
        Fr_  )re  )r	  rT  r^  r~  ra  r  re  s          r   call_nowaitzSession.call_nowait  s9    b tyy

 .--
 	
r   )r^  rc  r~  r  r`  rc  c                T   d}|r!| j                   j                         }t        |j                  j                  |      }	||	j
                  j                  j                  j                  j                  _        |D ]&  }
t        |	j                  j                         |
       ( |A|D ]<  }|	j                  j                         }||_        t        |j                  ||          > ||	j
                  j                  j                  _        | j                   j#                  |       t%        | j&                  t(              r" | j&                  j*                  |g|| |ddS t-        |       t/        | |g| }| | j0                  |g|d|i}| j3                  ||||||      S )a	  Private implementation of session.call

        Args:
            sproc_name: The name of stored procedure in Snowflake.
            args: Arguments should be basic Python types.
            statement_params: Dictionary of statement level parameters to be set while executing this action.
            is_return_table: When set to a non-null value, it signifies whether the return type of sproc_name
                is a table return type. This skips infer check and returns a dataframe with appropriate sql call.
        NF)r   r^  r  r~  )rr  rc  r`  r^  ast_stmtr~  )r  rF  r4   rG  
apply_exprrW  stored_procedurer  	name_flatr0   pos_argsr   rq  r  r  r~  r  evalr  ro  r   re  rn   rL   r^  _execute_sproc_internal)r	  rT  r^  rc  r~  r  r`  re  rJ  rG  rZ  r2  entryrr  s                 r   rd  zSession._call  s   * ??'')D$TYY%9%94@D@JDGG$$))..88= E*4==+<+<+>DE+) NA OO//1E EH.uxx9I!9LMN ?ODGG$$55;OO  &d++-LM-4((-- !1  	Z(+D*DtD"9d99!4DO +++-- , 
 	
r   z0.7.0z'Use `Session.table_function()` instead.z#Use :meth:`table_function` instead.)rj  extra_warning_textextra_doc_stringinputouter	recursivemodec                    t        |       d}|r| j                  j                         }t        |j                  j
                  |      }t        |j                  |       |||j                  _	        ||_
        ||_        |j                         dk(  rd|j                  _        n6|j                         dk(  rd|j                  _        nd|j                  _        t#        | j$                  t&              r8| j$                  j(                  ry| j$                  j+                  dt,               t#        |t.              rt1        |      }t3        | t5        t7        |j8                  ||||            ||      }	t;        |	d       |	S )a  Creates a new :class:`DataFrame` by flattening compound values into multiple rows.

        The new :class:`DataFrame` will consist of the following columns:

            - SEQ
            - KEY
            - PATH
            - INDEX
            - VALUE
            - THIS

        References: `Snowflake SQL function FLATTEN <https://docs.snowflake.com/en/sql-reference/functions/flatten.html>`_.

        Example::

            df = session.flatten(parse_json(lit('{"a":[1,2]}')), "a", False, False, "BOTH")

        Args:
            input: The name of a column or a :class:`Column` instance that will be unseated into rows.
                The column data must be of Snowflake data type VARIANT, OBJECT, or ARRAY.
            path: The path to the element within a VARIANT data structure which needs to be flattened.
                The outermost element is to be flattened if path is empty or ``None``.
            outer: If ``False``, any input rows that cannot be expanded, either because they cannot be accessed in the ``path``
                or because they have zero fields or entries, are completely omitted from the output.
                Otherwise, exactly one row is generated for zero-row expansions
                (with NULL in the KEY, INDEX, and VALUE columns).
            recursive: If ``False``, only the element referenced by ``path`` is expanded.
                Otherwise, the expansion is performed for all sub-elements recursively.
            mode: Specifies which types should be flattened "OBJECT", "ARRAY", or "BOTH".

        Returns:
            A new :class:`DataFrame` that has the flattened new columns and new rows from the compound data.

        Example::

            >>> from snowflake.snowpark.functions import lit, parse_json
            >>> session.flatten(parse_json(lit('{"a":[1,2]}')), path="a", outer=False, recursive=False, mode="BOTH").show()
            -------------------------------------------------------
            |"SEQ"  |"KEY"  |"PATH"  |"INDEX"  |"VALUE"  |"THIS"  |
            -------------------------------------------------------
            |1      |NULL   |a[0]    |0        |1        |[       |
            |       |       |        |         |         |  1,    |
            |       |       |        |         |         |  2     |
            |       |       |        |         |         |]       |
            |1      |NULL   |a[1]    |1        |2        |[       |
            |       |       |        |         |         |  1,    |
            |       |       |        |         |         |  2     |
            |       |       |        |         |         |]       |
            -------------------------------------------------------
            <BLANKLINE>

        See Also:
            - :meth:`DataFrame.flatten`, which creates a new :class:`DataFrame` by exploding a VARIANT column of an existing :class:`DataFrame`.
            - :meth:`Session.table_function`, which can be used for any Snowflake table functions, including ``flatten``.
        NOBJECTTARRAYzSession.flattenr  rU  )rU   r  rF  r4   rG  flattenr0   rs  r:  r  rt  ru  rV  rv  flatten_mode_objectflatten_mode_arrayflatten_mode_bothr  r  r   rX  r  r  r   r   r|   r,   r*   rm  rD   )
r	  rs  r:  rt  ru  rv  r  rJ  rG  r  s
             r   rz  zSession.flatten  sB   N 	4  ??'')D$TYY%6%6=D&tzz59"&		DJ&DNzz|x'04		-(/3		,.2		+djj"67zz99

22*; 3 3  eS!JE! 1 14	4P 
 	B 12	r   include_describeinclude_thread_idinclude_errorinclude_dataframe_profilingc                 Z    t        | ||||      }| j                  j                  |       |S )a  Create an instance of :class:`QueryHistory` as a context manager to record queries that are pushed down to the Snowflake database.

        Args:
            include_describe: Include query notifications for describe queries
            include_thread_id: Include thread id where queries are called
            include_error: record queries that have error during execution

        >>> with session.query_history(True) as query_history:
        ...     df = session.create_dataframe([[1, 2], [3, 4]], schema=["a", "b"])
        ...     df = df.filter(df.a == 1)
        ...     res = df.collect()
        >>> assert len(query_history.queries) == 2
        >>> assert query_history.queries[0].is_describe
        >>> assert not query_history.queries[1].is_describe
        )r   r  add_query_listener)r	  r~  r  r  r  query_listeners         r   query_historyzSession.query_history|  s7    , &'
 	

%%n5r   c                 T    t        | |      }| j                  j                  |       |S )a  
        Creates an instance of :class:`AstListener` as a context manager to capture ast batches flushed.
        Returns: AstListener instance holding base64 encoded batches.

        Args:
            include_error: Include ast objects that may have failed previous execution.
        )r   r  r  )r	  r  als      r   ast_listenerzSession.ast_listener  s'     }-

%%b)	r   raw_table_namec                 r   t        |      }t        | j                  t              r%| j                  j                  j                  |      S t        |      dk(  r"| j                  dt        |d          d      }nt        |      dk(  r'| j                  dt        |d          d|d          }nut        |      dk(  rC|d   dk(  r	d	|d    d
nd	|d    d|d    }| j                  dt        |d          d|       }n$t        j                  dj                  |            |duxr t        |      dkD  S )r6  r   zshow tables like 'r   r8  r)  z' in schema r   r  zschema z.PUBLICr  z' in N)r7  r  r  r   entity_registryis_existing_tabler   r  rk   r5   GENERAL_INVALID_OBJECT_NAMEr  )r	  r  qualified_table_nametables	conditions        r   r  zSession._table_exists  s     $N3djj"67::--??@TUU'(A-()\]qrs]t)u(vvwx )*a/ ()\]qrs]t)u(v  wC  DX  YZ  D[  C\  ] )*a/ ,A."4 2156g>"#7#:";1=QRS=T<UV 
 ()\]qrs]t)u(vv{  }F  |G  H
 6QQHH^,  %9#f+/9r   c                     	 | j                  d|       d   d   S # t        $ r t        j                  d|       Y y w xY w)Nzexplain using text r   zquery `%s` cannot be explained)r  r   r  rp   )r	  rr  s     r   _explain_queryzSession._explain_query  sI    	??%8#@A!DQGG 	OO<eD	s    >>r\  r   stringbooleanrW  floatr   c                    | j                   5  |}|| j                  vr/t        t                     t               t	               t               t               d}t        |   }t               rt        t        j                        }d| }| j                  |d      j                  d       | j                  j                  t         |ddd       t"         | dt$        j&                  j)                  t                }nt         }| j*                  j-                  ||||   t               t               gdd	gddd
      }|| j                  |<   | j                  |   cddd       S # 1 sw Y   yxY w)a3  
        Get or register an XPath UDF for the specified return type.

        This function manages UDF registration for XPath evaluation. It uses session-level
        caching to avoid re-registering the same UDF multiple times. The cache is stored
        in the session object for thread safety.
        r  z create temp stage if not exists Fr  T)rk  rl  rn  rd  r  zlxml<6)r\  input_typesr  rX  r  r  N)r  r  r   r   r   r   r   rQ   rc   rj   rS   r  r  collectr  rt  rP   rN   rI  r:  rr  r?  register_from_file)	r	  r\  	cache_keyreturn_type_maphandler_name
temp_stagesql_create_temp_stagepython_file_path	xpath_udfs	            r   _get_or_register_xpath_udfz"Session._get_or_register_xpath_udf  su    '' 5	4#I 5 55 'z|4(l*}&=&[#  1= *+ "=^=Q=Q!RJ::,G * HH2eHDLL"' M  JJ**0"&+"&59 +  +7
|1RWWEUEUVnEoDp'q$'?$ !HH77$  / <!+z| <98D #59 8 		 4=%%i0((3k5	4 5	4 5	4s   EE&&E/c                    |sV| j                   j                  ||      }t        |d   || |rt        j                  |      S t        j
                  |      S |rG| j                   j                  ||      }| j                  t        |      |      }	t        |	d       |	S | j                  ||      }	t        |	d       |	j                  |d      d	   d	   S )
z>Unified internal executor for sync/async, table/scalar SPROCs.)r  queryIdrS  r]  )rE  zSession.callF)r^  r  r   )r  'execute_async_and_notify_query_listenerrw   rx   ROWCOUNTexecute_and_get_sfqidr  r    rD   r  )
r	  rr  rc  r`  r^  ri  r~  results_cursorqidr  s
             r   ro  zSession._execute_sproc_internal  s     !ZZOO)9 P N y)(7 $$!1  >N=S=S!1  **22(8 3 C /4IBN3I %84BN3::/?5:QRSTUVWWr   r  c                     |j                  t              r|n	t         | }d}|rA| j                  j                         }t	        |j
                  j                  |      }||_        | j                  d| d||      S )a	  
        Returns a DataFrame representing the results of a directory table query on the specified stage.

        A directory table query retrieves file-level metadata about the data files in a Snowflake stage.
        This includes information like relative path, file size, last modified timestamp, file URL, and checksums.

        Note:
            The stage must have a directory table enabled for this method to work. The query is
            executed lazily, which means the SQL is not executed until methods like
            :func:`DataFrame.collect` or :func:`DataFrame.to_pandas` evaluate the DataFrame.

        Args:
            stage_name: The name of the stage to query. The stage name should not include the '@' prefix
                as it will be added automatically.

        Returns:
            A DataFrame containing metadata about files in the stage with the following columns:

            - ``RELATIVE_PATH``: Path to the files to access using the file URL
            - ``SIZE``: Size of the file in bytes
            - ``LAST_MODIFIED``: Timestamp when the file was last updated in the stage
            - ``MD5``: MD5 checksum for the file
            - ``ETAG``: ETag header for the file
            - ``FILE_URL``: Snowflake file URL to access the file

        Examples::
            >>> # Get all file metadata from a stage named 'test_stage'
            >>> _ = session.sql("CREATE OR REPLACE TEMP STAGE test_stage DIRECTORY = (ENABLE = TRUE)").collect()
            >>> _ = session.file.put("tests/resources/testCSV.csv", "@test_stage", auto_compress=False)
            >>> _ = session.file.put("tests/resources/testJson.json", "@test_stage", auto_compress=False)
            >>> _ = session.sql("ALTER STAGE test_stage REFRESH").collect()

            >>> # List all files in the stage
            >>> df = session.directory('test_stage')
            >>> df.count()
            2

            >>> # Get file URLs for CSV files only
            >>> csv_files = session.directory('test_stage').filter(
            ...     col('RELATIVE_PATH').like('%.csv%')
            ... ).select('RELATIVE_PATH')
            >>> csv_files.show()
            -------------------
            |"RELATIVE_PATH"  |
            -------------------
            |testCSV.csv      |
            -------------------
            <BLANKLINE>

        For details, see the Snowflake documentation on
        `Snowflake Directory Tables Documentation <https://docs.snowflake.com/en/user-guide/data-load-dirtables-query>`_
        NzSELECT * FROM DIRECTORY(r*  rU  )	rH  rN   r  rF  r4   rG  	directoryr  r  )r	  r  r  rJ  rK  s        r   r  zSession.directoryC  s    n $$\2  >*. 	
 ??'')D#DII$7$7>C'CN xx&zl!4  
 	
r   c                    d}|rM| j                   j                         }t        |j                  j                  |      }|||j
                  _        d|rd|z   nd }| j                  |||      j                  d       y)a  
        Begins a new transaction in the current session.

        Args:
            name: Optional string that assigns a name to the transaction. A name helps
                identify a transaction, but is not required and does not need to be unique.

        Example::
            >>> # Begin an anonymous transaction
            >>> session.begin_transaction()

            >>> # Begin a named transaction
            >>> session.begin_transaction("my_transaction")
        NzBEGIN TRANSACTION zNAME r  rU  Fr  )	r  rF  r4   rG  begin_transactionr  r  r  r  )r	  r  r  rJ  rK  rr  s         r   r  zSession.begin_transaction  sz    & ??'')D#DII$?$?FC!%$gn2$FG$)<DDuDUr   c                     d}|r:| j                   j                         }t        |j                  j                  |       | j                  d||      j                  d       y)z
        Commits an open transaction in the current session.

        Example::
            >>> session.begin_transaction()
            >>> session.commit()
        NCOMMITrU  Fr  )r  rF  r4   rG  commitr  r  r	  r  rJ  s      r   r  zSession.commit  sS     ??'')Ddii..5TY?GGRWGXr   c                     d}|r:| j                   j                         }t        |j                  j                  |       | j                  d||      j                  d       y)z
        Rolls back an open transaction in the current session.

        Example::
            >>> session.begin_transaction()
            >>> session.rollback()
        NROLLBACKrU  Fr  )r  rF  r4   rG  rollbackr  r  r  s      r   r  zSession.rollback  sX     ??'')Ddii00$7tyAII 	J 	
r   r   rS  )Ni    F)NF)NTFNN)TN)r  )FT)NNT)r   r~   )r   r   )FTN)NNTFFFNr  )NT)Nr   T)NFFBOTHT)FFFFrT  )NNF)T)r  r  r  rV  r"  rO  rY  __annotations__r   rC   r   r   r   r   r   r
   r  r  r  r  r  r  r  r!  rz  rW  r  r  r   r  classmethodr  getActiveSessionrZ   r  r  r   r  r  setterr[   r  r  r  r	  r   r  r  r  r  r  r  r   r9  rE  rM  rP  staticmethodrB  r}  r   ro  r  r   r   r  r  r  r  r  r   r  r  r  r  r  r  r  r  r(  r.  r>  re  r=  rh   r   r  r   r   r  r   r   rF   r|   r`  ry   rg  r   protoBindr  ry  r{  r:  r  r#   r  r  r   r!   r  r   r   r   r  r  rw   r  r  r  r  r  r  r  r  r  r(  r*  r,  r.  r2  r'  r@  r   r  r   rD  r   r?  r   rG  r   rI  r   rA  r   rL  rv   r6   rN  r   rP  r   rR  r^  re  rg  rd  rX   rz  r   r  r   r  r  r  r  rY  ro  r  r  r  r  r   r   r   r   r   o  s   B. .`A, A,J -.G^.
 -1p-$&:MIJp- $sCx.)p- 
	p-d
$ 

S 

T 

( (
 +8 + + 8I#6   *(# $ &2 m   , , ,  T     H-1 1$ 1 . 1. .$ . . >$ > > 6$ 6 6 3t 3 3 =sCx = = 	3t 	3 	3 8D 8 8 ) ) ) %1T %1 %1N ""1D 1T 1 #1 $$3d 3t 3 %3 .44H-d t  . 5" &,,H-d t  . -" #))H-4 D  . ** -33BU38_ BQU B 4B* #))H-
4 
D 
 . *
 (..   / %++T d  ,  !''G,$ 4  - (3T#Y 3 &* %P@P@ c]P@ 	P@
 P@ 
P@d1# 1$ 1>'  &* %	?,?,c]?, ?, 	?,
 
sHSM8C=0	1?, ?,N O$ 6:O$O$ "%O$ !)eHSM8C=899:!
	O$ #4S>2O$ 
cO$f )-B 6:	B B #4S>2	B
 
SB&) )cSVh )" .2E
j(5j3I*JJKE
 &c]E
 
	E
T .2)O)O &c])O 
	)OZ .2'%c]' 
'" .2:M:M &c]:M 
	:Mx '">CI$"3xI$7;I$	I$ #I$V !uS*_-.!	c5dK/00	1! !R 6:05o#3c4&< ==>o# o# 	o#
 sCx.o# #4S>2o# *.o# 
k	o#b 
eCO,-
<@cN
	c
 
 <@!%$59-1yuS*_-.y !)c3h 8y 	y
 y #4S>2y &c]y 
cyv^9s)^9 ^9 38n	^9
 &*#s(^^9 
k	^9@X XG#%(G#69G#	k	G#Z "&59*Cy*  * 	*
 #4S>2* 
c49n	*: 8C=  . "S "T " "(s ( )%C )%C )%$ )%V&D &T &P  +0	b ?C#' $=ABF $bC#&'b $(b 	b #7>#:;b C=b b E#x'8'8"89:b !s,='=!>?b b 
b bH 
 	od3i#s();=NNOo &o 	o
 !-o 
o ob  vv v 	v
 v 
v vp  +/ $QQ #'Q ::	Q
 Q 
Q Qf % %
  C         ',!%59  $ 	
 #4S>2 
c CGEE(0#(?E	iE 6:6"4S>26 
6< (# #' $$:!)',"&"'DF+/#ee e
 3-e e SMe e e !%e e  e  e e @Ae  #4.!e" #e$ sCx.%e& 
'e  $e^ #' $"&"'.2DFJ
#
J
 J
 J
 3-J
 J
  J
  J
 J
 J
 l+J
 @AJ
  
!J
X  #' $$;!)"&"'"'DF+/',-O#
O O 3-O O SMO O O O  O   !O"  #O$ %O& @A'O( #4.)O* !%+O, -O. sCx./O0 
1O Ob  CG	WD%!3_DEW z8C=#=>?W 	W
 sCx.W 
W Wr  "66 c]6 	6
 6 
6 6p. . ..<Xc] <9(3- 9=hsm =;HSM ;BC B  $>x} >9(3- 9/S /T /+ + +1s 1t 1'S 'T '
'-2H)I 
d 
Ls L L L0 54 5 5( : : m      &_ & & '& ' ' '& ' ' %2 % % !+B ! ! X&0&"5 0& ' 0&d "k " " ($5 ( ( EJ""&)"=A"	"H 
 6:!&+/D
D
 D
 #4S>2	D

 D
 D
 #4.D
 D
 
sH}	D
 D
L 
 6:!&+/8
8
 8
 #4S>2	8

 8
 #4.8
 8
 
8
 8
| 6:*.!&<
<
 <
 #4S>2	<

 "$<
 <
 <
 <
 
sH}	<
| D>
  #gg smg 	g
 g g g 
g gV "'"'#,1   	
 &* 
@
$ 
; 
):HSM ):VC HSM @4"#OP@4	@4D 'O 6:!&"X"X "X 	"X
 #4S>2"X "X 
sH}	"XHE
C E
D E
I E
N <@VSMV59V	V V8 Y Y Y Y  
$ 
$ 
 
r   rU  )r   r   r   N)r   r   r   r   (=  r  r  r  r  r#  rI  r  r  r  r  r   collectionsr   	functoolsr   loggingr   	threadingr   typesr   typingr	   r
   r   r   r   r   r   r   r   r   r   r   r  importlib.metadatar  packaging.requirementsr   packaging.versionr   r  4snowflake.snowpark._internal.proto.generated.ast_pb2r  r  r  	generatedast_pb2snowflake.snowpark.contextr  snowflake.connectorr   r   snowflake.connector.optionsr   r   r    snowflake.connector.pandas_toolsr   snowflake.snowparkr   %snowflake.snowpark._internal.analyzerr   .snowflake.snowpark._internal.analyzer.analyzerr   r  r    r!   5snowflake.snowpark._internal.analyzer.datatype_mapperr"   0snowflake.snowpark._internal.analyzer.expressionr#   6snowflake.snowpark._internal.analyzer.select_statementr$   r%   r&   4snowflake.snowpark._internal.analyzer.snowflake_planr'   9snowflake.snowpark._internal.analyzer.snowflake_plan_noder(   r)   4snowflake.snowpark._internal.analyzer.table_functionr*   r+   r,   6snowflake.snowpark._internal.analyzer.unary_expressionr-   &snowflake.snowpark._internal.ast.batchr.   &snowflake.snowpark._internal.ast.utilsr/   r0   r1   r2   r3   r4   *snowflake.snowpark._internal.error_messager5   2snowflake.snowpark._internal.event_table_telemetryr6   ,snowflake.snowpark._internal.packaging_utilsr7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   rB   .snowflake.snowpark._internal.server_connectionrC   &snowflake.snowpark._internal.telemetryrD   4snowflake.snowpark._internal.temp_table_auto_cleanerrE   'snowflake.snowpark._internal.type_utilsrF   rG   rH   rI   rJ   rK   &snowflake.snowpark._internal.udf_utilsrL   "snowflake.snowpark._internal.utilsrM   rN   rO   rP   rQ   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r]   r^   r_   r`   ra   rb   rc   rd   re   rf   rg   rh   ri   rj   rk   rl   rm   rn   ro   rp   rq   rr   rs   rt   ru   rv   snowflake.snowpark.async_jobrw   rx   snowflake.snowpark.columnry   rz   r{   snowflake.snowpark.dataframer|   #snowflake.snowpark.dataframe_readerr~   snowflake.snowpark.exceptionsr   r   !snowflake.snowpark.file_operationr   snowflake.snowpark.functionsr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   snowflake.snowpark.lineager   !snowflake.snowpark.mock._analyzerr   rl  r   %snowflake.snowpark.mock._nop_analyzerr   'snowflake.snowpark.mock._nop_connectionr   $snowflake.snowpark.mock._pandas_utilr   r   %snowflake.snowpark.mock._plan_builderr   )snowflake.snowpark.mock._stored_procedurer   snowflake.snowpark.mock._udafr   snowflake.snowpark.mock._udfr   snowflake.snowpark.mock._udtfr    snowflake.snowpark.query_historyr   r   snowflake.snowpark.rowr   #snowflake.snowpark.stored_procedurer   ,snowflake.snowpark.stored_procedure_profilerr   %snowflake.snowpark.dataframe_profilerr   snowflake.snowpark.tabler   !snowflake.snowpark.table_functionr   r   snowflake.snowpark.typesr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   snowflake.snowpark.udafr   snowflake.snowpark.udfr   snowflake.snowpark.udtfr   modin.pandasr]  r   version_infor   collections.abcr  r  r   r  r   r  rs  rx  r}  r  r{  r  r  r  r  r  r  +_PYTHON_SNOWPARK_ENABLE_THREAD_SAFE_SESSIONr  rt  r  r  r  r  r  r  r  r  r  r  r  r   rW  r   r   r   r   r   r   r   r   r   r   <module>r     sm        	 	 
    #          . 4 D D D , , E I I 9 * @ C M F 
 V 
 H ;  W R    L F U  O+ + + + + + + + + + +X D , 3 ? <    $ / : D = A K U > < > F & K P C *       . 5 4 2 2 4 4::
 v((
H
 7 #&5 #i. (- 0 .R *; > 0 0 3 . ? : ? : 4 / E @ C > C >
 1 ,
 A <
 9 4 7 2 $E  0 , 1 , /V +8 4 -W ) 5 ). & (2 $'1 $)?)Avt  K(>(@fd  JNNc)n N&
ZI
 ZI
r   