
    ɯei                        d dl Z d dlmZ d dlmZmZmZmZmZm	Z	m
Z
 d dlZd dlmc mc mc mc mZ d dlmZmZmZ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" d dl#m$Z$ d dl%m&Z& d dl'm(Z(m)Z) d d	l*m+Z+m,Z, d d
l-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7 d dl8m9Z9m:Z: d dl;m<Z<m=Z=m>Z> d dl?m@Z@ d dlAmBZB d dlCmDZD d dlEmFZF e j                  dk  rd dlmHZH nd dlImHZH dddddddZJ eeK      ZL G d d      ZMy)    N)	getLogger)AnyDictListLiteralOptionalUnionoverload)CopyIntoLocationNodeSaveModeSnowflakeCreateTableTableCreationSource)
+build_expr_from_snowpark_column_or_col_name*build_expr_from_snowpark_column_or_sql_str-build_expr_from_snowpark_column_or_python_valbuild_expr_from_python_valdebug_check_missing_astfill_save_modefill_write_filewith_src_positionDATAFRAME_AST_PARAMETERbuild_table_name)"track_data_source_statement_params)open_telemetry_context_manager)add_api_calldfw_collect_api_telemetry)ColumnOrNameColumnOrSqlExpr)
SUPPORTED_TABLE_TYPESget_aliased_option_nameget_copy_into_location_optionsis_cloud_pathnormalize_remote_file_or_dirparse_table_name	publicapistr_to_enumvalidate_object_namewarning)AsyncJob_AsyncResultType)Column_to_col_if_str_to_col_if_sql_expr)SnowparkClientException)sql_expr)MockServerConnection)Row)   	   )IterableFIELD_DELIMITERRECORD_DELIMITERFIELD_OPTIONALLY_ENCLOSED_BYNULL_IFDATE_FORMATTIMESTAMP_FORMAT)SEPLINESEPQUOTE	NULLVALUE
DATEFORMATTIMESTAMPFORMATc            ,       	   e Zd ZdZe	 dJdddeddfd       ZedJd	ededd fd
       Ze	 dJde	dedd fd       Z
edJdedededd fd       Ze	 dKdee   dedd fd       Zeeddddddddddeeee   f   dee   dededed   deee      deeeef      dededeeeef      ddfd               Zeeddddddddddeeee   f   dee   dededed   deee      deeeef      dededeeeef      defd!              Zeedddddddddddddddddd"deeee   f   dee   dededed   deee      deeeef      ded#ee   d$ee   d%ee   d&ee   d'ee   d(ed)eeeeeee	   f   f      d*ee   d+ee	   dedeeeef      dee   f(d,              Zeeddddddddddddd-d.ed/ee	   d0ee   d1ee   d2eeeef      d3edeeeef      ded   d4ee   d5ee   d6ee   d7ee   ded8eeeef      dee   fd9              Zeeddddddddddddd-d.ed/ee	   d0ee   d1ee   d2eeeef      d3edeeeef      ded   d4ee   d5ee   d6ee   d7ee   ded8eeeef      defd:              Zeddddddddddddd-d.ed/ee	   d0ee   d1ee   d2eeeef      d3edeeeef      ded4eed;      d5ee   d6ee   d7ee   ded8eeeef      deee   ef   fd<       Zddddddddddddd-d=ed.ed/ee	   d0ee   d1ee   d2eeeef      d3edeeeef      ded4ee   d5ee   d6ee   d7ee   ded8eeeef      deee   ef   f d>Zedefd?       Zej@                  deddfd@       Ze	 dJd0edA   dedd fdB       Z!edddddddddddC
d.ed/ee	   d2eeeef      d3edeeeef      ded4ee   d5ee   d6ee   d7ee   ded8ee   deee   ef   fdD       Z"edddddddddddC
d.ed/ee	   d2eeeef      d3edeeeef      ded4ee   d5ee   d6ee   d7ee   ded8ee   deee   ef   fdE       Z#edddddddddddC
d.ed/ee	   d2eeeef      d3edeeeef      ded4ee   d5ee   d6ee   d7ee   ded8ee   deee   ef   fdF       Z$edddddddddddC
d.ed/ee	   d2eeeef      d3edeeeef      ded4ee   d5ee   d6ee   d7ee   ded8ee   deee   ef   fdG       Z%e	 	 dLdeeee   f   dHededdfdI       Z&e&Z'eZ(y)MDataFrameWritera;  Provides methods for writing data from a :class:`DataFrame` to supported output destinations.

    To use this object:

    1. Create an instance of a :class:`DataFrameWriter` by accessing the :attr:`DataFrame.write` property.
    2. (Optional) Specify the save mode by calling :meth:`mode`, which returns the same
       :class:`DataFrameWriter` that is configured to save data using the specified mode.
       The default mode is "errorifexists".
    3. Call :meth:`save_as_table` or :meth:`copy_into_location` to save the data to the
       specified destination.
    T	dataframez&snowflake.snowpark.dataframe.DataFrame	_emit_astreturnNc                 z   || _         t        j                  | _        d | _        i | _        d | _        d | _        |rt        |j                  |j                  |       t        j                         }t        |j                         || _        |j                  | j                  j                  j                          y y N)
_dataframer   ERROR_IF_EXISTS
_save_mode_partition_by_cur_options_DataFrameWriter__format_astr   _ast_id_sessionprotoExprr   dataframe_writer_set_ast_refdf)selfrC   rD   writers       e/var/www/html/glpi_dashboard/venv/lib/python3.12/site-packages/snowflake/snowpark/dataframe_writer.py__init__zDataFrameWriter.__init__Z   s     $"228<,.'+ 	#I$5$5y7I7I9UZZ\Ff556DI""499#=#=#@#@A     	save_modec                     t        |j                         t        d      | _        |r@| j                  4t        | j                  j                  j                  | j                         | S )a  Set the save mode of this :class:`DataFrameWriter`.

        Args:
            save_mode: One of the following strings.

                "append": Append data of this DataFrame to the existing table. Creates a table if it does not exist.

                "overwrite": Overwrite the existing table by dropping old table.

                "truncate": Overwrite the existing table by truncating old table.

                "errorifexists": Throw an exception if the table already exists.

                "ignore": Ignore this operation if the table already exists.

                Default value is "errorifexists".

        Returns:
            The :class:`DataFrameWriter` itself.
        z`save_mode`)r&   lowerr   rJ   rN   r   rS   r[   )rV   r[   rD   s      rX   modezDataFrameWriter.modeo   sO    2 %0OOx%

 .49955??QrZ   exprc                     || _         |r6| j                  *t        | j                  j                  j                  |       | S )zSpecifies an expression used to partition the unloaded table rows into separate files. It can be a
        :class:`Column`, a column name, or a SQL expression.
        )rK   rN   r   rS   partition_by)rV   r_   rD   s      rX   ra   zDataFrameWriter.partition_by   s>     " .6		**77 rZ   keyvaluec                     t        |t              }|| j                  |<   |rW| j                  K| j                  j                  j
                  j                         }||_        t        |j                  |       | S )a  Depending on the ``file_format_type`` specified, you can include more format specific options.
        Use the options documented in the `Format Type Options <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location.html#format-type-options-formattypeoptions>`__.
        )
r    WRITER_OPTIONS_ALIAS_MAPrL   rN   rS   optionsadd_1r   _2)rV   rb   rc   rD   aliased_keyts         rX   optionzDataFrameWriter.option   sg    
 .c3KL).+& .		**22668AAD9!$$FrZ   configsc                     |r|rt        d      ||st        d      |}|j                         D ]  \  }}| j                  |||        | S )zSets multiple specified options for this :class:`DataFrameWriter`.

        This method is same as calling :meth:`option` except that you can set multiple options at once.
        z]Cannot set options with both a dictionary and keyword arguments. Please use one or the other.zNo options were provided)rD   )
ValueErroritemsrl   )rV   rm   rD   kwargskvs         rX   rf   zDataFrameWriter.options   sd     vo  ? !;<<GMMO 	3DAqKK1	K2	3rZ   indexF )r^   column_ordercreate_temp_table
table_typeclustering_keysstatement_paramsblockrD   
table_namer^   rv   rw   rx   )ru   temp	temporary	transientry   rz   r{   rq   c                     y rG    rV   r|   r^   rv   rw   rx   ry   rz   r{   rD   rq   s              rX   save_as_tablezDataFrameWriter.save_as_table         	rZ   c                     y rG   r   r   s              rX   r   zDataFrameWriter.save_as_table   r   rZ   )r^   rv   rw   rx   ry   rz   r{   commentenable_schema_evolutiondata_retention_timemax_data_extension_timechange_trackingcopy_grantsiceberg_configtable_existsoverwrite_conditionrD   r   r   r   r   r   r   r   r   r   c                *   t        | j                  |xs | j                  j                        }|r| j                  w| j                  j                  j
                  j                         }t        |j                  j                        }|j                  j                  | j                         t        |j                  |       |t        |j                  |       |||_        ||_        ||_        |+|D ]&  }t'        |j(                  j+                         |       ( |@|j-                         D ]-  \  }}|j.                  j+                         }||_        ||_        / ||_        |	|	|j6                  _        |
|
|j:                  _        |||j<                  _        |||j>                  _        |||j@                  _        ||_!        |O|j-                         D ]<  \  }}|jD                  j+                         }||_        tG        |j2                  |       > |||jH                  _        |tK        |jL                  |       | j                  j                  j
                  jO                  |       | j                  j                  j
                  jQ                  |      \  }|tR        <   tU        | jV                  | j                        5  |rtY        |j[                         t\        d      n| j^                  }ta        |tb              r|ndje                  |      }tg        |       ta        |tb              rti        |      n|}||j[                         dvrtk        d      d}|j[                         dk(  r;| j                  jl                  jo                         D cg c]  }|jp                   }}|r$|D cg c]  }ts        |d      jt                   c}ng } |rtw        dd	       d
}|r(|j[                         tx        vrtk        dtx               |,|t\        jz                  k7  rtk        d|j8                   d      |t}        |d      jt                  nd}!| j                  j                  }"|t\        j~                  t\        j                  fv xs |t\        jz                  k(  xr |du}#|-ta        |"j                  t              s|#r|"j                  |      }t        |||| j                  j                  t        j                  || |	|
|||||||!      }$|"j                  j                  |$      }% |"j                  j                  |%f||t        j                  d|}&|s|&ndcddd       S c c}w c c}w # 1 sw Y   yxY w)a[#  Writes the data to the specified table in a Snowflake database.

        Args:
            table_name: A string or list of strings representing table name.
                If input is a string, it represents the table name; if input is of type iterable of strings,
                it represents the fully-qualified object identifier (database name, schema name, and table name).
            mode: One of the following values. When it's ``None`` or not provided,
                the save mode set by :meth:`mode` is used.

                "append": Append data of this DataFrame to the existing table. Creates a table if it does not exist.

                "overwrite": Overwrite the existing table. By default, drops and recreates the table.
                    When ``overwrite_condition`` is specified, performs selective overwrite: deletes only
                    rows matching the condition, then inserts new data.

                "truncate": Overwrite the existing table by truncating old table.

                "errorifexists": Throw an exception if the table already exists.

                "ignore": Ignore this operation if the table already exists.

            column_order: When ``mode`` is "append", data will be inserted into the target table by matching column sequence or column name. Default is "index". When ``mode`` is not "append", the ``column_order`` makes no difference.

                "index": Data will be inserted into the target table by column sequence.
                "name": Data will be inserted into the target table by matching column names. If the target table has more columns than the source DataFrame, use this one.

            create_temp_table: (Deprecated) The to-be-created table will be temporary if this is set to ``True``.
            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. Not applicable
                        for iceberg tables. Learn more about table types
                        `here <https://docs.snowflake.com/en/user-guide/tables-temp-transient.html>`_.
            clustering_keys: Specifies one or more columns or column expressions in the table as the clustering key.
                See `Clustering Keys & Clustered Tables <https://docs.snowflake.com/en/user-guide/tables-clustering-keys#defining-a-clustering-key-for-a-table>`_
                for more details.
            comment: Adds a comment for the created table. See
                `COMMENT <https://docs.snowflake.com/en/sql-reference/sql/comment>`_. This argument is ignored if a
                table already exists and save mode is ``append`` or ``truncate``.
            enable_schema_evolution: Enables or disables automatic changes to the table schema from data loaded into the table from source files. Setting
                to ``True`` enables automatic schema evolution and setting to ``False`` disables it. If not set, the default behavior is used.
            data_retention_time: Specifies the retention period for the table in days so that Time Travel actions (SELECT, CLONE, UNDROP) can be performed
                on historical data in the table.
            max_data_extension_time: Specifies the maximum number of days for which Snowflake can extend the data retention period for the table to prevent
                streams on the table from becoming stale.
            change_tracking: Specifies whether to enable change tracking for the table. If not set, the default behavior is used.
            copy_grants: When true, retain the access privileges from the original table when a new table is created with "overwrite" mode.
            statement_params: Dictionary of statement level parameters to be set while executing this action.
            block: A bool value indicating whether this function will wait until the result is available.
                When it is ``False``, this function executes the underlying queries of the dataframe
                asynchronously and returns an :class:`AsyncJob`.
            iceberg_config: A dictionary that can contain the following iceberg configuration values:

                * partition_by: specifies one or more partition expressions for the Iceberg table.
                    Can be a single Column, column name, SQL expression string, or a list of these.
                    Supports identity partitioning (column names) as well as partition transform functions
                    like bucket(), truncate(), year(), month(), day(), hour().

                * external_volume: specifies the identifier for the external volume where
                    the Iceberg table stores its metadata files and data in Parquet format

                * catalog: specifies either Snowflake or a catalog integration to use for this table

                * base_location: the base directory that snowflake can write iceberg metadata and files to

                * target_file_size: specifies a target Parquet file size for the table.
                    Valid values: 'AUTO' (default), '16MB', '32MB', '64MB', '128MB'

                * catalog_sync: optionally sets the catalog integration configured for Polaris Catalog

                * storage_serialization_policy: specifies the storage serialization policy for the table

                * iceberg_version: Overrides the version of iceberg to use. Defaults to 2 when unset.
            table_exists: Optional parameter to specify if the table is known to exist or not.
                Set to ``True`` if table exists, ``False`` if it doesn't, or ``None`` (default) for automatic detection.
                Primarily useful for "append", "truncate", and "overwrite" with overwrite_condition modes to avoid running query for automatic detection.
            overwrite_condition: Specifies the overwrite condition to perform atomic targeted delete-insert.
                Can only be used when ``mode`` is "overwrite". When provided and the table exists, rows matching
                the condition are atomically deleted and all rows from the DataFrame are inserted, preserving
                non-matching rows. When not provided, the default "overwrite" behavior applies (drop and recreate table).
                If the table does not exist, ``overwrite_condition`` is ignored and the table is created normally.


        Example 1::

            Basic table saves

            >>> df = session.create_dataframe([[1,2],[3,4]], schema=["a", "b"])
            >>> df.write.mode("overwrite").save_as_table("my_table", table_type="temporary")
            >>> session.table("my_table").collect()
            [Row(A=1, B=2), Row(A=3, B=4)]
            >>> df.write.save_as_table("my_table", mode="append", table_type="temporary")
            >>> session.table("my_table").collect()
            [Row(A=1, B=2), Row(A=3, B=4), Row(A=1, B=2), Row(A=3, B=4)]
            >>> df.write.mode("overwrite").save_as_table("my_transient_table", table_type="transient")
            >>> session.table("my_transient_table").collect()
            [Row(A=1, B=2), Row(A=3, B=4)]

        Example 2::

            Saving DataFrame to an Iceberg table. Note that the external_volume, catalog, and base_location should have been setup externally.
            See `Create your first Iceberg table <https://docs.snowflake.com/en/user-guide/tutorials/create-your-first-iceberg-table>`_ for more information on creating iceberg resources.

            >>> df = session.create_dataframe([[1,2],[3,4]], schema=["a", "b"])
            >>> from snowflake.snowpark.functions import col, bucket
            >>> iceberg_config = {
            ...     "external_volume": "example_volume",
            ...     "catalog": "example_catalog",
            ...     "base_location": "/iceberg_root",
            ...     "storage_serialization_policy": "OPTIMIZED",
            ...     "target_file_size": "128MB",
            ...     "partition_by": ["a", bucket(3, col("b"))],
            ... }
            >>> df.write.mode("overwrite").save_as_table("my_table", iceberg_config=iceberg_config) # doctest: +SKIP

        Example 3::

            Using overwrite_condition for targeted delete and insert:

            >>> from snowflake.snowpark.functions import col
            >>> df = session.create_dataframe([[1, "a"], [2, "b"], [3, "c"]], schema=["id", "val"])
            >>> df.write.mode("overwrite").save_as_table("my_table", table_type="temporary")
            >>> session.table("my_table").order_by("id").collect()
            [Row(ID=1, VAL='a'), Row(ID=2, VAL='b'), Row(ID=3, VAL='c')]

            >>> new_df = session.create_dataframe([[2, "updated2"], [5, "updated5"]], schema=["id", "val"])
            >>> new_df.write.mode("overwrite").save_as_table("my_table", overwrite_condition="id = 1 or val = 'b'")
            >>> session.table("my_table").order_by("id").collect()
            [Row(ID=2, VAL='updated2'), Row(ID=3, VAL='c'), Row(ID=5, VAL='updated5')]
        Nz'mode'.)namert   z/'column_order' must be either 'name' or 'index'r   zDataFrameWriter.save_as_tablezsave_as_table.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: zI'overwrite_condition' is only supported with mode='overwrite'. Got mode='z'.)_statement_paramsr{   	data_type)Mr   rH   r   rN   rP   
_ast_batchbindr   r_   write_tablerW   CopyFromr   r|   r   r^   rv   rw   rx   r   ry   rg   rp   rz   rh   ri   r{   r   rc   r   r   r   r   r   r   r   r   r   r   evalflushr   r   r   r&   r]   r   rJ   
isinstancestrjoinr'   r$   ro   schema_to_attributesr   r,   _expressionr(   r   	OVERWRITEr-   APPENDTRUNCATE_connr0   _table_existsr   _planr   OTHERS	_analyzerresolveexecuter*   	NO_RESULT)'rV   r|   r^   rv   rw   rx   ry   rz   r{   r   r   r   r   r   r   r   r   r   rD   rq   stmtr_   col_or_namerr   rs   rk   _r[   full_table_namecolumn_namesxcolclustering_exprsoverwrite_condition_exprsessionneeds_table_exists_checkcreate_table_logic_plansnowflake_planresults'                                          rX   r   zDataFrameWriter.save_as_table   s   x >OO-R1R1R
 .??++66;;=D$TYY%:%:;DKK  +, T__j9tyy$/'$0!%6D"(DO*#2 K?,,002K
  +,224 DAq--113AADAD
 DJ"%,"&25L,,2".1D((.&25L,,2*-<$$**D)*002 8DAq++//1AAD.qttQ78 '*6!!'".:,,.A OO$$//44T: ((3399$?./ ,D,>,>P e	1  DJJL(H=__  )S9
sxx
?S  !1 j#. !, 
 #|'9'9';CT'T !RSSL!!#v-040F0F0U0U0WX1XX #  / #3(GHTT
   !5N
 )
j..08MM DEZD[\ 
 #.9@R@R3R !!* 15  '2 $')H+ % oo..G'0!!5 ( (W x111U6IQU6U %
 $"7==2FG,  '44Z@&:%%#** '#'(!'#$ %..667NON*W]]**"2*44	
 F "'6DKe	1 e	1(  Y/e	1 e	1s,   CV	)U?<V	V!FV	?
V		V)ra   file_format_namefile_format_typeformat_type_optionsheaderrz   r{   validation_modestorage_integrationcredentials
encryptionrD   locationra   r   r   r   r   r   r   r   r   copy_optionsc                     y rG   r   rV   r   ra   r   r   r   r   rz   r{   r   r   r   r   rD   r   s                  rX   copy_into_locationz"DataFrameWriter.copy_into_locationC      ( 	rZ   c                     y rG   r   r   s                  rX   r   z"DataFrameWriter.copy_into_locationY  r   rZ   RETURN_ROWSc                D     | j                   dd|||||||||	|
|||d|S )a  Executes a `COPY INTO <location> <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location.html>`__ to unload data from a ``DataFrame`` into one or more files in a stage or external stage.

        Args:
            location: The destination stage location.
            partition_by: Specifies an expression used to partition the unloaded table rows into separate files. It can be a :class:`Column`, a column name, or a SQL expression.
            file_format_name: Specifies an existing named file format to use for unloading data from the table. The named file format determines the format type (CSV, JSON, PARQUET), as well as any other format options, for the data files.
            file_format_type: Specifies the type of files unloaded from the table. If a format type is specified, additional format-specific options can be specified in ``format_type_options``.
            format_type_options: Depending on the ``file_format_type`` specified, you can include more format specific options. Use the options documented in the `Format Type Options <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location.html#format-type-options-formattypeoptions>`__.
            header: Specifies whether to include the table column headings in the output files.
            statement_params: Dictionary of statement level parameters to be set while executing this action.
            copy_options: The kwargs that are used to specify the copy options. Use the options documented in the `Copy Options <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location.html#copy-options-copyoptions>`__.
            block: A bool value indicating whether this function will wait until the result is available.
                When it is ``False``, this function executes the underlying queries of the dataframe
                asynchronously and returns an :class:`AsyncJob`.
            validation_mode: String (constant) that instructs the COPY command to return the results of the query in the SQL
                statement instead of unloading the results to the specified cloud storage location.
                The only supported validation option is RETURN_ROWS. This option returns all rows produced by the query.
            storage_integration: Specifies the name of the storage integration used to delegate authentication responsibility for external cloud storage to a Snowflake identity and access management (IAM) entity.
            credentials: Specifies the security credentials for connecting to the cloud provider and accessing the private/protected cloud storage.
            encryption: Specifies the encryption settings used to decrypt encrypted files in the storage location.

        Returns:
            A list of :class:`Row` objects containing unloading results.

        Example::

            >>> # save this dataframe to a parquet file on the session stage
            >>> df = session.create_dataframe([["John", "Berry"], ["Rick", "Berry"], ["Anthony", "Davis"]], schema = ["FIRST_NAME", "LAST_NAME"])
            >>> remote_file_path = f"{session.get_session_stage()}/names.parquet"
            >>> copy_result = df.write.copy_into_location(remote_file_path, file_format_type="parquet", header=True, overwrite=True, single=True)
            >>> copy_result[0].rows_unloaded
            3
            >>> # the following code snippet just verifies the file content and is actually irrelevant to Snowpark
            >>> # download this file and read it using pyarrow
            >>> import os
            >>> import tempfile
            >>> import pyarrow.parquet as pq
            >>> with tempfile.TemporaryDirectory() as tmpdirname:
            ...     _ = session.file.get(remote_file_path, tmpdirname)
            ...     pq.read_table(os.path.join(tmpdirname, "names.parquet"))
            pyarrow.Table
            FIRST_NAME: string not null
            LAST_NAME: string not null
            ----
            FIRST_NAME: [["John","Rick","Anthony"]]
            LAST_NAME: [["Berry","Berry","Davis"]]
        r   )callerr   ra   r   r   r   r   rz   r{   r   r   r   r   rD   r   _internal_copy_into_locationr   s                  rX   r   z"DataFrameWriter.copy_into_locationo  sS    D 1t00 
'%-- 3-+ 3#!
 
 	
rZ   r   c                l   i }t        | j                  |xs | j                  j                        }|r,| j                  | j                  j                  j
                  j                         }t        t        |j                  d|z               }|j                  j                  | j                         t        ||f|||||	|
|||d	| |dk(  r&|||j                  _        |||j                  _        | j                  j                  j
                  j!                  |       | j                  j                  j
                  j#                  |      \  }|t$        <   t'        |      st)        |      n|}||n| j*                  }t-        |t.              rt1        |      j2                  }n6t-        |t4              r|j2                  }n|t7        dt9        |             t;        | j<                        \  }}|r|j?                  |       |r@i }|jA                         D ]  \  }}tC        |tD              }|||<    |j?                  |       | j                  jG                  tI        | j                  jJ                  ||||||||
|||            }tM        |d        |jN                  d||	d|S )	zInternal method to return a DataFrame that represents the result of the COPY INTO operation.
        This is used by the public copy_into_location method to perform the actual operation.
        write_)	ra   r   r   rz   r{   r   r   r   r   r   z_'partition_by' is expected to be a column name, a Column object, or a sql expression. Got type )
ra   r   r   r   r   r   r   r   r   r   z"DataFrameWriter.copy_into_location)rz   r{   r   )(r   rH   r   rN   rP   r   r   r   getattrr_   rW   r   r   r   rc   r   r   r   r   r"   r#   rK   r   r   r/   r   r+   	TypeErrortyper!   rL   updaterp   r    re   
_with_planr   r   r   _internal_collect_with_tag)rV   r   r   ra   r   r   r   r   rz   r{   r   r   r   r   rD   r   rq   r   r_   r   stage_locationcur_format_type_optionscur_copy_optionsformat_type_aliased_optionsrb   rc   rj   rU   s                               rX   r   z,DataFrameWriter._internal_copy_into_location  s   0 =OO-R1R1R
 .??++66;;=D$WTYY68I%JKDKK  + *$7!1 /$7'%  --#/2BD))/#/2BD))/OO$$//44T: ((3399$?./
 !* )2 	
 (4'?|TEWEWlC(#L1==Lf-'33L%qrv  xD  sE  rF  G 
 5S5
1!1 ##L1*,'1779 A
U5c;ST;@+K8A $**+FG__'' %%)!1!1$;- /$7'%
  	R=>,r,, 
-
 
 	
rZ   c                     | j                   S rG   )rM   )rV   s    rX   _formatzDataFrameWriter._format9  s    }}rZ   c                     g d}|j                         j                         }||vrt        d| d| d      || _        y )Ncsvjsonparquetz0Unsupported file format. Expected file formats: z, got '')stripr]   ro   rM   )rV   rc   allowed_formatscanon_file_format_names       rX   r   zDataFrameWriter._format=  sQ    4!&!4!4!6!8B?BSSZ[`Zaabc  /rZ   r   c                     || _         |r;| j                  /| j                   | j                  j                  j                  _        | S )zSpecifies the file format type to use for unloading data from the table. Allowed values are "csv", "json", and "parquet".
        The file format name can be case insensitive and will be used when calling :meth:`save`.
        )r   rN   rS   formatrc   )rV   r   rD   s      rX   r   zDataFrameWriter.formatH  s8     (.6:llDII&&--3rZ   )
ra   r   r   rz   r{   r   r   r   r   rD   c       
             | j                   t        d       | j                  dd|| j                   ||||||||	|
|d|S )a
  Executes internally a `COPY INTO <location> <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location.html>`__ to unload data from a ``DataFrame`` into a file in a stage or external stage.
        The file format type is determined by the last call to :meth:`format`.

        Args:
            location: The destination stage location.
            partition_by: Specifies an expression used to partition the unloaded table rows into separate files. It can be a :class:`Column`, a column name, or a SQL expression.
            format_type_options: Depending on the ``file_format_type`` specified, you can include more format specific options. Use the options documented in the `Format Type Options <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location.html#format-type-options-formattypeoptions>`__.
            header: Specifies whether to include the table column headings in the output files.
            statement_params: Dictionary of statement level parameters to be set while executing this action.
            copy_options: The kwargs that are used to specify the copy options. Use the options documented in the `Copy Options <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location.html#copy-options-copyoptions>`__.
            block: A bool value indicating whether this function will wait until the result is available.
                When it is ``False``, this function executes the underlying queries of the dataframe
                asynchronously and returns an :class:`AsyncJob`.
            validation_mode: Specifies the validation mode to use for unloading data from the table.
            storage_integration: Specifies the name of the storage integration used to delegate authentication responsibility for external cloud storage to a Snowflake identity and access management (IAM) entity.
            credentials: Specifies the security credentials for connecting to the cloud provider and accessing the private/protected cloud storage.
            encryption: Specifies the encryption settings used to decrypt encrypted files in the storage location.

        Returns:
            A list of :class:`Row` objects containing unloading results.

        Example::

            >>> # save this dataframe to a csv file on the session stage
            >>> df = session.create_dataframe([["John", "Berry"], ["Rick", "Berry"], ["Anthony", "Davis"]], schema = ["FIRST_NAME", "LAST_NAME"])
            >>> remote_file_path = f"{session.get_session_stage()}/names.csv"
            >>> copy_result = df.write.format("csv").save(remote_file_path, overwrite=True, single=True)
            >>> copy_result[0].rows_unloaded
            3
        zGFile format type is not specified. Call `format` before calling `save`.saver   r   r   ra   r   r   rz   r{   r   r   r   r   rD   r   )r   ro   r   rV   r   ra   r   r   rz   r{   r   r   r   r   rD   r   s                rX   r   zDataFrameWriter.saveV  sp    ^ <<Y  1t00 
!\\% 3-+ 3#!
 
 	
rZ   c       
         B     | j                   dd|d||||||||	|
|d|S )a3
  Executes internally a `COPY INTO <location> <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location.html>`__ to unload data from a ``DataFrame`` into one or more CSV files in a stage or external stage.

        Args:
            location: The destination stage location.
            partition_by: Specifies an expression used to partition the unloaded table rows into separate files. It can be a :class:`Column`, a column name, or a SQL expression.
            format_type_options: Depending on the ``file_format_type`` specified, you can include more format specific options. Use the options documented in the `Format Type Options <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location.html#format-type-options-formattypeoptions>`__.
            header: Specifies whether to include the table column headings in the output files.
            statement_params: Dictionary of statement level parameters to be set while executing this action.
            copy_options: The kwargs that are used to specify the copy options. Use the options documented in the `Copy Options <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location.html#copy-options-copyoptions>`__.
            block: A bool value indicating whether this function will wait until the result is available.
                When it is ``False``, this function executes the underlying queries of the dataframe
                asynchronously and returns an :class:`AsyncJob`.
            validation_mode: Specifies the validation mode to use for unloading data from the table.
            storage_integration: Specifies the name of the storage integration used to delegate authentication responsibility for external cloud storage to a Snowflake identity and access management (IAM) entity.
            credentials: Specifies the security credentials for connecting to the cloud provider and accessing the private/protected cloud storage.
            encryption: Specifies the encryption settings used to decrypt encrypted files in the storage location.

        Returns:
            A list of :class:`Row` objects containing unloading results.

        Example::

            >>> # save this dataframe to a csv file on the session stage
            >>> df = session.create_dataframe([["John", "Berry"], ["Rick", "Berry"], ["Anthony", "Davis"]], schema = ["FIRST_NAME", "LAST_NAME"])
            >>> remote_file_path = f"{session.get_session_stage()}/names.csv"
            >>> copy_result = df.write.csv(remote_file_path, overwrite=True, single=True)
            >>> copy_result[0].rows_unloaded
            3
        r   CSVr   r   r   r   s                rX   r   zDataFrameWriter.csv  sP    \ 1t00 
"% 3-+ 3#!
 
 	
rZ   c       
         B     | j                   dd|d||||||||	|
|d|S )a	  Executes internally a `COPY INTO <location> <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location.html>`__ to unload data from a ``DataFrame`` into a JSON file in a stage or external stage.

        Args:
            location: The destination stage location.
            partition_by: Specifies an expression used to partition the unloaded table rows into separate files. It can be a :class:`Column`, a column name, or a SQL expression.
            format_type_options: Depending on the ``file_format_type`` specified, you can include more format specific options. Use the options documented in the `Format Type Options <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location.html#format-type-options-formattypeoptions>`__.
            header: Specifies whether to include the table column headings in the output files.
            statement_params: Dictionary of statement level parameters to be set while executing this action.
            copy_options: The kwargs that are used to specify the copy options. Use the options documented in the `Copy Options <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location.html#copy-options-copyoptions>`__.
            block: A bool value indicating whether this function will wait until the result is available.
                When it is ``False``, this function executes the underlying queries of the dataframe
                asynchronously and returns an :class:`AsyncJob`.
            validation_mode: Specifies the validation mode to use for unloading data from the table.
            storage_integration: Specifies the name of the storage integration used to delegate authentication responsibility for external cloud storage to a Snowflake identity and access management (IAM) entity.
            credentials: Specifies the security credentials for connecting to the cloud provider and accessing the private/protected cloud storage.
            encryption: Specifies the encryption settings used to decrypt encrypted files in the storage location.

        Returns:
            A list of :class:`Row` objects containing unloading results.

        Example::

            >>> # save this dataframe to a json file on the session stage
            >>> df = session.sql("select parse_json('[{a: 1, b: 2}, {a: 3, b: 0}]')")
            >>> remote_file_path = f"{session.get_session_stage()}/names.json"
            >>> copy_result = df.write.json(remote_file_path, overwrite=True, single=True)
            >>> copy_result[0].rows_unloaded
            1
        r   JSONr   r   r   r   s                rX   r   zDataFrameWriter.json  sP    \ 1t00 
#% 3-+ 3#!
 
 	
rZ   c       
         B     | j                   dd|d||||||||	|
|d|S )a-  Executes internally a `COPY INTO <location> <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location.html>`__ to unload data from a ``DataFrame`` into a PARQUET file in a stage or external stage.

        Args:
            location: The destination stage location.
            partition_by: Specifies an expression used to partition the unloaded table rows into separate files. It can be a :class:`Column`, a column name, or a SQL expression.
            format_type_options: Depending on the ``file_format_type`` specified, you can include more format specific options. Use the options documented in the `Format Type Options <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location.html#format-type-options-formattypeoptions>`__.
            header: Specifies whether to include the table column headings in the output files.
            statement_params: Dictionary of statement level parameters to be set while executing this action.
            copy_options: The kwargs that are used to specify the copy options. Use the options documented in the `Copy Options <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location.html#copy-options-copyoptions>`__.
            block: A bool value indicating whether this function will wait until the result is available.
                When it is ``False``, this function executes the underlying queries of the dataframe
                asynchronously and returns an :class:`AsyncJob`.
            validation_mode: String (constant) that instructs the COPY command to return the results of the query in the SQL
                statement instead of unloading the results to the specified cloud storage location.
                The only supported validation option is RETURN_ROWS. This option returns all rows produced by the query.
            storage_integration: Specifies the name of the storage integration used to delegate authentication responsibility for external cloud storage to a Snowflake identity and access management (IAM) entity.
            credentials: Specifies the security credentials for connecting to the cloud provider and accessing the private/protected cloud storage.
            encryption: Specifies the encryption settings used to decrypt encrypted files in the storage location.

        Returns:
            A list of :class:`Row` objects containing unloading results.

        Example::

            >>> # save this dataframe to a parquet file on the session stage
            >>> df = session.create_dataframe([["John", "Berry"], ["Rick", "Berry"], ["Anthony", "Davis"]], schema = ["FIRST_NAME", "LAST_NAME"])
            >>> remote_file_path = f"{session.get_session_stage()}/names.parquet"
            >>> copy_result = df.write.parquet(remote_file_path, overwrite=True, single=True)
            >>> copy_result[0].rows_unloaded
            3
        r   PARQUETr   r   r   r   s                rX   r   zDataFrameWriter.parquet  sP    ` 1t00 
&% 3-+ 3#!
 
 	
rZ   	overwritec                 F   t        |t              r|ndj                  |      }t        |       t        |t              rt	        |      n|}| j
                  j                  j                  |      st        d| d      i }|r| j                  | j
                  j                  j                  j                         }t        |j                  j                        }|j                  j!                  | j                         t#        |j$                  |       ||_        | j
                  j                  j                  j)                  |       | j
                  j                  j                  j+                  |      \  }	|t,        <    | j.                  |f|rdnddd| y)	a  
        Inserts the content of the DataFrame to the specified table.
        It requires that the schema of the DataFrame is the same as the schema of the table.

        Args:
            table_name: A string or list of strings representing table name.
                If input is a string, it represents the table name; if input is of type iterable of strings,
                it represents the fully-qualified object identifier (database name, schema name, and table name).
            overwrite: If True, the content of table will be overwritten.
                If False, the data will be appended to the table. Default is False.

        Example::

            >>> # save this dataframe to a json file on the session stage
            >>> df = session.create_dataframe([["John", "Berry"]], schema = ["FIRST_NAME", "LAST_NAME"])
            >>> df.write.save_as_table("my_table", table_type="temporary")
            >>> df2 = session.create_dataframe([["Rick", "Berry"]], schema = ["FIRST_NAME", "LAST_NAME"])
            >>> df2.write.insert_into("my_table")
            >>> session.table("my_table").collect()
            [Row(FIRST_NAME='John', LAST_NAME='Berry'), Row(FIRST_NAME='Rick', LAST_NAME='Berry')]
        r   zTable z" does not exist or not authorized.NtruncateappendF)r^   rD   )r   r   r   r'   r$   rH   rP   r   r.   rN   r   r   r   r_   write_insert_intorW   r   r   r|   r   r   r   r   r   )
rV   r|   r   rD   r   qualified_table_namerq   r   r_   r   s
             rX   insert_intozDataFrameWriter.insert_intoZ  sh   : %Z5J388J;O 	 	_-,6z3,GZ(Z 	 ''556JK)))KL 
 .??++66;;=D$TYY%@%@ADKK  +
 T__j9&DNOO$$//44T: ((3399$?./ 	 	
(h	
 		
rZ   )T)NT)FT))__name__
__module____qualname____doc__r%   boolrY   r   r^   r   ra   r   rl   r   r   rf   r
   r	   r4   r   r   r   r)   r   intdictr   r1   r   r   propertyr   setterr   r   r   r   r   r   
insertIntosaveAsTabler   rZ   rX   rB   rB   M   s   
  B;B B 
	B B(  c  d  >O    D 7;#04	   # c d FW   @D~9=	 ( 
 ##"'DF<@59#x},- sm	
    @A "(<"89 #4S>2   4S>* 
    
 ##"'DF<@59#x},- sm	
    @A "(<"89 #4S>2   4S>* 
    
 ##"'DF<@59!%26-115*.! '+9=-S1#x},-S1 sm	S1
 S1  S1 @AS1 "(<"89S1 #4S>2S1 S1 #S1 "*$S1 &c]S1 "*#S1 "$S1  !S1" !eC/!::;;<
#S1( tn)S1* &o6+S1, -S1. 4S>*/S10 
(	1S1  S1j
 
 37*.*.8<59#)--1&*%) /	
 #3- #3- &d38n5  #4S>2 t} "# &c] d^ TN   !c3h0!" 
c#  ( 
 37*.*.8<59 %)--1&*%) /	
 #3- #3- &d38n5  #4S>2 u~ "# &c] d^ TN   !c3h0!" 
#  ( 
 37*.*.8<59<@-1&*%)Q
Q
 /	Q

 #3-Q
 #3-Q
 &d38n5Q
 Q
 #4S>2Q
 Q
 "'-"89Q
 &c]Q
 d^Q
 TNQ
 Q
  !c3h0!Q
" 
tCy("	##Q
 Q
p 37*.*.8<59)--1&*%)!t
t
 t

 /t
 #3-t
 #3-t
 &d38n5t
 t
 #4S>2t
 t
 "#t
 &c]t
 d^t
 TNt
  !t
" !c3h0#t
$ 
tCy("	#%t
l    ^^/S /T / /  !":;  
	  
 378<59)--1&*%)B
B
 /	B

 &d38n5B
 B
 #4S>2B
 B
 "#B
 &c]B
 d^B
 TNB
 B
 !B
 
tCy("	#B
 B
H 
 378<59)--1&*%)<
<
 /	<

 &d38n5<
 <
 #4S>2<
 <
 "#<
 &c]<
 d^<
 TN<
 <
 !<
 
tCy("	#<
 <
| 
 378<59)--1&*%)<
<
 /	<

 &d38n5<
 <
 #4S>2<
 <
 "#<
 &c]<
 d^<
 TN<
 <
 !<
 
tCy("	#<
 <
| 
 378<59)--1&*%)>
>
 /	>

 &d38n5>
 >
 #4S>2>
 >
 "#>
 &c]>
 d^>
 TN>
 >
 !>
 
tCy("	#>
 >
@   	C
#x},-C
 C
 	C

 
C
 C
J JKrZ   rB   )Nsysloggingr   typingr   r   r   r   r   r	   r
   snowflake.snowpark	snowflake4snowflake.snowpark._internal.proto.generated.ast_pb2snowpark	_internalrQ   	generatedast_pb29snowflake.snowpark._internal.analyzer.snowflake_plan_noder   r   r   r   &snowflake.snowpark._internal.ast.utilsr   r   r   r   r   r   r   r   r   r   .snowflake.snowpark._internal.data_source.utilsr   +snowflake.snowpark._internal.open_telemetryr   &snowflake.snowpark._internal.telemetryr   r   'snowflake.snowpark._internal.type_utilsr   r   "snowflake.snowpark._internal.utilsr   r    r!   r"   r#   r$   r%   r&   r'   r(   snowflake.snowpark.async_jobr)   r*   snowflake.snowpark.columnr+   r,   r-   snowflake.snowpark.exceptionsr.   snowflake.snowpark.functionsr/   #snowflake.snowpark.mock._connectionr0   snowflake.snowpark.rowr1   version_infor4   collections.abcre   r   _loggerrB   r   rZ   rX   <module>r     s   
   F F F  D D D    W R   D Q Q A 1 D &
 v( !+)  H
T  T rZ   