
    ɯei#             7       W   d Z ddlZddlZddlZddlmZ ddlZddlmZ ddl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 ddlmZmZ ddl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-m.Z.m/Z/m0Z0m1Z1 ddl2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8 ddl9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z? ddl@mAZA ddlBmCZCmDZDmEZEmFZFmGZGmHZHmIZI ddlJ ddlKmLZLmMZMmNZNmOZOmPZPmQZQ ddlRmSZSmTZT ddlUmVZVmWZWmXZXmYZYmZZZm[Z[m\Z\m]Z] ddl^m_Z_m`Z` ddlambZbmcZc ddldmeZemfZf ej                  dk  rddlmhZh nddlimhZh eeE	 ddddejdekdekdeMfd               ZleeE	 dddd!ejdejdekdekdeMf
d"              ZleE	 	 dddd#ejd$eej   dekdekdeMf
d%       ZleeE	 ddddejdekdekdeMfd&              ZmeeE	 dddd!ejdejdekdekdeMf
d'              ZmeE	 	 dddd#ejd$eej   dekdekdeMf
d(       ZmeE	 	 dd)e:d*eeW   dekdeMfd+       ZneEdd,ejdekdeMfd-       ZoeE	 	 	 dd.ejd/ejd0ejd1eeej      dekf
d2       ZpeEddekdeMfd3       ZqeEddekdeMfd4       ZreEddekdeMfd5       ZseEddekdeMfd6       ZteEddekdeMfd7       ZueEddekdeMfd8       ZveEddekdeMfd9       ZweEddekdeMfd:       ZxeEddekdeMfd;       ZyeEddekdeMfd<       ZzeEddekdeMfd=       Z{eEddekdeMfd>       Z|eE	 dd?e<d@eeMe}f   dekdeMfdA       Z~eEddBe<dekdeMfdC       ZeEddBe<dekdeMfdD       ZeE	 ddEe<dFeeMe}f   dekdeMfdG       ZeE	 ddEe<dFeeMe}f   dekdeMfdH       ZeE	 ddEe<dFeeMe}f   dekdeMfdI       ZeE	 ddJe<dKeeMe}f   dekdeMfdL       ZeE	 	 ddMe<dNe<dOee<   dekdeMf
dP       ZeEddBe<dekdeMfdQ       ZeEddBe<dekdeMfdR       ZeE	 ddSe<dTe<dekdeMfdU       ZeEddBe<dekdeMfdV       ZeEddWdXe<dekdeMfdY       ZeE	 ddSe<dTe<dekdeMfdZ       ZeE	 ddSe<dTe<dekdeMfd[       ZeEddWdXee<ee<   ee<   f   dekdeMfd\       ZeEddBe<dekdeMfd]       ZeEddBe<dekdeMfd^       ZeEddBe<dekdeMfd_       ZeEddBe<dekdeMfd`       ZeEddBe<dekdeMfda       ZeEddBe<dekdeMfdb       ZeEddBe<dekdeMfdc       ZeEddBe<dekdeMfdd       ZeEddBe<dekdeMfde       ZeEddBe<dekdeMfdf       ZeEddBe<dekdeMfdg       ZeEddBe<dekdeMfdh       ZeEddBe<dekdeMfdi       ZeEddBe<dekdeMfdj       ZeEddBe<dekdeMfdk       ZeE	 ddJe<dledekdeMfdm       ZeZeEddJe<dekdeMfdn       ZeE	 ddoe<dledekdeMfdp       ZeEddoe<dekdeMfdq       ZeE	 ddJe<dekddrfds       ZeE	 ddJe<dekddrfdt       ZeE	 	 	 	 	 ddJe<duejdvekdwekdxejH                  dy   dekddrfdz       ZeEddWdXe<dekdeMfd{       ZeZeEddWdBe<dekdeMfd|       ZeEddBe<dekdeMfd}       ZeEddBe<dekdeMfd~       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddee}   dekdeMfd       ZeE	 ddee<e}ef   dee<e}ef   dee<e}ef   dekdeMf
d       ZeEdde}dekdeMfd       ZeEdde}dekdeMfd       ZeEdde}dekdeMfd       ZeEdde}dekdeMfd       ZeEddBe<dekdeMfd       ZeE	 ddBe<de}dKe}dekdeMf
d       ZeE	 ddBe<dee;   dekdeMfd       ZeE	 ddee<e}ef   dee<e}ef   dekdeMfd       ZeE	 ddee<e}ef   dee<e}ef   dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEdde<de<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddJe<deeMe}f   dekfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<de}dekdeMfd       ZeEddWdXe<dekdeMfd       ZeEddBe<dekdeMfd       ZeE	 ddBe<de<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeE	 ddBe<deeMe}f   de<dekdeMf
d       ZeE	 ddBe<dee<   dekdeMfd       ZeE	 ddBe<deeMe}f   de<dekdeMf
d       ZeE	 ddBe<dee<   dekdeMfd       ZeEdde<dFeeMe}f   dekdeMfd       ZeEddJe<dekdeMfd       ZeEddBe<dekdeMfd       ZeE	 ddBe<dee<   dekdeMfd       ZeEddBe<dekdeMfd       ZeE	 dde<dee<   dekdeMfdń       ZeEddWdXe<dekdeMfdƄ       ZeE	 ddee<e}ef   dee<e}ef   dekdeMfdȄ       ZeE	 ddee<e}ef   dekdeMfdɄ       ZeE	 ddee<e}ef   dekdeMfdʄ       ZeE	 ddee<e}ef   dekdeMfd˄       Zdee<e}ef   deMfd̄Zdee<e}ef   deMfd̈́ZeE	 ddee<e}ef   dee<e}ef   dekdeMfdЄ       ZeE	 ddBe<dKee<e}ef   dekdeMfdф       ZeEddJe<dekdeMfd҄       ZeEdde<de<dekdeMfdՄ       ZeE	 	 dde<deeMe}f   deeeMe}f      dekdeMf
dׄ       ZeE	 dde<de;de}dekdeMf
dڄ       ZeE	 dddWde<de;deeMe}f   de:dekdeMfdބ       ZeE	 dde;de;de}dekdeMf
d       ZeE	 	 	 dddWde<de;de;deeMe}f   deeMe}f   de:dekdeMfd       ZeE	 	 dde<de;de;dekdeMf
d       ZeE	 	 dde<de<deeeMe}f      dekdeMf
d       ZeEddBeMdejdekdeMfd       ZeEddBe<dekdeMfd       ZeEddWdXe<dekdeMfd       ZeEddWdXe<dekdeMfd       ZeEddWdejdXe<dekdeMfd       ZeE	 dde<de<de<dekdeMf
d       ZeEddJe<de<dekdeMfd       ZeEddJe<de<dekdeMfd       ZeEddJe<de<dekdeMfd       ZeE	 dde<deeMe}f   deeMe}f   de<dekdeMfd       ZeE	 dde<deeMe}f   dekdeMfd       ZeE	 dde<deeMe}f   dekdeMfd       ZeEddJe<dekdeMfd        ZeE	 dǐde<deej   dekdeMfd       ZeE	 dƐde<de;dekdeMfd       ZeE	 ddBe<dee;   dekdeMfd       ZeE	 ddBe<ded   dekdeMfd       ZeE	 ddBe<dee;   dekdeMfd       Z eE	 ddBe<dee;   dekdeMfd	       ZeE	 ddBe<dee;   dekdeMfd
       ZeE	 ddBe<de:dekdeMfd       ZeE	 ddBe<de:dekdeMfd       ZeE	 ddBe<dee:   dekdeMfd       ZeEddekdeMfd       ZeEddekdeMfd       ZeEddekdeMfd       ZeEddBe<dekdeMfd       Z	eEddBe<dekdeMfd       Z
eE	 dǐde<dee<   dekdeMfd       ZeEddBe<dekdeMfd       ZeE	 dƐde<de:dekdeMfd       ZeE	 dƐde<de:dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd        ZeE	 dƐd!ee}e<f   dJe<dekdeMfd"       ZeE	 dƐd#ee}e<f   dJe<dekdeMfd$       ZeEddekdeMfd%       ZeE	 dƐd&e<d'e<dekdeMfd(       ZeEddBe<dekdeMfd)       ZeEddBe<dekdeMfd*       ZeE	 dƐd+e<d,e<dekdeMfd-       ZeEddJe<dekfd.       ZeE	 dƐd+e<d,e<dekdeMfd/       ZeE	 	 dΐd0e<d1e<d2ekdekdeMf
d3       ZeEdƐd4e<dekdeMfd5       ZeEdƐd4e<dekdeMfd6       ZeEdƐd4e<dekdeMfd7       Z eEddJe<dekdeMfd8       Z!eE	 	 	 dϐd4e<d9eek   d:eek   dekdeMf
d;       Z"eE	 dƐd<e<d=e<dekdeMfd>       Z#eEddWdXe<dekdeMfd?       Z$eE	 	 dǐd@e<dAe<dBee<   dekdeMf
dC       Z%eE	 	 dǐd@e<dAe<dBee<   dekdeMf
dD       Z&eE	 ddJe<dEee<e}f   dekfdF       Z'eE	 ddJe<dEee<e}f   dekfdG       Z(eE	 dƐdejdHe<dIe<dekdeMf
dJ       Z)eEdƐdHe<dIe<dekdeMfdK       Z*eE	 ddBe<dKee<e}ef   dekdeMfdL       Z+eE	 dƐdejdHe<dIe<dekdeMf
dM       Z,eEdƐdejdBe<dekdeMfdN       Z-eE	 ddee<e}f   dOee<e}f   dee<e}f   dekdeMf
dP       Z.eEdƐdejde<dekdeMfdQ       Z/eEddBe<dekdeMfdR       Z0eEddBe<dekdeMfdS       Z1eEddBe<dekdeMfdT       Z2eEddBe<dekdeMfdU       Z3eE	 	 	 dАdVe<dWejdXeej   dYeej   dekdeMfdZ       Z4eEddJe<dekdeMfd[       Z5eEddJe<dekdeMfd\       Z6eEddJe<dekdeMfd]       Z7eEddJe<dekdeMfd^       Z8e8Z9eEddJe<dekdeMfd_       Z:e:Z;eEddJe<dekdeMfd`       Z<eEddJe<dekdeMfda       Z=eEddJe<dekdeMfdb       Z>eEddJe<dekdeMfdc       Z?eEddJe<dekdeMfdd       Z@eEddJe<dekdeMfde       ZAeEddJe<dekdeMfdf       ZBeEddJe<dekdeMfdg       ZCeEddJe<dekdeMfdh       ZDeEddJe<dekdeMfdi       ZEdjejdkee<e}f   deeMdlf   fdmZFdjejdkee<e}f   dnee<e}f   deeMdlf   fdoZGeE	 	 dǐdpee<e}f   dqee<e}f   dree<e}f   dseee<e}f      dekdeMfdt       ZHeeE	 dƐdue<dve<dekdeMfdw              ZIeeE	 	 	 dАdxee<e}f   dyee<e}f   dzee<e}f   dpee<e}f   dqee<e}f   dree<e}f   d{eee<e}f      d|ee;   dekdeMfd}              ZIeEddWdekdeMfd~       ZIeE	 	 dǐdxee<e}f   dyee<e}f   dzee<e}f   dpee<e}f   dqee<e}f   dree<e}f   dseee<e}f      dekdeMfd       ZJeeE	 dƐdue<dve<dekdeMfd              ZKeeE	 	 dǐdxee<e}f   dyee<e}f   dzee<e}f   dpee<e}f   dqee<e}f   dree<e}f   d{eee<e}f      dekdeMfd              ZKeEddWdekdeMfd       ZKeE	 	 	 dАdxee<e}f   dyee<e}f   dzee<e}f   dpee<e}f   dqee<e}f   dree<e}f   dseee<e}f      d|ee;   dekdeMfd       ZLeEddBe<dekdeMfd       ZMeEddJe<dekdeMfd       ZNeEddJe<dekdeMfd       ZOeEddJe<dekdeMfd       ZPeE	 ddJe<due<dekdeMfd       ZQeEddBe<dekdeMfd       ZReEddBe<dekdeMfd       ZSeE	 ddBe<deejeWf   dekdeMfd       ZTeEddBe<dekdeMfd       ZUeEddJe<dekdeMfd       ZVeE	 ddJe<dekdekdeMfd       ZWeE	 dƐd4e<de<dekdeMfd       ZXeE	 dƐd4e<de:dekdeMfd       ZYeE	 dƐd+e<d,e<dekdeMfd       ZZeEdƐd4e<dekdeMfd       Z[eEddWdXe<dekdeMfd       Z\eEddWdXe<dekdeMfd       Z]eE	 dƐde<d4e<dekdeMfd       Z^eE	 dƐd4e<de<de<dekdeMf
d       Z_eE	 dƐde<d4e<dekdeMfd       Z`eE	 dƐd4e<de<dekdeMfd       ZaeEdƐd4e<dekdeMfd       ZbeE	 dƐd4e<de<de<dekdeMf
d       ZceE	 dƐd4e<de<dekdeMfd       ZdeEddJe<dekdeMfd       ZeeEddWdHe<dIe<dXe<dekfd       ZfeEdde:dJe<dekfd       ZgeEddJe<dekfd       ZheEddJe<dekdeMfd       ZieE	 dƐde<de<dekdeMfd       ZjeEddWde<dekdeMfd       ZkeEddWde<dekdeMfd       ZleEddWde<de<d<e<dekdeMf
d       ZmeE	 	 dǐde<de<de<dee<   dekdeMfd       ZneEddWde<de<d<e<dekdeMf
d       ZoeE	 dƐde<de<dekdeMfd       ZpeE	 dƐde<de<dekdeMfd       ZqeE	 dƐde<de<dekdeMfd       ZreEdƐde:dekdeMfd       ZseEdƐde<dekdeMfd       ZteEdƐde<dekdeMfd       ZueEdƐde<dekdeMfd       ZveEdƐde<dekdeMfd       ZweEdƐde<dekdeMfd       ZxeEdƐde<dekdeMfd       ZyeEdƐde<dekdeMfd       ZzeEdƐde<dekdeMfd       Z{eEdƐde<dekdeMfd       Z|eEdƐde<dekdeMfd       Z}eEdƐde<dekdeMfdÄ       Z~eE	 dƐde<deejeWf   dekdeMfdń       ZeE	 dƐde<deejeWf   dekdeMfdƄ       ZeE	 	 	 dАde<dee}   dKee}   dekdeMf
dǄ       ZeZeEdƐde<dekdeMfdȄ       ZeEdƐde<dekdeMfdɄ       ZeEdƐde<dekdeMfdʄ       ZeEdƐde<dekdeMfd˄       ZeEdƐde<dekdeMfd̄       ZeEdƐde<dekdeMfd̈́       ZeEdƐde<dekdeMfd΄       ZeEdƐde<dekdeMfdτ       ZeE	 ddBe<deej   dekdeMfdЄ       ZeEddBe<dekdeMfdф       ZeEddBe<dekdeMfd҄       ZeEddBe<dekdeMfdӄ       ZeEddBe<dekdeMfdԄ       ZeEddBe<dekdeMfdՄ       ZeE	 dƐde<de<dekdeMfdׄ       ZeEdƐde<dekdeMfd؄       ZeE	 	 dʐde<de<dee<e}f   dekdeMf
d܄       ZeEddJe<due<dekdeMfd݄       ZeE	 dƐdHee<e}f   dIee<e}f   dekdeMfdބ       ZeZeE	 dƐde=de:dekdeLfd       ZeE	 dƐde=de:de:dekdeMf
d       ZeEddWdXee<   dede>eMehe>   eheM   f   dekdeMfd       ZeEddekdeMfd       ZeEddekdeMfd       ZeEddekdeMfd       ZeEddekdeMfd       ZeEddekdeMfd       ZeE	 	 	 	 ddBe<de}dee:   dekdekdeMfd       ZeE	 	 	 	 ddBe<de}deeeMe>f      dekdekdeMfd       ZeE	 ddBe<dekdekdeMfd       ZeE	 ddBe<dekdekdeMfd       ZeE	 ddBe<dFe}dekdekdeMf
d       ZeEddBee}e<f   dekdeMfd       ZeEddledekdeMfd       ZeEddWde<dekdeMfd       ZeEddWde<dekdeMfd       ZeE	 	 	 ddBe<dejdekdekdeMf
d       ZeE	 dǐdeeM   dekddfd       ZeE	 dǐdeeM   dekddfd       ZeE	 dddddddddddddddddddddddddd ee
   deeW   deeeW      deeejehej   f      dekdeej   deeeejeejejf   f         deeeeje	f         dekd	ekd
ed   de}dee}   deeejejf      dekdekdekdeeej      deeejejf      dekdeej   deej   deeejejf      dekdeecejV                  f   f2d       ZeE	 dddddddddddddddddddddddee
   dee[eej   df   deeeW      deeejehej   f      dekdeej   deeeejeejejf   f         deeeeje	f         dekd	ekd
ed   de}deeejejf      dekdekdeeej      deeejejf      dekdeej   deej   deeejejf      dekdeefejV                  f   f.d       ZeE	 ddddddddddddddddddddddeej\                     deeW   deeeW      deeejehej   f      dekdeej   deeeejeejejf   f         deeeeje	f         dekd	ekd
ed   de}deeejejf      dekdeeej      deeejejf      deej   deej   deeejejf      dekdee`ejV                  f   f*d       ZeE	 ddddddddddddddddddddddd d ee
   deeW   deeeW      deeejehej   f      dekdeej   deeeejeejejf   f         deeeeje	f         dekd	ekd
ed   de}dee}   deeejejf      dekdekdekdeeej      deeejejf      dekdeej   dekdeecejV                  f   f.d!       ZdԐd"edee}   de
fd#ZeE	 dddddddddddddddddddddd$dee
   dee[eej   df   deeeW      d%eeej      deeejehej   f      dekdeej   deeeejeejejf   f         deeeeje	f         dekd	ekd
ed   de}deeejejf      dekdekdeeej      deeejejf      dekdee}   deej   dekdeefejV                  f   f.d&       ZeEddWd'ejdke:dekdeMfd(       ZeEddWd)eejehej   f   dke:dekdne:ddrf
d*       ZeEdƐd)ejdekde
fd+       ZeEddWd)ejdke:dekdeMfd,       ZeEdƐd)ejdekde
fd-       Z	 	 	 dАdejdneeje:f   d.eej   d/ejr                  dekdeMfd0ZeE	 dddddddddddddd1ddddddddd2d ee
   deeW   deeeW      deeejehej   f      dekdeej   deeeejeejejf   f         deeeeje	f         dekd	ekd
ed3   de}deeejejf      d4ejH                  d5   dekdekdeeej      deeejejf      deej   dekdeej   deeejejf      deeSejV                  f   f.d6       ZddWd7ejd8eej   d9ejdekdeMf
d:ZddWd;ejd9ejdekdeMfd<ZeE	 	 dǐd7ejd8eej   dekde
fd=       ZeE	 dƐd;ejdekde
fd>       ZeZeeZeWZeZeZeZeZeoZeZeZɐe"Zʐe#ZeZ̐edZ͐eZZΐefZeE	 ddBe<ded   dekdeMfd?       ZeE	 dՐdejde<d@e}dekdeMf
dA       ZeE	 	 	 	 	 	 	 	 	 	 	 	 	 	 d֐dBee}   dCee}   dDee}   dEee}   dFee}   dGee}   dHee}   dIee}   dJee}   dKee}   dsee}   dLee}   dMee}   dekdeMfdN       Z eIdOdPQ      eE	 	 	 	 dאdBee<   dDee<   dReek   dekdeMf
dS              Z eIdOdTQ      eE	 	 	 	 	 	 dؐdFee<   dGee<   dLee<   dMee<   dReek   dekdeMfdU              ZeE eHdVdWdXY      	 dde;dekdeMfdZ              ZeE eHdVd[d\Y      	 dde;dekdeMfd]              ZeEddBe<dekdeMfd^       ZeEddBe<dekdeMfd_       ZeEddBe<dekdeMfd`       ZeEddBe<dekdeMfda       ZeEdƐdbe<dekdeMfdc       ZeEddBe<dekdeMfdd       ZeE	 dƐdee<dekdeMfdf       ZeEddBe<dekdeMfdg       ZeEdƐdhe<die<dekdeMfdj       ZeEdƐdhe<die<dekdeMfdk       ZeZeEdِdle}dekdeMfdm       ZeE	 	 dǐdne<doe<dpee}   dekdeMf
dq       ZeE	 	 dǐdne<dre<dpee}   dekdeMf
ds       ZeEddBe<dekdeMfdt       ZeE	 	 dՐde<de<d@e}dekdeMf
du       ZeEdde<de<dekdeMfdv       ZeEdde<de<dekdeMfdw       ZeEdde<de<dekdeMfdx       ZeEdde<de<dekdeMfdy       ZeEdde<de<dekdeMfdz       ZeEdde<de<dekdeMfd{       ZeEdde<de<dekdeMfd|       ZeEdde<de<dekdeMfd}       ZeEdde<de<dekdeMfd~       ZeE	 ddBe<deej   dekdeMfd       ZeE	 	 	 ddBe<dee}   deej   dekdeMf
d       ZeZeE	 ddBe<deej   dekdeMfd       ZeZeEddBe<de}dekfd       ZeZeE	 	 dǐdhe<die<deee}e<f      dekdeMf
d       ZeEdde<dejdekfd       ZeE	 dƐdee}ef   dee}ef   dee<e}ef   dekfd       ZeE	 ddeee<e}ef      dekdeMfd       ZeEddJe<duejdekdeMfd       ZeEddJe<duejdekdeMfd       ZeEddJe<duejdekdeMfd       ZeEddJe<duejdekdeMfd       ZeEddJe<duejdekdeMfd       ZexZ ZexZZeE	 dƐdejdejdekdeMfd       ZeEdƐde:dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       Z	eEddBe<dekdeMfd       Z
eEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddBe<dekdeMfd       ZeEddWdejde<dekdeMfd       ZeE	 dƐd"ee;eMf   deeef   dekdeMfd       ZeE	 	 dǐde;deeM   dekdeMfd       ZeE	 dƐde;deeMeej   f   dekdeMfd       ZeEdƐde;dekdeMfd       ZeE	 dƐde;de;dekdeMfd       ZeE	 dƐde;de;dekdeMfd       ZeE	 dƐdeMdekdeMfd       ZeE	 dƐdeMdekdeMfd       ZeeE	 	 	 	 dېdejde;dee   dee   deek   dekdeMfd              ZeeE	 	 	 	 dېdejdejdeMdee   dee   deek   dekdeMfd              ZeE	 	 	 	 	 dܐdejde;deeM   dee   dee   deek   dekdeMfd       ZeE	 dƐdejd"e;dekdeMfd       Z eE	 	 dde;deeej      dekdeMfd       Z!eE	 dde;de;de;dekdeMf
dń       Z"y(  a  
Provides utility and SQL functions that generate :class:`~snowflake.snowpark.Column` expressions that you can pass to :class:`~snowflake.snowpark.DataFrame` transformation methods.

These utility functions generate references to columns, literals, and SQL expressions (e.g. "c + 1").

  - Use :func:`col()` to convert a column name to a :class:`Column` object. Refer to the API docs of :class:`Column` to know more ways of referencing a column.
  - Use :func:`lit()` to convert a Python value to a :class:`Column` object that represents a constant value in Snowflake SQL.
  - Use :func:`sql_expr()` to convert a Snowflake SQL expression to a :class:`Column`.

    >>> df = session.create_dataframe([[1, 'a', True, '2022-03-16'], [3, 'b', False, '2023-04-17']], schema=["a", "b", "c", "d"])
    >>> res1 = df.filter(col("a") == 1).collect()
    >>> res2 = df.filter(lit(1) == col("a")).collect()
    >>> res3 = df.filter(sql_expr("a = 1")).collect()
    >>> assert res1 == res2 == res3
    >>> res1
    [Row(A=1, B='a', C=True, D='2022-03-16')]

Some :class:`DataFrame` methods accept column names or SQL expressions text aside from a Column object for convenience.
For instance:

    >>> df.filter("a = 1").collect()  # use the SQL expression directly in filter
    [Row(A=1, B='a', C=True, D='2022-03-16')]
    >>> df.select("a").collect()
    [Row(A=1), Row(A=3)]

whereas :class:`Column` objects enable you to use chained column operators and transformations with
Python code fluently:

    >>> # Use columns and literals in expressions.
    >>> df.select(((col("a") + 1).cast("string")).alias("add_one")).show()
    -------------
    |"ADD_ONE"  |
    -------------
    |2          |
    |4          |
    -------------
    <BLANKLINE>

The Snowflake database has hundreds of `SQL functions <https://docs.snowflake.com/en/sql-reference-functions.html>`_
This module provides Python functions that correspond to the Snowflake SQL functions. They typically accept :class:`Column`
objects or column names as input parameters and return a new :class:`Column` objects.
The following examples demonstrate the use of some of these functions:

    >>> # This example calls the function that corresponds to the TO_DATE() SQL function.
    >>> df.select(dateadd('day', lit(1), to_date(col("d")))).show()
    ---------------------------------------
    |"DATEADD('DAY', 1, TO_DATE(""D""))"  |
    ---------------------------------------
    |2022-03-17                           |
    |2023-04-18                           |
    ---------------------------------------
    <BLANKLINE>

If you want to use a SQL function in Snowflake but can't find the corresponding Python function here,
you can create your own Python function with :func:`function`:

    >>> my_radians = function("radians")  # "radians" is the SQL function name.
    >>> df.select(my_radians(col("a")).alias("my_radians")).show()
    ------------------------
    |"MY_RADIANS"          |
    ------------------------
    |0.017453292519943295  |
    |0.05235987755982988   |
    ------------------------
    <BLANKLINE>

or call the SQL function directly:

    >>> df.select(call_function("radians", col("a")).as_("call_function_radians")).show()
    ---------------------------
    |"CALL_FUNCTION_RADIANS"  |
    ---------------------------
    |0.017453292519943295     |
    |0.05235987755982988      |
    ---------------------------
    <BLANKLINE>

Similarly, to call a table function, you can use :func:`~snowflake.snowpark.functions.table_function`, or :func:`~snowflake.snowpark.functions.call_table_function`.

**How to find help on input parameters of the Python functions for SQL functions**
The Python functions have the same name as the corresponding `SQL functions <https://docs.snowflake.com/en/sql-reference-functions.html>`_.

By reading the API docs or the source code of a Python function defined in this module, you'll see the type hints of the input parameters and return type.
The return type is always ``Column``. The input types tell you the acceptable values:

  - ``ColumnOrName`` accepts a :class:`Column` object, or a column name in str. Most functions accept this type.
    If you still want to pass a literal to it, use `lit(value)`, which returns a ``Column`` object that represents a literal value.

    >>> df.select(avg("a")).show()
    ----------------
    |"AVG(""A"")"  |
    ----------------
    |2.000000      |
    ----------------
    <BLANKLINE>
    >>> df.select(avg(col("a"))).show()
    ----------------
    |"AVG(""A"")"  |
    ----------------
    |2.000000      |
    ----------------
    <BLANKLINE>

  - ``LiteralType`` accepts a value of type ``bool``, ``int``, ``float``, ``str``, ``bytearray``, ``decimal.Decimal``,
    ``datetime.date``, ``datetime.datetime``, ``datetime.time``, or ``bytes``. An example is the third parameter of :func:`lead`.

    >>> import datetime
    >>> from snowflake.snowpark.window import Window
    >>> df.select(col("d"), lead("d", 1, datetime.date(2024, 5, 18), False).over(Window.order_by("d")).alias("lead_day")).show()
    ---------------------------
    |"D"         |"LEAD_DAY"  |
    ---------------------------
    |2022-03-16  |2023-04-17  |
    |2023-04-17  |2024-05-18  |
    ---------------------------
    <BLANKLINE>

  - ``ColumnOrLiteral`` accepts a ``Column`` object, or a value of ``LiteralType`` mentioned above.
    The difference from ``ColumnOrLiteral`` is ``ColumnOrLiteral`` regards a str value as a SQL string value instead of
    a column name. When a function is much more likely to accept a SQL constant value than a column expression, ``ColumnOrLiteral``
    is used. Yet you can still pass in a ``Column`` object if you need to. An example is the second parameter of
    :func:``when``.

    >>> df.select(when(df["a"] > 2, "Greater than 2").else_("Less than 2").alias("compare_with_2")).show()
    --------------------
    |"COMPARE_WITH_2"  |
    --------------------
    |Less than 2       |
    |Greater than 2    |
    --------------------
    <BLANKLINE>

  - ``int``, ``bool``, ``str``, or another specific type accepts a value of that type. An example is :func:`to_decimal`.

    >>> df.with_column("e", lit("1.2")).select(to_decimal("e", 5, 2)).show()
    -----------------------------
    |"TO_DECIMAL(""E"", 5, 2)"  |
    -----------------------------
    |1.20                       |
    |1.20                       |
    -----------------------------
    <BLANKLINE>

  - ``ColumnOrSqlExpr`` accepts a ``Column`` object, or a SQL expression. For instance, the first parameter in :func:``when``.

    >>> df.select(when("a > 2", "Greater than 2").else_("Less than 2").alias("compare_with_2")).show()
    --------------------
    |"COMPARE_WITH_2"  |
    --------------------
    |Less than 2       |
    |Greater than 2    |
    --------------------
    <BLANKLINE>
    N)reduce)randint)
ModuleType)CallableDictListOptionalTupleUnionoverload)general_functions)_call_function_check_column_parameters)
CaseWhenFunctionExpressionIntervalListAggLiteralModelExpressionServiceExpressionMultipleExpressionStarNamedFunctionExpression)Alias)
FirstValueLag	LastValueLeadNthValue)build_builtin_fn_applybuild_call_table_function_apply-build_expr_from_snowpark_column_or_python_val*build_expr_from_snowpark_column_or_sql_strwith_src_positionbuild_function_expr)ColumnOrLiteralColumnOrLiteralStrColumnOrNameColumnOrSqlExprLiteralTypetype_string_to_type_object)check_decorator_args)parse_duration_stringparse_positional_args_to_list	publicapivalidate_object_namecheck_create_map_parameter
deprecatedprivate_preview)*)CaseExprColumn_to_col_if_lit_to_col_if_sql_expr_to_col_if_str_to_col_if_str_or_int)StoredProcedureStoredProcedureRegistration)	ArrayTypeDataType	FloatTypePandasDataFrameType
StringType
StructTypeTimestampTimeZoneTimestampType)UDAFRegistrationUserDefinedAggregateFunction)UDFRegistrationUserDefinedFunction)UDTFRegistrationUserDefinedTableFunction)   	   )IterableTF_is_qualified_namecol_name	_emit_astrO   returnc                     y)zReturns the :class:`~snowflake.snowpark.Column` with the specified name.

    Args:
        col_name: The name of the column.

    Example::
        >>> df = session.sql("select 1 as a")
        >>> df.select(col("a")).collect()
        [Row(A=1)]
    N rP   rQ   rO   s      ^/var/www/html/glpi_dashboard/venv/lib/python3.12/site-packages/snowflake/snowpark/functions.pycolrW              df_aliasc                     y)zReturns the :class:`~snowflake.snowpark.Column` with the specified dataframe alias and column name.

    Example::
        >>> df = session.sql("select 1 as a")
        >>> df.alias("df").select(col("df", "a")).collect()
        [Row(A=1)]
    NrT   rZ   rP   rQ   rO   s       rV   rW   rW           rY   name1name2c                4    t        j                  | |||      S )NrN   )r   rW   r^   r_   rQ   rO   s       rV   rW   rW   (  s!       ui4F rY   c                     y)a  Returns a :class:`~snowflake.snowpark.Column` with the specified name. Alias for col.

    Args:
         col_name: The name of the column.

    Example::
         >>> df = session.sql("select 1 as a")
         >>> df.select(column("a")).collect()
         [Row(A=1)]
    NrT   rU   s      rV   columnrc   5  rX   rY   c                     y)a  Returns a :class:`~snowflake.snowpark.Column` with the specified name and dataframe alias name. Alias for col.

    Example::
        >>> df = session.sql("select 1 as a")
        >>> df.alias("df").select(column("df", "a")).collect()
        [Row(A=1)]
    NrT   r\   s       rV   rc   rc   G  r]   rY   c                \    t        | |       |t        | ||d      S t        | |||d      S )Nrc   )rO   rQ   _caller_name)r   r6   ra   s       rV   rc   rc   Z  sJ     UE*}1!	
 	
 1!
 	
rY   literaldatatypec                 0    t        j                  | ||      S )ai  
    Creates a :class:`~snowflake.snowpark.Column` expression for a literal value.
    It supports basic Python data types, including ``int``, ``float``, ``str``,
    ``bool``, ``bytes``, ``bytearray``, ``datetime.time``, ``datetime.date``,
    ``datetime.datetime`` and ``decimal.Decimal``. Also, it supports Python structured data types,
    including ``list``, ``tuple`` and ``dict``, but this container must
    be JSON serializable. If a ``Column`` object is passed, it is returned as is.

    Example::

        >>> import datetime
        >>> columns = [lit(1), lit("1"), lit(1.0), lit(True), lit(b'snow'), lit(datetime.date(2023, 2, 2)), lit([1, 2]), lit({"snow": "flake"}), lit(lit(1))]
        >>> session.create_dataframe([[]]).select([c.as_(str(i)) for i, c in enumerate(columns)]).show()
        ---------------------------------------------------------------------------------------------
        |"0"  |"1"  |"2"  |"3"   |"4"                 |"5"         |"6"   |"7"                |"8"  |
        ---------------------------------------------------------------------------------------------
        |1    |1    |1.0  |True  |bytearray(b'snow')  |2023-02-02  |[     |{                  |1    |
        |     |     |     |      |                    |            |  1,  |  "snow": "flake"  |     |
        |     |     |     |      |                    |            |  2   |}                  |     |
        |     |     |     |      |                    |            |]     |                   |     |
        ---------------------------------------------------------------------------------------------
        <BLANKLINE>
    )r   lit)rg   rh   rQ   s      rV   rj   rj   u  s    :   (I>>rY   sqlc                     d}|rQt        j                         }t        |j                        }| |_        t        j                         }t        |d|       t        j                  | |      S )a  Creates a :class:`~snowflake.snowpark.Column` expression from raw SQL text.
    Note that the function does not interpret or check the SQL text.

    Example::
        >>> df = session.create_dataframe([[1, 2], [3, 4]], schema=["A", "B"])
        >>> df.select(sql_expr("a + 1").as_("c"), sql_expr("a = 1").as_("d")).collect()  # use SQL expression
        [Row(C=2, D=True), Row(C=4, D=False)]
    Nsql_expr)ast)protoExprr$   rm   rk   r    r6   _expr)rk   rQ   rn   sql_expr_asts       rV   rm   rm     sX     Czz| 5 56 jjlsJ=<<%%rY   object_typeobject_identifierscope
privilegesc                 `    |xs g }|rt        d| ||g|z         nd}t        d| ||g|||dS )a  
    Returns a reference to an object (a table, view, or function). When you execute SQL actions on a
    reference to an object, the actions are performed using the role of the user who created the
    reference.

    Example::
        >>> df = session.create_dataframe([(1,)], schema=["A"])
        >>> df.write.save_as_table("my_table", mode="overwrite", table_type="temporary")
        >>> df.select(substr(system_reference("table", "my_table"), 1, 14).alias("identifier")).collect()
        [Row(IDENTIFIER='ENT_REF_TABLE_')]
    system_referenceNzsystem$reference_astrQ   )r%   r   )rs   rt   ru   rv   rQ   rn   s         rV   rx   rx     sl    & !rJ 	 	+U3j@	

   	
 
  rY   c                     t        d|       S )a  
    Returns a unique system identifier for the Snowflake session corresponding to the present connection.
    This will generally be a system-generated alphanumeric string. It is NOT derived from the user name or user account.

    Example:
        >>> # Return result is tied to session, so we only test if the result exists
        >>> result = session.create_dataframe([1]).select(current_session()).collect()
        >>> assert result[0]['CURRENT_SESSION()'] is not None
    current_sessionrQ   r   r}   s    rV   r|   r|     s     +yAArY   c                     t        d|       S )a  
    Returns the SQL text of the statement that is currently executing.

    Example:
        >>> # Return result is tied to session, so we only test if the result exists
        >>> session.create_dataframe([1]).select(current_statement()).collect() # doctest: +SKIP
        [Row(CURRENT_STATEMENT()='SELECT current_statement() FROM ( SELECT "_1" FROM ( SELECT $1 AS "_1" FROM  VALUES (1 :: INT)))')]
    current_statementr}   r~   r}   s    rV   r   r          -CCrY   c                     t        d|       S )a:  
    Returns the name of the user currently logged into the system.

    Example:
        >>> # Return result is tied to session, so we only test if the result exists
        >>> result = session.create_dataframe([1]).select(current_user()).collect()
        >>> assert result[0]['CURRENT_USER()'] is not None
    current_userr}   r~   r}   s    rV   r   r     s     .I>>rY   c                     t        d|       S )a(  
    Returns the current Snowflake version.

    Example:
        >>> # Return result is tied to session, so we only test if the result exists
        >>> result = session.create_dataframe([1]).select(current_version()).collect()
        >>> assert result[0]['CURRENT_VERSION()'] is not None
    current_versionr}   r~   r}   s    rV   r   r     s     +yAArY   c                     t        d|       S )aG  
    Returns the name of the warehouse in use for the current session.

    Example:
        >>> # Return result is tied to session, so we only test if the result exists
        >>> result = session.create_dataframe([1]).select(current_warehouse()).collect()
        >>> assert result[0]['CURRENT_WAREHOUSE()'] is not None
    current_warehouser}   r~   r}   s    rV   r   r     r   rY   c                     t        d|       S )a?  Returns the name of the database in use for the current session.

    Example:
        >>> # Return result is tied to session, so we only test if the result exists
        >>> result = session.create_dataframe([1]).select(current_database()).collect()
        >>> assert result[0]['CURRENT_DATABASE()'] is not None
    current_databaser}   r~   r}   s    rV   r   r     s     ,	BBrY   c                     t        d|       S )a3  Returns the name of the role in use for the current session.

    Example:
        >>> # Return result is tied to session, so we only test if the result exists
        >>> result = session.create_dataframe([1]).select(current_role()).collect()
        >>> assert result[0]['CURRENT_ROLE()'] is not None
    current_roler}   r~   r}   s    rV   r   r   !       .I>>rY   c                     t        d|       S )a9  Returns the name of the schema in use for the current session.

    Example:
        >>> # Return result is tied to session, so we only test if the result exists
        >>> result = session.create_dataframe([1]).select(current_schema()).collect()
        >>> assert result[0]['CURRENT_SCHEMA()'] is not None
    current_schemar}   r~   r}   s    rV   r   r   -       *i@@rY   c                     t        d|       S )a   Returns active search path schemas.

    Example:
        >>> # Return result is tied to session, so we only test if the result exists
        >>> result = session.create_dataframe([1]).select(current_schemas()).collect()
        >>> assert result[0]['CURRENT_SCHEMAS()'] is not None
    current_schemasr}   r~   r}   s    rV   r   r   9       +yAArY   c                     t        d|       S )aN  Returns the name of the region for the account where the current user is logged in.

    Example:
        >>> # Return result is tied to session, so we only test if the result exists
        >>> result = session.create_dataframe([1]).select(current_region()).collect()
        >>> assert result[0]['CURRENT_REGION()'] is not None
    current_regionr}   r~   r}   s    rV   r   r   E  r   rY   c                     t        d|       S )a9  Returns the name of the account used in the current session.

    Example:
        >>> # Return result is tied to session, so we only test if the result exists
        >>> result = session.create_dataframe([1]).select(current_account()).collect()
        >>> assert result[0]['CURRENT_ACCOUNT()'] is not None
    current_accountr}   r~   r}   s    rV   r   r   Q  r   rY   c                     t        d|       S )aT  Returns a JSON string that lists all roles granted to the current user.

    Example:
        >>> # Return result is tied to session, so we only test if the result exists
        >>> result = session.create_dataframe([1]).select(current_available_roles()).collect()
        >>> assert result[0]['CURRENT_AVAILABLE_ROLES()'] is not None
    current_available_rolesr}   r~   r}   s    rV   r   r   ]  s     3yIIrY   date_or_timestampnumber_of_monthsc                 8    t        | d      }t        d|||      S )aO  Adds or subtracts a specified number of months to a date or timestamp, preserving the end-of-month information.

    Example:
        >>> import datetime
        >>> df = session.create_dataframe([datetime.date(2022, 4, 6)], schema=["d"])
        >>> df.select(add_months("d", 4)).collect()[0][0]
        datetime.date(2022, 8, 6)
    
add_monthsr}   r9   r   )r   r   rQ   cs       rV   r   r   i  s#     	(,7A,+;yQQrY   ec                 6    t        | d      }t        d||      S )aR  Returns a non-deterministic any value for the specified column.
    This is an aggregate and window function.

    Example:
        >>> df = session.create_dataframe([[1, 2], [3, 4]], schema=["a", "b"])
        >>> result = df.select(any_value("a")).collect()
        >>> assert len(result) == 1  # non-deterministic value in result.
    	any_valuer}   r   r   rQ   r   s      rV   r   r   {  s     	q+&A+qI>>rY   c                 6    t        | d      }t        d||      S )zReturns the bitwise negation of a numeric expression.

    Example:
        >>> df = session.create_dataframe([1], schema=["a"])
        >>> df.select(bitnot("a")).collect()[0][0]
        -2
    bitnotr}   r   r   s      rV   r   r     s     	q(#A(A;;rY   to_shift_columnnc                 8    t        | d      }t        d|||      S )zReturns the bitwise negation of a numeric expression.

    Example:
        >>> df = session.create_dataframe([2], schema=["a"])
        >>> df.select(bitshiftleft("a", 1)).collect()[0][0]
        4
    bitshiftleftr}   r   r   r   rQ   r   s       rV   r   r     s!     	7A.!Q)DDrY   c           	          |rt        d| |g      nd}t        | d      }t        t        dd      dd      }t	        |dk  t        ||z   |d      t        ||d      d      }t        d||dz
  ||	      S )
a  Returns the bitwise negation of a numeric expression.

    Example:
        >>> df = session.createDataFrame([(-1999)], ['a'])
        >>> df.select(bitshiftright_unsigned('a', 1)).collect()[0][0]
        9223372036854774808

        >>> df = session.createDataFrame([(42)], ['a'])
        >>> df.select(bitshiftright_unsigned('a', 1)).collect()[0][0]
        21

        >>> df = session.createDataFrame([(-21)], ['a'])
        >>> df.select(bitshiftright_unsigned('a', 1)).collect()[0][0]
        9223372036854775797
    bitshiftright_unsignedN   Fr}   @   r   bitandry   )r%   r9   r   rj   iffbitshiftrightr   )r   r   rQ   rn   r   max_bit
unsigned_cs          rV   r   r     s    ,  	46JK  	(@AA3qE2B%HG	Aa'k16ae,	J *gky rY   c                 8    t        | d      }t        d|||      S )zReturns the bitwise negation of a numeric expression.

    Example:
        >>> df = session.create_dataframe([2], schema=["a"])
        >>> df.select(bitshiftright("a", 1)).collect()[0][0]
        1
    r   r}   r   r   s       rV   r   r     s!     	8A/1a9EErY   rW   scalec           	          |rt        d| |g      nd}t        | d      } t        |d      }t        d| |t	        dd      ||      S )a[  
    Rounds the number using `HALF_TO_EVEN` option. The `HALF_TO_EVEN` rounding mode rounds the given decimal value to the specified scale (number of decimal places) as follows:
    * If scale is greater than or equal to 0, round to the specified number of decimal places using half-even rounding. This rounds towards the nearest value with ties (equally close values) rounding to the nearest even digit.
    * If scale is less than 0, round to the integral part of the decimal. This rounds towards 0 and truncates the decimal places.

    Note:

        1. The data type of the expression must be one of the `data types for a fixed-point number
        <https://docs.snowflake.com/en/sql-reference/data-types-numeric.html#label-data-types-for-fixed-point-numbers>`_.

        2. Data types for floating point numbers (e.g. FLOAT) are not supported with this argument.

        3. If the expression data type is not supported, the expression must be explicitly cast to decimal before calling.

    Example:
        >>> import decimal
        >>> data = [(decimal.Decimal(1.235)),(decimal.Decimal(3.5))]
        >>> df = session.createDataFrame(data, ["value"])
        >>> df.select(bround('VALUE',1).alias("VALUE")).show() # Rounds to 1 decimal place
        -----------
        |"VALUE"  |
        -----------
        |1.2      |
        |3.5      |
        -----------
        <BLANKLINE>
        >>> df.select(bround('VALUE',0).alias("VALUE")).show() # Rounds to 1 decimal place
        -----------
        |"VALUE"  |
        -----------
        |1        |
        |4        |
        -----------
        <BLANKLINE>
    broundNROUNDHALF_TO_EVENFr}   ry   )r%   r9   r7   r   rj   )rW   r   rQ   rn   s       rV   r   r     s[    P :C
he
5C
h
'C5(+E Ne, rY   target_timezonesource_timesource_timezonec                     |t        |d      nd}t        | d      }t        |d      }|rt        d| |g|g n|gz         nd}|t        d||||      S t        d|||||      S )a=  Converts the given source_time to the target timezone.

    For timezone information, refer to the `Snowflake SQL convert_timezone notes <https://docs.snowflake.com/en/sql-reference/functions/convert_timezone.html#usage-notes>`_

        Args:
            target_timezone: The time zone to which the input timestamp should be converted.=
            source_time: The timestamp to convert. When it's a TIMESTAMP_LTZ, use ``None`` for ``source_timezone``.
            source_timezone: The time zone for the ``source_time``. Required for timestamps with no time zone (i.e. TIMESTAMP_NTZ). Use ``None`` if the timestamps have a time zone (i.e. TIMESTAMP_LTZ). Default is ``None``.

        Note:
            The sequence of the 3 params is different from the SQL function, which two overloads:

              - ``CONVERT_TIMEZONE( <source_tz> , <target_tz> , <source_timestamp_ntz> )``
              - ``CONVERT_TIMEZONE( <target_tz> , <source_timestamp> )``

            The first parameter ``source_tz`` is optional. But in Python an optional argument shouldn't be placed at the first.
            So ``source_timezone`` is after ``source_time``.

        Example:
            >>> import datetime
            >>> from dateutil import tz
            >>> datetime_with_tz = datetime.datetime(2022, 4, 6, 9, 0, 0, tzinfo=tz.tzoffset("myzone", -3600*7))
            >>> datetime_with_no_tz = datetime.datetime(2022, 4, 6, 9, 0, 0)
            >>> df = session.create_dataframe([[datetime_with_tz, datetime_with_no_tz]], schema=["a", "b"])
            >>> result = df.select(convert_timezone(lit("UTC"), col("a")), convert_timezone(lit("UTC"), col("b"), lit("Asia/Shanghai"))).collect()
            >>> result[0][0]
            datetime.datetime(2022, 4, 6, 16, 0, tzinfo=<UTC>)
            >>> result[0][1]
            datetime.datetime(2022, 4, 6, 1, 0)
    Nconvert_timezonery   )r9   r%   r   )r   r   r   rQ   	source_tz	target_tzsource_time_to_convertrn   s           rV   r   r     s    N & 	(:; 
 0BCI+K9KL  	k*$,r?2CE	
   "
 	
  rY   c                 6    t        | d      }t        d||      S )a  Uses HyperLogLog to return an approximation of the distinct cardinality of the input (i.e. HLL(col1, col2, ... )
    returns an approximation of COUNT(DISTINCT col1, col2, ... )).

    Example::
        >>> df = session.create_dataframe([[1, 2], [3, 4], [5, 6]], schema=["a", "b"])
        >>> df.select(approx_count_distinct("a").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |3         |
        ------------
        <BLANKLINE>

    approx_count_distinctr}   r   r   s      rV   r   r   [  s!      	q12A11	JJrY   c                 6    t        | d      }t        d||      S )a  Returns the average of non-NULL records. If all records inside a group are NULL,
    the function returns NULL.

    Example::
        >>> df = session.create_dataframe([[1], [2], [2]], schema=["d"])
        >>> df.select(avg(df.d).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |1.666667  |
        ------------
        <BLANKLINE>
    avgr}   r   r   s      rV   r   r   o       	q% A%i88rY   column1column2c                 P    t        | d      }t        |d      }t        d|||      S )a  Returns the correlation coefficient for non-null pairs in a group.

    Example:
        >>> df = session.create_dataframe([[1, 2], [1, 2], [4, 5], [2, 3], [3, None], [4, None], [6,4]], schema=["a", "b"])
        >>> df.select(corr(col("a"), col("b")).alias("result")).show()
        ---------------------
        |"RESULT"           |
        ---------------------
        |0.813681508328809  |
        ---------------------
        <BLANKLINE>
    corrr}   r   )r   r   rQ   c1c2s        rV   r   r     s-      
	(B		(B&"bI>>rY   c                     |rt        d| g      nd}t        | d      }t        |j                  t              rt        d      n|j                  }t        d|||      S )aI  Returns either the number of non-NULL records for the specified columns, or the
    total number of records.

    Example:
        >>> df = session.create_dataframe([[1], [None], [3], [4], [None]], schema=["a"])
        >>> df.select(count(col("a")).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |3         |
        ------------
        <BLANKLINE>
        >>> df.select(count("*").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |5         |
        ------------
        <BLANKLINE>
    countNr   ry   )r%   r9   
isinstance_expressionr   r   r   )r   rQ   rn   r   exprs        rV   r   r     sP    . 09
gs
+dCq'"A#AMM4871:ammD'4cYGGrY   r}   colsc           	          |D cg c]  }t        |d       }}| rt        d|      nd}t        t        d|D cg c]  }|j                   c}d      ||       S c c}w c c}w )aH  Returns either the number of non-NULL distinct records for the specified columns,
    or the total number of the distinct records.

    Example:

        >>> df = session.create_dataframe([[1, 2], [1, 2], [3, None], [2, 3], [3, None], [4, None]], schema=["a", "b"])
        >>> df.select(count_distinct(col("a"), col("b")).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |2         |
        ------------
        <BLANKLINE>
        >>> #  The result should be 2 for {[1,2],[2,3]} since the rest are either duplicate or NULL records
    count_distinctNr   T)is_distinctry   )r9   r%   r6   r   r   )rQ   r   r   csrn   s        rV   r   r     sj    " 8<	<!.,
-	<B	<7@
.
3dC7B$?qQ]]$?TR  
= %@s
   AA!c                 P    t        | d      }t        |d      }t        d|||      S )a  Returns the population covariance for non-null pairs in a group.

    Example:
        >>> from snowflake.snowpark.types import DecimalType
        >>> df = session.create_dataframe([[1, 2], [1, 2], [4, 5], [2, 3], [3, None], [4, None], [6,4]], schema=["a", "b"])
        >>> df.select(covar_pop(col("a"), col("b")).cast(DecimalType(scale=3)).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |1.840     |
        ------------
        <BLANKLINE>
    	covar_popr}   r   r   r   rQ   col1col2s        rV   r   r     s-    " ';/D';/D+tTYGGrY   c                 P    t        | d      }t        |d      }t        d|||      S )a  Returns the sample covariance for non-null pairs in a group.

    Example:
        >>> from snowflake.snowpark.types import DecimalType
        >>> df = session.create_dataframe([[1, 2], [1, 2], [4, 5], [2, 3], [3, None], [4, None], [6,4]], schema=["a", "b"])
        >>> df.select(covar_samp(col("a"), col("b")).cast(DecimalType(scale=3)).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |2.300     |
        ------------
        <BLANKLINE>
    
covar_sampr}   r   r   s        rV   r   r     s-    " '<0D'<0D,diHHrY   c                     t        | }d}| r)t        j                         }| rt        |dg|r|n| nd t	        |      dk(  rt        |d   t        t        f      r|d   }t        |ddi}||_	        |S )ai  Transforms multiple column pairs into a single map :class:`~snowflake.snowpark.Column` where each pair of
    columns is treated as a key-value pair in the resulting map.

    Args:
        *cols: A variable number of column names or :class:`~snowflake.snowpark.Column` objects that can also be
               expressed as a list of columns.
               The function expects an even number of arguments, where each pair of arguments represents a key-value
               pair for the map.

    Returns:
        A :class:`~snowflake.snowpark.Column` where each row contains a map created from the provided column pairs.

    Example:
        >>> from snowflake.snowpark.functions import create_map
        >>> df = session.create_dataframe([("Paris", "France"), ("Tokyo", "Japan")], ("city", "country"))
        >>> df.select(create_map("city", "country").alias("map")).show()
        -----------------------
        |"MAP"                |
        -----------------------
        |{                    |
        |  "Paris": "France"  |
        |}                    |
        |{                    |
        |  "Tokyo": "Japan"   |
        |}                    |
        -----------------------
        <BLANKLINE>

        >>> df.select(create_map([df.city, df.country]).alias("map")).show()
        -----------------------
        |"MAP"                |
        -----------------------
        |{                    |
        |  "Paris": "France"  |
        |}                    |
        |{                    |
        |  "Tokyo": "Japan"   |
        |}                    |
        -----------------------
        <BLANKLINE>
    N
create_mapr   r   rQ   F)
r1   ro   rp   r    lenr   listtupleobject_construct_keep_nullrz   )rQ   r   variadicrn   rW   s        rV   r   r     s    \ *40H
Cjjl  		
(0d	
  4yA~*T!WtUm<Aw
$d
<e
<CCHJrY   c                 6    t        | d      }t        d||      S )a  
    Returns the population excess kurtosis of non-NULL records. If all records
    inside a group are NULL, the function returns NULL.

    Example::

        >>> from snowflake.snowpark.functions import kurtosis
        >>> df = session.create_dataframe([1, 3, 10, 1, 3], schema=["x"])
        >>> df.select(kurtosis("x").as_("x")).collect()
        [Row(X=Decimal('3.613736609956'))]
    kurtosisr}   r   r   s      rV   r   r   :  s     	q*%A*a9==rY   c                 6    t        | d      }t        d||      S )aE  
    Returns the maximum value for the records in a group. NULL values are ignored
    unless all the records are NULL, in which case a NULL value is returned.

    Example::

        >>> df = session.create_dataframe([1, 3, 10, 1, 3], schema=["x"])
        >>> df.select(max("x").as_("x")).collect()
        [Row(X=10)]
    maxr}   r   r   s      rV   r   r   K       	q% A%i88rY   c                 r    t        | d      }t        |d      }|rt        d|g      |_        |S d|_        |S )a  
    Return the average for the specific numeric columns. Alias of :func:`avg`.

    Example::

        >>> df = session.create_dataframe([1, 3, 10, 1, 3], schema=["x"])
        >>> df.select(mean("x").as_("x")).collect()
        [Row(X=Decimal('3.600000'))]
    meanFr}   N)r9   r   r%   rz   )r   rQ   r   anss       rV   r   r   [  sD     	q&!A
a5
!C3<"6A3/CHJ CGCHJrY   c                 6    t        | d      }t        d||      S )aU  
    Returns the median value for the records in a group. NULL values are ignored
    unless all the records are NULL, in which case a NULL value is returned.

    Example::

        >>> df = session.create_dataframe([1, 3, 10, 1, 3], schema=["x"])
        >>> df.select(median("x").as_("x")).collect()
        [Row(X=Decimal('3.000'))]
    medianr}   r   r   s      rV   r   r   l  s     	q(#A(A;;rY   c                 6    t        | d      }t        d||      S )aD  
    Returns the minimum value for the records in a group. NULL values are ignored
    unless all the records are NULL, in which case a NULL value is returned.

    Example::

        >>> df = session.create_dataframe([1, 3, 10, 1, 3], schema=["x"])
        >>> df.select(min("x").as_("x")).collect()
        [Row(X=1)]
    minr}   r   r   s      rV   r   r   |  r   rY   c                 6    t        | d      }t        d||      S )aT  
    Returns the most frequent value for the records in a group. NULL values are ignored.
    If all the values are NULL, or there are 0 rows, then the function returns NULL.

    Example::

        >>> df = session.create_dataframe([1, 3, 10, 1, 4], schema=["x"])
        >>> df.select(mode("x").as_("x")).collect()
        [Row(X=1)]
    moder}   r   r   s      rV   r   r          	q&!A&!y99rY   c                 6    t        | d      }t        d||      S )a  Returns the sample skewness of non-NULL records. If all records inside a group
    are NULL, the function returns NULL.

    Example::
        >>> from snowflake.snowpark.types import DecimalType
        >>> df = session.create_dataframe(
        ...     [10, 10, 20, 25, 30],
        ...     schema=["a"]
        ... ).select(skew("a").cast(DecimalType(scale=4)))
        >>> df.collect()
        [Row(CAST (SKEW("A") AS NUMBER(38, 4))=Decimal('0.0524'))]
    skewr}   r   r   s      rV   r   r     s     	q&!A&!y99rY   c                 6    t        | d      }t        d||      S )a  Returns the sample standard deviation (square root of sample variance) of
    non-NULL values. If all records inside a group are NULL, returns NULL.

    Example::
        >>> from snowflake.snowpark.types import DecimalType
        >>> df = session.create_dataframe(
        ...     [4, 9],
        ...     schema=["N"],
        ... ).select(stddev(col("N")).cast(DecimalType(scale=4)))
        >>> df.collect()
        [Row(CAST (STDDEV("N") AS NUMBER(38, 4))=Decimal('3.5355'))]
    stddevr}   r   r   s      rV   r   r     s     	q(#A(A;;rY   c                 6    t        | d      }t        d||      S )a  Returns the sample standard deviation (square root of sample variance) of
    non-NULL values. If all records inside a group are NULL, returns NULL. Alias of
    :func:`stddev`.

    Example::
        >>> from snowflake.snowpark.types import DecimalType
        >>> df = session.create_dataframe(
        ...     [4, 9],
        ...     schema=["N"],
        ... ).select(stddev_samp(col("N")).cast(DecimalType(scale=4)))
        >>> df.collect()
        [Row(CAST (STDDEV_SAMP("N") AS NUMBER(38, 4))=Decimal('3.5355'))]
    stddev_sampr}   r   r   s      rV   r   r     s     	q-(A-i@@rY   c                 6    t        | d      }t        d||      S )am  Returns the population standard deviation (square root of variance) of non-NULL
    values. If all records inside a group are NULL, returns NULL.

    Example::
        >>> df = session.create_dataframe(
        ...     [4, 9],
        ...     schema=["N"],
        ... ).select(stddev_pop(col("N")))
        >>> df.collect()
        [Row(STDDEV_POP("N")=2.5)]
    
stddev_popr}   r   r   s      rV   r   r     s     	q,'A,Y??rY   c                 6    t        | d      }t        d||      S )a  Returns the sum of non-NULL records in a group. You can use the DISTINCT keyword
    to compute the sum of unique non-null values. If all records inside a group are
    NULL, the function returns NULL.

    Example::
        >>> df = session.create_dataframe(
        ...     [4, 9],
        ...     schema=["N"],
        ... ).select(sum(col("N")))
        >>> df.collect()
        [Row(SUM("N")=13)]
    sumr}   r   r   s      rV   r   r          	q% A%i88rY   c                 \    |rt        d| g      nd}t        | d      }t        d|d||      S )a  Returns the sum of non-NULL distinct records in a group. You can use the
    DISTINCT keyword to compute the sum of unique non-null values. If all records
    inside a group are NULL, the function returns NULL.

    Example::
        >>> df = session.create_dataframe(
        ...     [1, 2, None, 3],
        ...     schema=["N"],
        ... ).select(sum_distinct(col("N")))
        >>> df.collect()
        [Row(SUM( DISTINCT "N")=6)]
    sum_distinctNr   Tr   rz   rQ   r%   r9   r   r   rQ   rn   r   s       rV   r   r     s7     7@
nqc
2TCq.)A%3)TTrY   c                 6    t        | d      }t        d||      S )al  Returns the sample variance of non-NULL records in a group. If all records
    inside a group are NULL, a NULL is returned. For a single row, NULL is returned as sample variance.

    Example::

        >>> df = session.create_dataframe([1, -1, 1, -1, -1], schema=["a"])
        >>> df.select(variance(col("a"))).collect()
        [Row(VARIANCE("A")=Decimal('1.200000'))]

        >>> df = session.create_dataframe([1, None, 2, 3, None, 5, 6], schema=["a"])
        >>> df.select(variance(col("a"))).collect()
        [Row(VARIANCE("A")=Decimal('4.300000'))]

        >>> df = session.create_dataframe([None, None, None], schema=["a"])
        >>> df.select(variance(col("a"))).collect()
        [Row(VARIANCE("A")=None)]

        >>> df = session.create_dataframe([42], schema=["a"])
        >>> df.select(variance(col("a"))).collect()
        [Row(VARIANCE("A")=None)]

    variancer}   r   r   s      rV   r  r    s    0 	q*%A*a9==rY   c                 Z    |rt        d| g      nd}t        | d      }t        d|||      S )a  Returns the sample variance of non-NULL records in a group. If all records
    inside a group are NULL, a NULL is returned. For a single row, NULL is returned as sample variance.
    Alias of :func:`variance`

    Example::

        >>> df = session.create_dataframe([1, -1, 1, -1, -1], schema=["a"])
        >>> df.select(var_samp(col("a"))).collect()
        [Row(VARIANCE("A")=Decimal('1.200000'))]

        >>> df = session.create_dataframe([1, None, 2, 3, None, 5, 6], schema=["a"])
        >>> df.select(var_samp(col("a"))).collect()
        [Row(VARIANCE("A")=Decimal('4.300000'))]

        >>> df = session.create_dataframe([None, None, None], schema=["a"])
        >>> df.select(var_samp(col("a"))).collect()
        [Row(VARIANCE("A")=None)]

        >>> df = session.create_dataframe([42], schema=["a"])
        >>> df.select(var_samp(col("a"))).collect()
        [Row(VARIANCE("A")=None)]

    var_sampNr  ry   r  r  s       rV   r  r  '  s4    4 3<
j1#
.Cq*%A*acYGGrY   c                 6    t        | d      }t        d||      S )ap  Returns the population variance of non-NULL records in a group. If all records
    inside a group are NULL, a NULL is returned. The population variance of a single row is 0.0.

    Example::

        >>> df = session.create_dataframe([1, -1, 1, -1, -1], schema=["a"])
        >>> df.select(var_pop(col("a"))).collect()
        [Row(VAR_POP("A")=Decimal('0.960000'))]

        >>> df = session.create_dataframe([1, None, 2, 3, None, 5, 6], schema=["a"])
        >>> df.select(var_pop(col("a"))).collect()
        [Row(VAR_POP("A")=Decimal('3.440000'))]

        >>> df = session.create_dataframe([None, None, None], schema=["a"])
        >>> df.select(var_pop(col("a"))).collect()
        [Row(VAR_POP("A")=None)]

        >>> df = session.create_dataframe([42], schema=["a"])
        >>> df.select(var_pop(col("a"))).collect()
        [Row(VAR_POP("A")=Decimal('0.000000'))]

    var_popr}   r   r   s      rV   r  r  G  s    0 	q)$A)Q)<<rY   
percentilec                 t    t        | d      }|rt        d||g      nd}t        d|t        |d      ||      S )a  Returns an approximated value for the desired percentile. This function uses the t-Digest algorithm.

    Example::
        >>> df = session.create_dataframe([0,1,2,3,4,5,6,7,8,9], schema=["a"])
        >>> df.select(approx_percentile("a", 0.5).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |4.5       |
        ------------
        <BLANKLINE>
    approx_percentileNFr}   ry   r9   r%   r   rj   )rW   r	  rQ   r   rn   s        rV   r  r  c  sT      	s/0A FO/!ZATX  	J%( rY   c                 6    t        | d      }t        d||      S )a_  Returns the internal representation of the t-Digest state (as a JSON object) at the end of aggregation.
    This function uses the t-Digest algorithm.

    Example::
        >>> df = session.create_dataframe([1,2,3,4,5], schema=["a"])
        >>> df.select(approx_percentile_accumulate("a").alias("result")).show()
        ------------------------------
        |"RESULT"                    |
        ------------------------------
        |{                           |
        |  "state": [                |
        |    1.000000000000000e+00,  |
        |    1.000000000000000e+00,  |
        |    2.000000000000000e+00,  |
        |    1.000000000000000e+00,  |
        |    3.000000000000000e+00,  |
        |    1.000000000000000e+00,  |
        |    4.000000000000000e+00,  |
        |    1.000000000000000e+00,  |
        |    5.000000000000000e+00,  |
        |    1.000000000000000e+00   |
        |  ],                        |
        |  "type": "tdigest",        |
        |  "version": 1              |
        |}                           |
        ------------------------------
        <BLANKLINE>
    approx_percentile_accumulater}   r   rW   rQ   r   s      rV   r  r    s!    < 	s:;A8!yQQrY   statec                 t    t        | d      }|rt        d||g      nd}t        d|t        |d      ||      S )a^  Returns the desired approximated percentile value for the specified t-Digest state.
    APPROX_PERCENTILE_ESTIMATE(APPROX_PERCENTILE_ACCUMULATE(.)) is equivalent to
    APPROX_PERCENTILE(.).

    Example::
        >>> df = session.create_dataframe([1,2,3,4,5], schema=["a"])
        >>> df_accu = df.select(approx_percentile_accumulate("a").alias("app_percentile_accu"))
        >>> df_accu.select(approx_percentile_estimate("app_percentile_accu", 0.5).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |3.0       |
        ------------
        <BLANKLINE>
    approx_percentile_estimateNFr}   ry   r  )r  r	  rQ   r   rn   s        rV   r  r    sT    & 	u:;A  	81j/J 
 $	J%( rY   c                 6    t        | d      }t        d||      S )a%  Combines (merges) percentile input states into a single output state.
    This allows scenarios where APPROX_PERCENTILE_ACCUMULATE is run over horizontal partitions
    of the same table, producing an algorithm state for each table partition. These states can
    later be combined using APPROX_PERCENTILE_COMBINE, producing the same output state as a
    single run of APPROX_PERCENTILE_ACCUMULATE over the entire table.

    Example::
        >>> df1 = session.create_dataframe([1,2,3,4,5], schema=["a"])
        >>> df2 = session.create_dataframe([6,7,8,9,10], schema=["b"])
        >>> df_accu1 = df1.select(approx_percentile_accumulate("a").alias("app_percentile_accu"))
        >>> df_accu2 = df2.select(approx_percentile_accumulate("b").alias("app_percentile_accu"))
        >>> df_accu1.union(df_accu2).select(approx_percentile_combine("app_percentile_accu").alias("result")).show()
        ------------------------------
        |"RESULT"                    |
        ------------------------------
        |{                           |
        |  "state": [                |
        |    1.000000000000000e+00,  |
        |    1.000000000000000e+00,  |
        |    2.000000000000000e+00,  |
        |    1.000000000000000e+00,  |
        |    3.000000000000000e+00,  |
        |    1.000000000000000e+00,  |
        |    4.000000000000000e+00,  |
        |    1.000000000000000e+00,  |
        |    5.000000000000000e+00,  |
        |    1.000000000000000e+00,  |
        |    6.000000000000000e+00,  |
        |    1.000000000000000e+00,  |
        |    7.000000000000000e+00,  |
        |    1.000000000000000e+00,  |
        |    8.000000000000000e+00,  |
        |    1.000000000000000e+00,  |
        |    9.000000000000000e+00,  |
        |    1.000000000000000e+00,  |
        |    1.000000000000000e+01,  |
        |    1.000000000000000e+00   |
        |  ],                        |
        |  "type": "tdigest",        |
        |  "version": 1              |
        |}                           |
        ------------------------------
        <BLANKLINE>
    approx_percentile_combiner}   r   )r  rQ   r   s      rV   r  r    s"    \ 	u9:A5qINNrY   z3snowflake.snowpark.table_function.TableFunctionCallc                     |rt        d| g      nd}t        | d      } t        j                  j                  j                  | t        dd            }|j                  d       ||_        |S )aY  Flattens a given array or map type column into individual rows. The default
    column name for the output column in case of array input column is ``VALUE``,
    and is ``KEY`` and ``VALUE`` in case of map input column.

    Examples::
        >>> df = session.create_dataframe([[1, [1, 2, 3], {"Ashi Garami": "Single Leg X"}, "Kimura"],
        ...                                [2, [11, 22], {"Sankaku": "Triangle"}, "Coffee"]],
        ...                                schema=["idx", "lists", "maps", "strs"])
        >>> df.select(df.idx, explode(df.lists)).sort(col("idx")).show()
        -------------------
        |"IDX"  |"VALUE"  |
        -------------------
        |1      |1        |
        |1      |2        |
        |1      |3        |
        |2      |11       |
        |2      |22       |
        -------------------
        <BLANKLINE>

        >>> df.select(df.strs, explode(df.maps)).sort(col("strs")).show()
        -----------------------------------------
        |"STRS"  |"KEY"        |"VALUE"         |
        -----------------------------------------
        |Coffee  |Sankaku      |"Triangle"      |
        |Kimura  |Ashi Garami  |"Single Leg X"  |
        -----------------------------------------
        <BLANKLINE>

        >>> df.select(explode(col("lists")).alias("uno")).sort(col("uno")).show()
        ---------
        |"UNO"  |
        ---------
        |1      |
        |2      |
        |3      |
        |11     |
        |22     |
        ---------
        <BLANKLINE>

        >>> df.select(explode('maps').as_("primo", "secundo")).sort(col("primo")).show()
        --------------------------------
        |"PRIMO"      |"SECUNDO"       |
        --------------------------------
        |Ashi Garami  |"Single Leg X"  |
        |Sankaku      |"Triangle"      |
        --------------------------------
        <BLANKLINE>
    explodeNFr}   zfunctions.explode	r%   r9   	snowflakesnowparktable_function_ExplodeFunctionCallrj   _set_api_call_sourcerz   rW   rQ   rn   	func_calls       rV   r  r    sj    n 4=
i#
/$C
i
(C""11FFS%(I ""#67INrY   c                     |rt        d| g      nd}t        | d      } t        j                  j                  j                  | t        dd            }|j                  d       ||_        |S )a/  Flattens a given array or map type column into individual rows. Unlike :func:`explode`,
    if array or map is empty, null or empty, then null values are produced. The default column
    name for the output column in case of array input column is ``VALUE``, and is ``KEY`` and
    ``VALUE`` in case of map input column.

    Args:
        col: Column object or string name of the desired column

    Examples::
        >>> df = session.create_dataframe([[1, [1, 2, 3], {"Ashi Garami": "Single Leg X"}],
        ...                                [2, [11, 22], {"Sankaku": "Triangle"}],
        ...                                [3, [], {}]],
        ...                                schema=["idx", "lists", "maps"])
        >>> df.select(df.idx, explode_outer(df.lists)).sort(col("idx")).show()
        -------------------
        |"IDX"  |"VALUE"  |
        -------------------
        |1      |1        |
        |1      |2        |
        |1      |3        |
        |2      |11       |
        |2      |22       |
        |3      |NULL     |
        -------------------
        <BLANKLINE>

        >>> df.select(df.idx, explode_outer(df.maps)).sort(col("idx")).show()
        ----------------------------------------
        |"IDX"  |"KEY"        |"VALUE"         |
        ----------------------------------------
        |1      |Ashi Garami  |"Single Leg X"  |
        |2      |Sankaku      |"Triangle"      |
        |3      |NULL         |NULL            |
        ----------------------------------------
        <BLANKLINE>

    See Also:
        :func:`explode`
    explode_outerNTFr}   zfunctions.explode_outerr  r  s       rV   r   r   >  sk    X :C
ou
5C
o
.C""11FFS'I ""#<=INrY   pathouter	recursiver   )objectarraybothc           
          |rt        d| ||||g      nd}t        | d      } t        j                  j                  j                  d| t        |      t        |      t        |      t        |      d      }|j                  d       ||_        |S )a  FLATTEN explodes compound values into multiple rows. This table function takes a
    VARIANT, OBJECT, or ARRAY column and produces a lateral view.

    Args:
        col: Column object or string name of the desired column.
        path: The path to the element within VARIANT data structure which needs to be
            flattened. Defaults to "".
        outer: When ``False``, any input rows that cannot be expanded are completely
            omitted from the output. When ``True``, exactly one row s generated for
            zero-row expansions. Defaults to ``False``.
        recursive: When ``False``, only the reference by ``path`` is expanded. When
            ``True``, the expansion is performed for all sub-elements recursively.
            Defaults to ``False``.
        mode: Specifies whether only objects, arrays, or both should be flattened.
            Defaults to "both".

    Examples::
        >>> df = session.create_dataframe([[1, [1, 2, 3], {"Ashi Garami": ["X", "Leg Entanglement"]}, "Kimura"],
        ...                                [2, [11, 22], {"Sankaku": ["Triangle"]}, "Coffee"],
        ...                                [3, [], {}, "empty"]],
        ...                                schema=["idx", "lists", "maps", "strs"])
        >>> df.select(df.idx, flatten(df.lists, outer=True)).select("idx", "value").sort("idx").show()
        -------------------
        |"IDX"  |"VALUE"  |
        -------------------
        |1      |1        |
        |1      |2        |
        |1      |3        |
        |2      |11       |
        |2      |22       |
        |3      |NULL     |
        -------------------
        <BLANKLINE>

        >>> df.select(df.strs, flatten(df.maps, recursive=True)).select("strs", "key", "value").where("key is not NULL").sort("strs").show()
        -----------------------------------------------
        |"STRS"  |"KEY"        |"VALUE"               |
        -----------------------------------------------
        |Coffee  |Sankaku      |[                     |
        |        |             |  "Triangle"          |
        |        |             |]                     |
        |Kimura  |Ashi Garami  |[                     |
        |        |             |  "X",                |
        |        |             |  "Leg Entanglement"  |
        |        |             |]                     |
        -----------------------------------------------
        <BLANKLINE>

        >>> df.select(df.strs, flatten(df.maps, recursive=True)).select("strs", "key", "value").where("key is NULL").sort("strs", "value").show()
        ---------------------------------------
        |"STRS"  |"KEY"  |"VALUE"             |
        ---------------------------------------
        |Coffee  |NULL   |"Triangle"          |
        |Kimura  |NULL   |"Leg Entanglement"  |
        |Kimura  |NULL   |"X"                 |
        ---------------------------------------
        <BLANKLINE>

    See Also:
        - :func:`explode`
        - `Flatten <https://docs.snowflake.com/en/sql-reference/functions/flatten>`_
    flattenNF)inputr!  r"  r#  r   rQ   zfunctions.flatten)	r%   r9   r  r  r  TableFunctionCallrj   r  rz   )rW   r!  r"  r#  r   rQ   rn   r  s           rV   r(  r(  v  s    T  	IT5)T'JK  i
(C""11CCY%ji.Y D I ""#67INrY   c                 \    |D cg c]  }t        |d       }}t        dg|d| iS c c}w )a  
    Describes which of a list of expressions are grouped in a row produced by a GROUP BY query.

    :func:`grouping_id` is an alias of :func:`grouping`.

    Example::
        >>> from snowflake.snowpark import GroupingSets
        >>> df = session.create_dataframe([[1, 2, 3], [4, 5, 6]],schema=["a", "b", "c"])
        >>> grouping_sets = GroupingSets([col("a")], [col("b")], [col("a"), col("b")])
        >>> df.group_by_grouping_sets(grouping_sets).agg([count("c").alias("count_c"), grouping("a").alias("ga"), grouping("b").alias("gb"), grouping("a", "b").alias("gab")]).sort("a", "b").collect()
        [Row(A=None, B=2, COUNT_C=1, GA=1, GB=0, GAB=2), Row(A=None, B=5, COUNT_C=1, GA=1, GB=0, GAB=2), Row(A=1, B=None, COUNT_C=1, GA=0, GB=1, GAB=1), Row(A=1, B=2, COUNT_C=1, GA=0, GB=0, GAB=0), Row(A=4, B=None, COUNT_C=1, GA=0, GB=1, GAB=1), Row(A=4, B=5, COUNT_C=1, GA=0, GB=0, GAB=0)]
    groupingrQ   r   rQ   r   r   columnss       rV   r,  r,    s8    & 7;;~a,;G;*DwD)DD <   )c                 \    |D cg c]  }t        |d       }}t        dg|d| iS c c}w )a  Returns the first non-NULL expression among its arguments, or NULL if all its
    arguments are NULL.

    Example::

        >>> df = session.create_dataframe([[1, 2, 3], [None, 2, 3], [None, None, 3], [None, None, None]], schema=['a', 'b', 'c'])
        >>> df.select(df.a, df.b, df.c, coalesce(df.a, df.b, df.c).as_("COALESCE")).show()
        -----------------------------------
        |"A"   |"B"   |"C"   |"COALESCE"  |
        -----------------------------------
        |1     |2     |3     |1           |
        |NULL  |2     |3     |2           |
        |NULL  |NULL  |3     |3           |
        |NULL  |NULL  |NULL  |NULL        |
        -----------------------------------
        <BLANKLINE>
    coalescerQ   r   )rQ   r   exr   s       rV   r1  r1    s8    & 344BJ	'4A4*>q>I>> 	5r/  c                 r    |rt        d| g      nd}t        | d      }|j                  d      }||_        |S )aN  
    Return true if the value in the column is not a number (NaN).

    Example::

        >>> import math
        >>> df = session.create_dataframe([1.1, math.nan, 2.3], schema=["a"])
        >>> df.select(equal_nan(df["a"]).alias("equal_nan")).collect()
        [Row(EQUAL_NAN=False), Row(EQUAL_NAN=True), Row(EQUAL_NAN=False)]
    	equal_nanNFr}   )r%   r9   r4  rz   r   rQ   rn   r   r   s        rV   r4  r4    s?     4=
kA3
/$Cq+&A
+++
&CCHJrY   c                 r    |rt        d| g      nd}t        | d      }|j                  d      }||_        |S )aU  
    Return true if the value in the column is null.

    Example::

        >>> from snowflake.snowpark.functions import is_null
        >>> df = session.create_dataframe([1.2, float("nan"), None, 1.0], schema=["a"])
        >>> df.select(is_null("a").as_("a")).collect()
        [Row(A=False), Row(A=False), Row(A=True), Row(A=False)]
    is_nullNFr}   )r%   r9   r7  rz   r5  s        rV   r7  r7    s?     2;
i!
-Cq)$A
))e)
$CCHJrY   c                 T    |rt        d| g      nd}t        | d      }| }||_        |S )a^  Returns the negation of the value in the column (equivalent to a unary minus).

    Example::

        >>> df = session.create_dataframe([[1]], schema=["a"])
        >>> df.select(negate(col("a").alias("result"))).show()
        ------------
        |"RESULT"  |
        ------------
        |-1        |
        ------------
        <BLANKLINE>
    negateNr%   r9   rz   r5  s        rV   r9  r9  /  s6      1:
h
,tCq(#A"CCHJrY   c                 T    |rt        d| g      nd}t        | d      }| }||_        |S )a=  Returns the inverse of a boolean expression.

    Example::

        >>> df = session.create_dataframe([[True]], schema=["a"])
        >>> df.select(not_(col("a").alias("result"))).show()
        ------------
        |"RESULT"  |
        ------------
        |False     |
        ------------
        <BLANKLINE>
    not_Nr:  r5  s        rV   r<  r<  G  s6      /8
fqc
*TCq&!A"CCHJrY   seedc                 |    |rt        d| g n| g      nd}| | nt        dd      }t        dt        |      ||      S )zEach call returns a pseudo-random 64-bit integer.

    Example::
        >>> df = session.sql("select 1")
        >>> df = df.select(random(123).alias("result"))
    randomNl         l    ry   )r%   r   r   r   )r=  rQ   rn   ss       rV   r?  r?  _  sM      	HDLbtfE   gh	&BA(GAJSINNrY   min_max_genc           	          |rt        d| ||g      nd}d } ||       } ||      }t        |t        t        f      rt	        |d      nt        |d      }t        d|||d||      S )a+  
    Returns a uniformly random number.

    Example::
        >>> import datetime
        >>> df = session.create_dataframe(
        ...     [[1]],
        ...     schema=["a"],
        ... )
        >>> df.select(uniform(1, 100, col("a")).alias("UNIFORM")).collect()
        [Row(UNIFORM=62)]
    uniformNc                     t        | t              rt        | d      S t        | t              r&t        | d      j	                  t               d      S t        | d      S )NFr}   rE  )r   intrj   floatcastr?   r9   )limits    rV   convert_limit_to_colz%uniform.<locals>.convert_limit_to_col  sO    eS!u..u%u.33IK53QQeY//rY   Fr}   Tis_data_generatorrz   rQ   r%   r   rG  rH  rj   r9   r   )	rA  rB  rC  rQ   rn   rK  min_colmax_colgen_cols	            rV   rE  rE  s  s    & @I
i$c):
;dC0 #4(G"4(G cC<( 	C5!C+ 
  rY   signc                 V    |rt        d| g      nd}t        dt        |       d||      S )au  Returns a sequence of monotonically increasing integers, with wrap-around
    which happens after largest representable integer of integer width 1 byte.

    Args:
        sign: When 0, the sequence continues at 0 after wrap-around. When 1, the sequence
            continues at smallest representable 1 byte integer. Defaults to 0.

    See Also:
        - :meth:`Session.generator`, which can be used to generate in tandem with `seq1` to
            generate sequences.

    Example::
        >>> df = session.generator(seq1(0), rowcount=3)
        >>> df.collect()
        [Row(SEQ1(0)=0), Row(SEQ1(0)=1), Row(SEQ1(0)=2)]
    seq1NTrL  r%   r   r   rR  rQ   rn   s      rV   rT  rT    3    $ 2;
ftf
-CC9 rY   c                 V    |rt        d| g      nd}t        dt        |       d||      S )au  Returns a sequence of monotonically increasing integers, with wrap-around
    which happens after largest representable integer of integer width 2 byte.

    Args:
        sign: When 0, the sequence continues at 0 after wrap-around. When 1, the sequence
            continues at smallest representable 2 byte integer. Defaults to 0.

    See Also:
        - :meth:`Session.generator`, which can be used to generate in tandem with `seq2` to
            generate sequences.

    Example::
        >>> df = session.generator(seq2(0), rowcount=3)
        >>> df.collect()
        [Row(SEQ2(0)=0), Row(SEQ2(0)=1), Row(SEQ2(0)=2)]
    seq2NTrL  rU  rV  s      rV   rY  rY    rW  rY   c                 V    |rt        d| g      nd}t        dt        |       d||      S )au  Returns a sequence of monotonically increasing integers, with wrap-around
    which happens after largest representable integer of integer width 4 byte.

    Args:
        sign: When 0, the sequence continues at 0 after wrap-around. When 1, the sequence
            continues at smallest representable 4 byte integer. Defaults to 0.

    See Also:
        - :meth:`Session.generator`, which can be used to generate in tandem with `seq4` to
            generate sequences.

    Example::
        >>> df = session.generator(seq4(0), rowcount=3)
        >>> df.collect()
        [Row(SEQ4(0)=0), Row(SEQ4(0)=1), Row(SEQ4(0)=2)]
    seq4NTrL  rU  rV  s      rV   r[  r[    rW  rY   c                 V    |rt        d| g      nd}t        dt        |       d||      S )au  Returns a sequence of monotonically increasing integers, with wrap-around
    which happens after largest representable integer of integer width 8 byte.

    Args:
        sign: When 0, the sequence continues at 0 after wrap-around. When 1, the sequence
            continues at smallest representable 8 byte integer. Defaults to 0.

    See Also:
        - :meth:`Session.generator`, which can be used to generate in tandem with `seq8` to
            generate sequences.

    Example::
        >>> df = session.generator(seq8(0), rowcount=3)
        >>> df.collect()
        [Row(SEQ8(0)=0), Row(SEQ8(0)=1), Row(SEQ8(0)=2)]
    seq8NTrL  rU  rV  s      rV   r]  r]    rW  rY   c                 6    t        | d      }t        d||      S )zConverts an input expression to a boolean.

    Example::
        >>> df = session.create_dataframe(['yes', 'no'], schema=['a'])
        >>> df.select(to_boolean(col('a')).as_('ans')).collect()
        [Row(ANS=True), Row(ANS=False)]
    
to_booleanr}   r   r   s      rV   r_  r_         	q,'A,Y??rY   	precisionc           	          |rt        d| ||g      nd}t        | d      }t        d|t        |d      t        |d      ||      S )a  Converts an input expression to a decimal.

    Example::
        >>> df = session.create_dataframe(['12', '11.3', '-90.12345'], schema=['a'])
        >>> df.select(to_decimal(col('a'), 38, 0).as_('ans')).collect()
        [Row(ANS=12), Row(ANS=11), Row(ANS=-90)]

        >>> df.select(to_decimal(col('a'), 38, 2).as_('ans')).collect()
        [Row(ANS=Decimal('12.00')), Row(ANS=Decimal('11.30')), Row(ANS=Decimal('-90.12'))]
    
to_decimalNFr}   ry   r%   r9   r   rj   )r   ra  r   rQ   rn   r   s         rV   rc  rc    s]      ENL1i*?@SW  	q,'A	I'EU# rY   fmtc                     |rt        d|| gn| |g      nd}t        | d      }|t        |d      nd}|t        d|||      S t        d||||      S )a  Converts an input expression to a decimal.

    Example::
        >>> df = session.create_dataframe(['12', '11.3', '-90.12345'], schema=['a'])
        >>> df.select(to_double(col('a')).as_('ans')).collect()
        [Row(ANS=12.0), Row(ANS=11.3), Row(ANS=-90.12345)]

    Example::
        >>> df = session.create_dataframe(['12+', '11.3+', '90.12-'], schema=['a'])
        >>> df.select(to_double(col('a'), "999.99MI").as_('ans')).collect()
        [Row(ANS=12.0), Row(ANS=11.3), Row(ANS=-90.12)]
    	to_doubleNry   r%   r9   r7   r   )r   re  rQ   rn   r   fmt_cols         rV   rg  rg  +  sz    $  	K!!SJ 
 	q+&A25/nS+.tG ? 	{AC9E KG#SrY   dividenddivisorc                    |rt        d| |g      nd}t        | t        t        f      rt	        | d      nt        | d      }t        |t        t        f      rt	        |d      nt        |d      }t        d||||      S )a  
    Performs division like the division operator (/),
    but returns 0 when the divisor is 0 (rather than reporting an error).

    Example::

        >>> df = session.create_dataframe([1], schema=["a"])
        >>> df.select(div0(df["a"], 1).alias("divided_by_one"), div0(df["a"], 0).alias("divided_by_zero")).collect()
        [Row(DIVIDED_BY_ONE=Decimal('1.000000'), DIVIDED_BY_ZERO=Decimal('0.000000'))]
    div0NFr}   ry   rN  )rj  rk  rQ   rn   dividend_coldivisor_cols         rV   rm  rm  I  s    " ?H
fx&9
:TC he- 	H&Hf-  gU|, 	Gu%GV, 
 ky rY   c                    t        | t        t        f      rt        | d      nt	        | d      }t        |t        t        f      rt        |d      nt	        |d      }|t        |d      z  }|rt        d| |g      |_        |S d|_        |S )a  Performs division like the division operator (/),
    but returns NULL when the divisor is 0 (rather then reporting error).

    Example::

        >>> df = session.create_dataframe([1], schema=["a"])
        >>> df.select(divnull(df["a"], 1).alias("divided_by_one"), divnull(df["a"], 0).alias("divided_by_zero")).collect()
        [Row(DIVIDED_BY_ONE=Decimal('1.000000'), DIVIDED_BY_ZERO=None)]
    Fr}   divnullN)r   rG  rH  rj   r9   
nullifzeror%   rz   )rj  rk  rQ   rn  ro  r   s         rV   rq  rq  j  s    $ he- 	H&Hi0  gU|, 	Gu%GY/ 
 K5A
AC?HI'':; H J OS H JrY   c                 6    t        | d      }t        d||      S )a  Returns NULL if the argument evaluates to 0; otherwise, returns the argument.

    Example::
        >>> df = session.create_dataframe([0, 1], schema=["a"])
        >>> df.select(nullifzero(df["a"]).alias("result")).collect()
        [Row(RESULT=None), Row(RESULT=1)]
    rr  r}   r   r   s      rV   rr  rr    r`  rY   c                 6    t        | d      }t        d||      S )a!  Returns the square-root of a non-negative numeric expression.

    Example::
        >>> df = session.create_dataframe(
        ...     [4, 9],
        ...     schema=["N"],
        ... ).select(sqrt(col("N")))
        >>> df.collect()
        [Row(SQRT("N")=2.0), Row(SQRT("N")=3.0)]
    sqrtr}   r   r   s      rV   ru  ru    r   rY   c                 6    t        | d      }t        d||      S )a@  Returns the absolute value of a numeric expression.

    Example::
        >>> df = session.create_dataframe([[-1]], schema=["a"])
        >>> df.select(abs(col("a")).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |1         |
        ------------
        <BLANKLINE>
    absr}   r   r   s      rV   rw  rw    r   rY   c                 6    t        | d      }t        d||      S )a  Computes the inverse cosine (arc cosine) of its input;
    the result is a number in the interval [-pi, pi].

    Example::
        >>> from snowflake.snowpark.types import DecimalType
        >>> df = session.create_dataframe([[0.5]], schema=["deg"])
        >>> df.select(acos(col("deg")).cast(DecimalType(scale=3)).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |1.047     |
        ------------
        <BLANKLINE>
    acosr}   r   r   s      rV   ry  ry          	q&!A&!y99rY   c                 6    t        | d      }t        d||      S )a  Computes the inverse sine (arc sine) of its input;
    the result is a number in the interval [-pi, pi].

    Example::
        >>> from snowflake.snowpark.types import DecimalType
        >>> df = session.create_dataframe([[1]], schema=["deg"])
        >>> df.select(asin(col("deg")).cast(DecimalType(scale=3)).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |1.571     |
        ------------
        <BLANKLINE>
    asinr}   r   r   s      rV   r|  r|    rz  rY   c                 6    t        | d      }t        d||      S )a  Computes the inverse tangent (arc tangent) of its input;
    the result is a number in the interval [-pi, pi].

    Example::
        >>> from snowflake.snowpark.types import DecimalType
        >>> df = session.create_dataframe([[1]], schema=["deg"])
        >>> df.select(atan(col("deg")).cast(DecimalType(scale=3)).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |0.785     |
        ------------
        <BLANKLINE>
    atanr}   r   r   s      rV   r~  r~    rz  rY   yxc                 P    t        | d      }t        |d      }t        d|||      S )a  Computes the inverse tangent (arc tangent) of its input;
    the result is a number in the interval [-pi, pi].

    Example::
        >>> from snowflake.snowpark.types import DecimalType
        >>> df = session.create_dataframe([[1, 2]], schema=["x", "y"])
        >>> df.select(atan2(df.x, df.y).cast(DecimalType(scale=3)).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |0.464     |
        ------------
        <BLANKLINE>
    atan2r}   r   r  r  rQ   y_colx_cols        rV   r  r    s-      1g&E1g&E'5%9EErY   c                 6    t        | d      }t        d||      S )a'  Returns values from the specified column rounded to the nearest equal or larger
    integer.

    Example::

        >>> df = session.create_dataframe([135.135, -975.975], schema=["a"])
        >>> df.select(ceil(df["a"]).alias("ceil")).collect()
        [Row(CEIL=136.0), Row(CEIL=-975.0)]
    ceilr}   r   r   s      rV   r  r  	       	q&!A&!y99rY   c                 6    t        | d      }t        d||      S )a  Computes the cosine of its argument; the argument should be expressed in radians.

    Example:
        >>> from math import pi
        >>> df = session.create_dataframe([[pi]], schema=["deg"])
        >>> df.select(cos(col("deg")).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |-1.0      |
        ------------
        <BLANKLINE>
    cosr}   r   r   s      rV   r  r  	  r   rY   c                 6    t        | d      }t        d||      S )a|  Computes the hyperbolic cosine of its argument.

    Example:
        >>> from snowflake.snowpark.types import DecimalType
        >>> df = session.create_dataframe([[0]], schema=["deg"])
        >>> df.select(cosh(col("deg")).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |1.0       |
        ------------
        <BLANKLINE>
    coshr}   r   r   s      rV   r  r  -	       	q&!A&!y99rY   c                 6    t        | d      }t        d||      S )ah  
    Computes Euler's number e raised to a floating-point value.

    Example::

        >>> import math
        >>> from snowflake.snowpark.types import IntegerType
        >>> df = session.create_dataframe([0.0, math.log(10)], schema=["a"])
        >>> df.select(exp(df["a"]).cast(IntegerType()).alias("exp")).collect()
        [Row(EXP=1), Row(EXP=10)]
    expr}   r   r   s      rV   r  r  @	  s     	q% A%i88rY   c                 6    t        | d      }t        d||      S )as  
    Computes the factorial of its input. The input argument must be an integer
    expression in the range of 0 to 33.

    Example::

        >>> df = session.create_dataframe([0, 1, 5, 10], schema=["a"])
        >>> df.select(factorial(df["a"]).alias("factorial")).collect()
        [Row(FACTORIAL=1), Row(FACTORIAL=1), Row(FACTORIAL=120), Row(FACTORIAL=3628800)]
    	factorialr}   r   r   s      rV   r  r  Q	       	q+&A+qI>>rY   c                 6    t        | d      }t        d||      S )a2  
    Returns values from the specified column rounded to the nearest equal or
    smaller integer.

    Examples::

        >>> df = session.create_dataframe([135.135, -975.975], schema=["a"])
        >>> df.select(floor(df["a"]).alias("floor")).collect()
        [Row(FLOOR=135.0), Row(FLOOR=-976.0)]
    floorr}   r   r   s      rV   r  r  a	  s     	q'"A'1	::rY   dc                     t        | d      } t        | |d      j                  t               d      }|rt	        d| |g      |_        |S d|_        |S )a  Format numbers to a specific number of decimal places with HALF_TO_EVEN rounding.

    Note:
        1. The data type of the expression must be one of the `data types for a fixed-point number
        <https://docs.snowflake.com/en/sql-reference/data-types-numeric.html#label-data-types-for-fixed-point-numbers>`_.

        2. Data types for floating point numbers (e.g. FLOAT) are not supported with this argument.

        3. If the expression data type is not supported, the expression must be explicitly cast to decimal before calling.

    Example::
            >>> import decimal
            >>> from snowflake.snowpark.functions import format_number
            >>> data = [(1, decimal.Decimal(3.14159)), (2, decimal.Decimal(2.71828)), (3, decimal.Decimal(1.41421))]
            >>> df = session.createDataFrame(data, ["id", "value"])
            >>> df.select("id",format_number("value",2).alias("value")).show()
            ------------------
            |"ID"  |"VALUE"  |
            ------------------
            |1     |3.14     |
            |2     |2.72     |
            |3     |1.41     |
            ------------------
            <BLANKLINE>
    format_numberFr}   N)r9   r   rI  rA   r%   rz   )rW   r  rQ   r   s       rV   r  r  q	  sZ    6 o
.CsA',,Z\U,KA?H 3(;AFH OSAFHrY   c                 6    t        | d      }t        d||      S )a  Computes the sine of its argument; the argument should be expressed in radians.

    Example::
        >>> from snowflake.snowpark.types import DecimalType
        >>> df = session.generator(seq1(0), rowcount=3).select(sin(seq1(0)).cast(DecimalType(scale=4)))
        >>> df.collect()
        [Row(CAST (SIN(SEQ1(0)) AS NUMBER(38, 4))=Decimal('0.0000')), Row(CAST (SIN(SEQ1(0)) AS NUMBER(38, 4))=Decimal('0.8415')), Row(CAST (SIN(SEQ1(0)) AS NUMBER(38, 4))=Decimal('0.9093'))]
    sinr}   r   r   s      rV   r  r  	  s     	q% A%i88rY   c                 6    t        | d      }t        d||      S )a  Computes the hyperbolic sine of its argument.

    Example::
        >>> from snowflake.snowpark.types import DecimalType
        >>> df = session.generator(seq1(0), rowcount=3).select(sinh(seq1(0)).cast(DecimalType(scale=4)))
        >>> df.collect()
        [Row(CAST (SINH(SEQ1(0)) AS NUMBER(38, 4))=Decimal('0.0000')), Row(CAST (SINH(SEQ1(0)) AS NUMBER(38, 4))=Decimal('1.1752')), Row(CAST (SINH(SEQ1(0)) AS NUMBER(38, 4))=Decimal('3.6269'))]
    sinhr}   r   r   s      rV   r  r  	  s     	q&!A&!y99rY   c                 6    t        | d      }t        d||      S )a  Computes the tangent of its argument; the argument should be expressed in radians.

    Example::
       >>> from snowflake.snowpark.types import DecimalType
       >>> df = session.create_dataframe([0, 1], schema=["N"]).select(
       ...     tan(col("N")).cast(DecimalType(scale=4))
       ... )
       >>> df.collect()
       [Row(CAST (TAN("N") AS NUMBER(38, 4))=Decimal('0.0000')), Row(CAST (TAN("N") AS NUMBER(38, 4))=Decimal('1.5574'))]
    tanr}   r   r   s      rV   r  r  	  r   rY   c                 6    t        | d      }t        d||      S )a  Computes the hyperbolic tangent of its argument.

    Example::
        >>> from snowflake.snowpark.types import DecimalType
        >>> df = session.create_dataframe([0, 1], schema=["N"]).select(
        ...     tanh(col("N").cast(DecimalType(scale=4)))
        ... )
        >>> df.collect()
        [Row(TANH( CAST ("N" AS NUMBER(38, 4)))=0.0), Row(TANH( CAST ("N" AS NUMBER(38, 4)))=0.7615941559557649)]
    tanhr}   r   r   s      rV   r  r  	  r   rY   c                 6    t        | d      }t        d||      S )a  
    Converts radians to degrees.

    Example::

        >>> import math
        >>> from snowflake.snowpark.types import StructType, StructField, DoubleType, IntegerType
        >>> df = session.create_dataframe(
        ...     [math.pi / 3, math.pi, 3 * math.pi],
        ...     schema=StructType([StructField("a", DoubleType())]),
        ... )
        >>> df.select(degrees(col("a")).cast(IntegerType()).alias("DEGREES")).collect()
        [Row(DEGREES=60), Row(DEGREES=180), Row(DEGREES=540)]
    degreesr}   r   r   s      rV   r  r  	  s      	q)$A)Q)<<rY   c                 6    t        | d      }t        d||      S )a  Converts degrees to radians.

    Examples::

        >>> df = session.create_dataframe([[1.111], [2.222], [3.333]], schema=["a"])
        >>> df.select(radians(col("a")).cast("number(38, 5)").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |0.01939   |
        |0.03878   |
        |0.05817   |
        ------------
        <BLANKLINE>
    radiansr}   r   r   s      rV   r  r  	  s    " 	q)$A)Q)<<rY   c                 6    t        | d      }t        d||      S )aR  
    Returns a 32-character hex-encoded string containing the 128-bit MD5 message digest.

     Example::

        >>> df = session.create_dataframe(["a", "b"], schema=["col"]).select(md5("col"))
        >>> df.collect()
        [Row(MD5("COL")='0cc175b9c0f1b6a831c399e269772661'), Row(MD5("COL")='92eb5ffee6ae2fec3ad71c777531578f')]
    md5r}   r   r   s      rV   r  r  	  s     	q% A%i88rY   c                 6    t        | d      }t        d||      S )a`  Returns a 40-character hex-encoded string containing the 160-bit SHA-1 message digest.

    Example::
        >>> df = session.create_dataframe(["a", "b"], schema=["col"]).select(sha1("col"))
        >>> df.collect()
        [Row(SHA1("COL")='86f7e437faa5a7fce15d1ddcb9eaeaea377667b8'), Row(SHA1("COL")='e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98')]
    sha1r}   r   r   s      rV   r  r  
  s     	q&!A&!y99rY   num_bitsc                 j    g d}||vrt        d| d|       t        | d      }t        d|||      S )a  Returns a hex-encoded string containing the N-bit SHA-2 message digest,
    where N is the specified output digest size.

    Example::
        >>> df = session.create_dataframe(["a", "b"], schema=["col"]).select(sha2("col", 256))
        >>> df.collect()
        [Row(SHA2("COL", 256)='ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb'), Row(SHA2("COL", 256)='3e23e8160039594a33894f6564e1b1348bbd7a0088d42c4acb73eeaed59c009d')]
    )r         i  i   z	num_bits z  is not in the permitted values sha2r}   )
ValueErrorr9   r   )r   r  rQ   permitted_valuesr   s        rV   r  r  
  sR     /''z!ABRAST
 	
 	q&!A&!XCCrY   c                 \    |D cg c]  }t        |d       }}t        dg|d| iS c c}w )a  
    Returns a signed 64-bit hash value. Note that HASH never returns NULL, even for NULL inputs.

    Examples::

        >>> import decimal
        >>> df = session.create_dataframe([[10, "10", decimal.Decimal(10), 10.0]], schema=["a", "b", "c", "d"])
        >>> df.select(hash("a").alias("hash_a"), hash("b").alias("hash_b"), hash("c").alias("hash_c"), hash("d").alias("hash_d")).collect()
        [Row(HASH_A=1599627706822963068, HASH_B=3622494980440108984, HASH_C=1599627706822963068, HASH_D=1599627706822963068)]
        >>> df.select(hash(lit(None)).alias("one"), hash(lit(None), lit(None)).alias("two"), hash(lit(None), lit(None), lit(None)).alias("three")).collect()
        [Row(ONE=8817975702393619368, TWO=953963258351104160, THREE=2941948363845684412)]
    hashrQ   r   r-  s       rV   r  r  &
  s8     377Q~a(7G7&@7@i@@ 8r/  c                 6    t        | d      }t        d||      S )a  Returns the ASCII code for the first character of a string. If the string is empty,
    a value of 0 is returned.

    Example::

        >>> df = session.create_dataframe(['!', 'A', 'a', '', 'bcd', None], schema=['a'])
        >>> df.select(df.a, ascii(df.a).as_('ascii')).collect()
        [Row(A='!', ASCII=33), Row(A='A', ASCII=65), Row(A='a', ASCII=97), Row(A='', ASCII=0), Row(A='bcd', ASCII=98), Row(A=None, ASCII=None)]
    asciir}   r   r   s      rV   r  r  8
       	q'"A'1	::rY   
delimitersc                 p    t        | d      }|t        d||      S t        |d      }t        d|||      S )u  
    Returns the input string with the first letter of each word in uppercase
    and the subsequent letters in lowercase.

    ``delimiters`` is an optional argument specifying a string of one or more
    characters that ``initcap`` uses as separators for words in the input expression.

    If ``delimiters`` is not specified, any of the following characters in the
    input expressions are treated as word separators:

        ``<whitespace> ! ? @ " ^ # $ & ~ _ , . : ; + - * % / | \ [ ] ( ) { } < >``

    Examples::

        >>> df = session.create_dataframe(["the sky is blue", "WE CAN HANDLE THIS", "ÄäÖößÜü", None], schema=["a"])
        >>> df.select(initcap(df["a"]).alias("initcap")).collect()
        [Row(INITCAP='The Sky Is Blue'), Row(INITCAP='We Can Handle This'), Row(INITCAP='Ääöößüü'), Row(INITCAP=None)]
        >>> df.select(initcap(df["a"], lit('')).alias("initcap")).collect()
        [Row(INITCAP='The sky is blue'), Row(INITCAP='We can handle this'), Row(INITCAP='Ääöößüü'), Row(INITCAP=None)]
    initcapr}   r   )r   r  rQ   r   delimiter_cols        rV   r  r  G
  sB    0 	q)$Aii@@":y9M)QKKrY   c                 6    t        | d      }t        d||      S )u  
    Returns the length of an input string or binary value. For strings,
    the length is the number of characters, and UTF-8 characters are counted as a
    single character. For binary, the length is the number of bytes.

    Example::

        >>> df = session.create_dataframe(["the sky is blue", "WE CAN HANDLE THIS", "ÄäÖößÜü", None], schema=["a"])
        >>> df.select(length(df["a"]).alias("length")).collect()
        [Row(LENGTH=15), Row(LENGTH=18), Row(LENGTH=7), Row(LENGTH=None)]
    lengthr}   r   r   s      rV   r  r  g
       	q(#A(A;;rY   c                 6    t        | d      }t        d||      S )u  
    Returns the input string with all characters converted to lowercase.

    Example::

        >>> df = session.create_dataframe(['abc', 'Abc', 'aBC', 'Anführungszeichen', '14.95 €'], schema=["a"])
        >>> df.select(lower(col("a"))).collect()
        [Row(LOWER("A")='abc'), Row(LOWER("A")='abc'), Row(LOWER("A")='abc'), Row(LOWER("A")='anführungszeichen'), Row(LOWER("A")='14.95 €')]
    lowerr}   r   r   s      rV   r  r  x
  r  rY   r   padc                     t        | d      }t        |d      }|rt        d|||g      nd}t        d|t        |t              r|nt        |d      |||      S )a  
    Left-pads a string with characters from another string, or left-pads a
    binary value with bytes from another binary value.

    Example::

        >>> from snowflake.snowpark.functions import lit
        >>> df = session.create_dataframe([["a"], ["b"], ["c"]], schema=["a"])
        >>> df.select(lpad(col("a"), 3, lit("k")).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |kka       |
        |kkb       |
        |kkc       |
        ------------
        <BLANKLINE>
    lpadNFr}   ry   r9   r%   r   r   r6   rj   r   r   r  rQ   r   prn   s          rV   r  r  
  d    , 	q&!AsF#A6?
fq#qk
2TC	#v&Cu,E	 rY   trim_stringc                 x    t        | d      }|t        |d      nd}|t        d|||      S t        d||      S )a  
    Removes leading characters, including whitespace, from a string.

    Example::

        >>> from snowflake.snowpark.functions import lit
        >>> df = session.create_dataframe([["asss"], ["bsss"], ["csss"]], schema=["a"])
        >>> df.select(rtrim(col("a"), trim_string=lit("sss")).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |a         |
        |b         |
        |c         |
        ------------
        <BLANKLINE>
    ltrimNr}   r   r   r  rQ   r   ts        rV   r  r  
  sR    * 	q'"A0;0G{G,TA = 	w1	: GQ)<rY   c                     t        | d      }t        |d      }|rt        d|||g      nd}t        d|t        |t              r|nt        |d      |||      S )a^  Right-pads a string with characters from another string, or right-pads a
    binary value with bytes from another binary value. When called, `e` is padded to length `len`
    with characters/bytes from `pad`.

    Example::

        >>> from snowflake.snowpark.functions import lit
        >>> df = session.create_dataframe([["a"], ["b"], ["c"]], schema=["a"])
        >>> df.select(rpad(col("a"), 3, lit("k")).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |akk       |
        |bkk       |
        |ckk       |
        ------------
        <BLANKLINE>
    rpadNFr}   ry   r  r  s          rV   r  r  
  r  rY   c                 x    t        | d      }|t        |d      nd}|t        d|||      S t        d||      S )a  Removes trailing characters, including whitespace, from a string.

    Example::

        >>> from snowflake.snowpark.functions import lit
        >>> df = session.create_dataframe([["asss"], ["bsss"], ["csss"]], schema=["a"])
        >>> df.select(rtrim(col("a"), trim_string=lit("sss")).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |a         |
        |b         |
        |c         |
        ------------
        <BLANKLINE>
    rtrimNr}   r   r  s        rV   r  r  
  sR    ( 	q'"A0;0G{G,TA = 	w1	: GQ)<rY   r@  c                     t        | d      }|rt        d||g      nd}t        d|t        |t              r|nt        |d      ||      S )a  Builds a string by repeating the input for the specified number of times.

    Example::

        >>> df = session.create_dataframe([["a"], ["b"], ["c"]], schema=["a"])
        >>> df.select(repeat(col("a"), 3).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |aaa       |
        |bbb       |
        |ccc       |
        ------------
        <BLANKLINE>
    repeatNFr}   ry   r  )r@  r   rQ   r   rn   s        rV   r  r  
  sS    " 	q(#A3<
hA
/$C	6"A(? rY   c                 6    t        | d      } t        d| |      S )a  Reverses the order of characters in a string, or of bytes in a binary value.

    Example::

        >>> df = session.create_dataframe([["Hello"], ["abc"]], schema=["col1"])
        >>> df.select(reverse(col("col1"))).show()
        -----------------------
        |"REVERSE(""COL1"")"  |
        -----------------------
        |olleH                |
        |cba                  |
        -----------------------
        <BLANKLINE>
    reverser}   r   rW   rQ   s     rV   r  r  '  s      i
(C)SI>>rY   c                 6    t        | d      }t        d||      S )a  Returns a string that contains a phonetic representation of the input string.

    Example::
        >>> df = session.create_dataframe(["Marsha", "Marcia"], schema=["V"]).select(soundex(col("V")))
        >>> df.collect()
        [Row(SOUNDEX("V")='M620'), Row(SOUNDEX("V")='M620')]
    soundexr}   r   r   s      rV   r  r  ;  s     	q)$A)Q)<<rY   c                 x    t        | d      }|t        |d      nd}|t        d|||      S t        d||      S )ae  Removes leading and trailing characters from a string. Per default only whitespace ' ' characters are removed.

    Example::

        >>> df = session.create_dataframe(['hello', ' world', '   !   '], schema=["a"])
        >>> df.collect()
        [Row(A='hello'), Row(A=' world'), Row(A='   !   ')]
        >>> df.select(trim(col("a"))).collect()
        [Row(TRIM("A")='hello'), Row(TRIM("A")='world'), Row(TRIM("A")='!')]

    Example::

        >>> df = session.create_dataframe(['EUR 12.96', '7.89USD', '5.99E'], schema=["a"])
        >>> df.select(trim(col("a"), lit("EURUSD ")).as_("ans")).collect()
        [Row(ANS='12.96'), Row(ANS='7.89'), Row(ANS='5.99')]

    Example::

        >>> df = session.create_dataframe(['abc12 45a 79bc!'], schema=["a"])
        >>> df.select(trim(col("a"), lit("abc!")).as_("ans")).collect()
        [Row(ANS='12 45a 79')]

    trimNr}   r   r  s        rV   r  r  H  sR    6 	q&!A/:/F{F+DA = 	vq!y9 FA;rY   c                 6    t        | d      }t        d||      S )u  Returns the input string with all characters converted to uppercase.
       Unicode characters are supported.

    Example::

        >>> df = session.create_dataframe(['abc', 'Abc', 'aBC', 'Anführungszeichen', '14.95 €'], schema=["a"])
        >>> df.select(upper(col("a"))).collect()
        [Row(UPPER("A")='ABC'), Row(UPPER("A")='ABC'), Row(UPPER("A")='ABC'), Row(UPPER("A")='ANFÜHRUNGSZEICHEN'), Row(UPPER("A")='14.95 €')]
    upperr}   r   r   s      rV   r  r  l  r  rY   text	delimiterc                 x    t        | d      }|t        |d      nd}|t        d|||      S t        d||      S )aS  
    Tokenizes the given string using the given set of delimiters and returns the tokens as an array.

    If either parameter is a NULL, a NULL is returned. An empty array is returned if tokenization produces no tokens.

    Example::
        >>> df = session.create_dataframe(
        ...     [["a.b.c", "."], ["1,2.3", ","]],
        ...     schema=["text", "delimiter"],
        ... )
        >>> df.select(strtok_to_array("text", "delimiter").alias("TIME_FROM_PARTS")).collect()
        [Row(TIME_FROM_PARTS='[\n  "a",\n  "b",\n  "c"\n]'), Row(TIME_FROM_PARTS='[\n  "1",\n  "2.3"\n]')]
    strtok_to_arrayNr}   r   )r  r  rQ   r  r  s        rV   r  r  {  s`    " 	t./A ! 	y"34  ! 	(!Q)D -qIFrY   c                    | rt        d|      nd}fdg } |      D ]  }t        |t              r|j                  t	        |d             nb|j
                  j                  }|j                  d      r|dd n|}|j                  d      r|dd n|}|j                  t	        |d             t        |d      }t        |t              rNt        |j
                  t              r4|j                  t        |j
                  j                  d	   d             |j                  |        t        |d
di}||_        |S )a  
    Returns an OBJECT constructed with the given columns.

    Example::
        >>> from snowflake.snowpark.functions import struct
        >>> df = session.createDataFrame([("Bob", 80), ("Alice", None)], ["name", "age"])
        >>> res = df.select(struct("age", "name").alias("struct")).show()
        ---------------------
        |"STRUCT"           |
        ---------------------
        |{                  |
        |  "age": 80,       |
        |  "name": "Bob"    |
        |}                  |
        |{                  |
        |  "age": null,     |
        |  "name": "Alice"  |
        |}                  |
        ---------------------
        <BLANKLINE>
    structNc                     t        | t              st        | t              r| gS t        | d      rg }| D ]  }| |      z   } |S y )N__iter__)r   strr6   hasattr)objaccinnerObjflatten_col_lists      rV   r  z struct.<locals>.flatten_col_list  sU    c3:c6#:5LS*%C 7,X667J	 &rY   Fr}   "r   r   rQ   )r%   r   r  appendrj   r   name
startswithendswithr9   r6   r   childrenr   rz   )rQ   r   rn   new_colsr   r  r   r  s          @rV   r  r    s   0 2;
h
-C Hd# aOOCU34==%%D#s348D $c 249DOOC671h'a Zu%EOOF1==#9#9!#<NOOOA %h
@%
@CCHJrY   basec                    |rt        d| |g      nd}t        | t        t        f      rt	        | d      nt        | d      }t        |t        t        f      rt	        |d      nt        |d      }t        d||||      S )a:  
    Returns the logarithm of a numeric expression.

    Example::

        >>> from snowflake.snowpark.types import IntegerType
        >>> df = session.create_dataframe([1, 10], schema=["a"])
        >>> df.select(log(10, df["a"]).cast(IntegerType()).alias("log")).collect()
        [Row(LOG=0), Row(LOG=1)]
    logNFr}   ry   rN  )r  r  rQ   rn   bargs         rV   r  r    s    " 4=
edAY
/$C dS%L) 	DE"D%(  a#u& 	AAu% 
 %CcYGGrY   c                     |rt        d| g      nd}t        | t        t        f      rt	        | d      nt        | d      } t        | d      t	        dd      z   }t        |d      }||_        |S )z
    Returns the natural logarithm of (1 + x).

    Example::

        >>> df = session.create_dataframe([0, 1], schema=["a"])
        >>> df.select(log1p(df["a"]).alias("log1p")).collect()
        [Row(LOG1P=0.0), Row(LOG1P=0.6931471805599453)]
    log1pNFr}   r  r   )r%   r   rG  rH  rj   r9   lnrz   )r  rQ   rn   
one_plus_xr   s        rV   r  r    st     09
gs
+dC a#u& 	AAu% 
  7+c!u.EEJ
Z5
)CCHJrY   c                 V    t        |       }|rt        d| g      |_        |S d|_        |S )z
    Returns the base-10 logarithm of x.

    Example::

        >>> df = session.create_dataframe([1, 10], schema=["a"])
        >>> df.select(log10(df["a"]).alias("log10")).collect()
        [Row(LOG10=0.0), Row(LOG10=1.0)]
    log10N)_log10r%   rz   r  rQ   r   s      rV   r  r    s5     )C4="7QC0CHJ DHCHJrY   c                 V    t        |       }|rt        d| g      |_        |S d|_        |S )z
    Returns the base-2 logarithm of x.

    Example::

        >>> df = session.create_dataframe([1, 2, 8], schema=["a"])
        >>> df.select(log2(df["a"]).alias("log2")).collect()
        [Row(LOG2=0.0), Row(LOG2=1.0), Row(LOG2=3.0)]
    log2N)_log2r%   rz   r  s      rV   r  r    s5     (C3<"6A3/CHJ CGCHJrY   c                     t        d| d      S )N   Fr}   r  r  s    rV   r  r  2  s     q!u%%rY   c                     t        d| d      S )N
   Fr}   r   r  s    rV   r  r  8  s     r1&&rY   leftrightc                    |rt        d| |g      nd}t        | t        t        f      rt	        | d      nt        | d      }t        |t        t        f      rt	        |d      nt        |d      }t        d||||      S )ay  Returns a number (left) raised to the specified power (right).

    Example::
        >>> df = session.create_dataframe([[2, 3], [3, 4]], schema=["x", "y"])
        >>> df.select(pow(col("x"), col("y")).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |8.0       |
        |81.0      |
        ------------
        <BLANKLINE>
    powNFr}   ry   rN  )r  r  rQ   rn   numberpowers         rV   r  r  >  s    ( 8A
edE]
3dC dS%L) 	DE"D%(  ec5\* 	EU#E5) 

 %SINNrY   c                     |rt        d| |g      nd}t        | d      }t        |t        t        f      rt        |d      nt        |d      }t        d||||      S )a}  Returns rounded values from the specified column.

    Example::

        >>> df = session.create_dataframe([[1.11], [2.22], [3.33]], schema=["a"])
        >>> df.select(round(col("a")).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |1.0       |
        |2.0       |
        |3.0       |
        ------------
        <BLANKLINE>
    roundNFr}   ry   r%   r9   r   rG  rH  rj   r   r   r   rQ   rn   r   	scale_cols         rV   r  r  `  sf    ( 7@
g5z
2TCq'"A ec5\* 	EU#E7+  '1icYOOrY   c                 6    t        | d      }t        d||      S )av  
    Returns the sign of its argument:

        - -1 if the argument is negative.
        - 1 if it is positive.
        - 0 if it is 0.

    Args:
        col: The column to evaluate its sign

    Example::
        >>> df = session.create_dataframe([(-2, 2, 0)], ["a", "b", "c"])
        >>> df.select(sign("a").alias("a_sign"), sign("b").alias("b_sign"), sign("c").alias("c_sign")).show()
        ----------------------------------
        |"A_SIGN"  |"B_SIGN"  |"C_SIGN"  |
        ----------------------------------
        |-1        |1         |0         |
        ----------------------------------
        <BLANKLINE>
    rR  r}   r   r  s      rV   rR  rR    s    , 	sF#A&!y99rY   r  patternc                 P    t        | d      }t        |d      }t        d|||      S )a  Splits a given string with a given separator and returns the result in an array
    of strings. To specify a string separator, use the :func:`lit()` function.

    Example 1::

        >>> df = session.create_dataframe(
        ...     [["many-many-words", "-"], ["hello--hello", "--"]],
        ...     schema=["V", "D"],
        ... ).select(split(col("V"), col("D")))
        >>> df.show()
        -------------------------
        |"SPLIT(""V"", ""D"")"  |
        -------------------------
        |[                      |
        |  "many",              |
        |  "many",              |
        |  "words"              |
        |]                      |
        |[                      |
        |  "hello",             |
        |  "hello"              |
        |]                      |
        -------------------------
        <BLANKLINE>

    Example 2::

        >>> df = session.create_dataframe([["many-many-words"],["hello-hi-hello"]],schema=["V"],)
        >>> df.select(split(col("V"), lit("-"))).show()
        -----------------------
        |"SPLIT(""V"", '-')"  |
        -----------------------
        |[                    |
        |  "many",            |
        |  "many",            |
        |  "words"            |
        |]                    |
        |[                    |
        |  "hello",           |
        |  "hi",              |
        |  "hello"            |
        |]                    |
        -----------------------
        <BLANKLINE>
    splitr}   r   )r  r  rQ   r@  r  s        rV   r  r    s.    ^ 	sG$Aw(A'1a9==rY   posc                    t        | d      }|rt        d|||gn|||g      nd}t        |t              r|nt	        |d      }|t        d||||      S t        |t              r|nt	        |d      }t        d|||||      S )a  Returns the portion of the string or binary value str, starting from the
    character/byte specified by pos, with limited length. The length should be greater
    than or equal to zero. If the length is a negative number, the function returns an
    empty string.

    Note:
        For ``pos``, 1 is the first character of the string in Snowflake database.

    :func:`substr` is an alias of :func:`substring`.

    Example 1::
        >>> df = session.create_dataframe(
        ...     ["abc", "def"],
        ...     schema=["S"],
        ... )
        >>> df.select(substring(col("S"), 1, 1)).collect()
        [Row(SUBSTRING("S", 1, 1)='a'), Row(SUBSTRING("S", 1, 1)='d')]

    Example 2::
        >>> df = session.create_dataframe(
        ...     ["abc", "def"],
        ...     schema=["S"],
        ... )
        >>> df.select(substring(col("S"), 2)).collect()
        [Row(SUBSTRING("S", 2)='bc'), Row(SUBSTRING("S", 2)='ef')]
    	substringNFr}   ry   r9   r%   r   r6   rj   r   )r  r  r   rQ   r@  rn   r  r  s           rV   r  r    s    B 	sK(A  	KS[!Sq#smT 
 #v&Cu,EA
{k1acYOOsF+SSE1JF+q!V#SSrY   delimr   c                     |rt        d| ||g      nd}t        | d      }t        d||d      }t        dt        d||dk\  rdnt        d	|d      |z   |dk\  r|nt        d	|d      d      |||
      S )aD  
    Returns the substring from string ``text`` before ``count`` occurrences of the delimiter ``delim``.
    If ``count`` is positive, everything to the left of the final delimiter (counting from left) is
    returned. If ``count`` is negative, everything to the right of the final delimiter (counting from the
    right) is returned. If ``count`` is zero, returns empty string.

    Example 1::
        >>> df = session.create_dataframe(
        ...     ["a.b.c.d"],
        ...     schema=["S"],
        ... ).select(substring_index(col("S"), ".", 2).alias("result"))
        >>> df.show()
        ------------
        |"RESULT"  |
        ------------
        |a.b       |
        ------------
        <BLANKLINE>

    Example 2::
        >>> df = session.create_dataframe(
        ...     [["a.b.c.d", "."]],
        ...     schema=["S", "delimiter"],
        ... ).select(substring_index(col("S"), col("delimiter"), 2).alias("result"))
        >>> df.show()
        ------------
        |"RESULT"  |
        ------------
        |a.b       |
        ------------
        <BLANKLINE>
    substring_indexNr  Fr}   array_to_stringarray_slicer   
array_sizery   r  )r  r  r   rQ   rn   r@  strtok_arrays          rV   r  r    s    P  	-eU/CD  	t./A!"3QOLz leLuTz leL
	
 	 rY   subjectposition
parametersc                (   d}t        | |      }|rt        ||||g|      nd}t        |t              r|nt	        |d      }t        |t              r|nt	        |d      }	|D 
cg c]  }
t	        |
d       }}
t        ||||	g|||dS c c}
w )a  Returns the number of times that a pattern occurs in the subject.

    Example::

        >>> df = session.sql("select * from values('apple'),('banana'),('peach') as T(a)")
        >>> df.select(regexp_count(col("a"), "a").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |1         |
        |3         |
        |1         |
        ------------
        <BLANKLINE>
    regexp_countNFr}   ry   r  )r  r  r  rQ   r   sql_func_namesubrn   patr  r  paramss               rV   r"  r"  >  s    . #M
-
0C
  	MC(+PZ+PQ   0'c'U6SC 62(HPU8VC/9:!c!u%:F:sC'-479  ;s   &Bvalueregexpidxc                    |rt        d| ||g      nd}t        | d      } t        |d      }t        |d      }t        t	        d| |t        d      t        d      t        d      |d      t        dd      d      }||_        |S )	a>  
    Extract a specific group matched by a regex, from the specified string column.
    If the regex did not match, or the specified group did not match,
    an empty string is returned.

    Example::

        >>> from snowflake.snowpark.functions import regexp_extract
        >>> df = session.createDataFrame([["id_20_30", 10], ["id_40_50", 30]], ["id", "age"])
        >>> df.select(regexp_extract("id", r"(\d+)", 1).alias("RES")).show()
        ---------
        |"RES"  |
        ---------
        |20     |
        |40     |
        ---------
        <BLANKLINE>
    regexp_extractNregexp_substrr   r   Fr}    )r%   r9   r7   r1  r   rj   rz   )r'  r(  r)  rQ   rn   r   s         rV   r+  r+  h  s    :  	,ufc.BC  5"23EF$45F
.
/CFFH		
 	B% 	A AFHrY   replacementoccurrencesc                   |rt        d| ||||g|      nd}d}t        | |      }	t        |t              r|nt	        |d      }
t        |t              r|nt	        |d      }t        |t              r|nt	        |d      }t        |t              r|nt	        |d      }|D cg c]!  }t        |t              r|nt	        |d      # }}t        ||	|
|||g|||dS c c}w )a  Returns the subject with the specified pattern (or all occurrences of the pattern) either removed or replaced by a replacement string.
    If no matches are found, returns the original subject.

    Example::
        >>> df = session.create_dataframe(
        ...     [["It was the best of times, it was the worst of times"]], schema=["a"]
        ... )
        >>> df.select(regexp_replace(col("a"), lit("( ){1,}"), lit("")).alias("result")).show()
        --------------------------------------------
        |"RESULT"                                  |
        --------------------------------------------
        |Itwasthebestoftimes,itwastheworstoftimes  |
        --------------------------------------------
        <BLANKLINE>
    regexp_replaceNFr}   ry   r%   r9   r   r6   rj   r   )r  r  r.  r  r/  rQ   r   rn   r#  r$  r%  repr  occr  r&  s                   rV   r1  r1    s   @ 	 	g{HkOJO	

   %M
-
0C0'c'U6SC k6* 	. 
 !62(HPU8VC k6* 	.  JTDEZ6"A(??F  sCc317>AY s   &&C#c                     |rt        d| ||g      nd}d}t        | |      }t        |t              r|nt	        |d      }t        |t              r|nt	        |d      }t        ||||||      S )a  
    Removes all occurrences of a specified subject and optionally replaces them with replacement.

    Example::

        >>> df = session.create_dataframe([["apple"], ["apple pie"], ["apple juice"]], schema=["a"])
        >>> df.select(replace(col("a"), "apple", "orange").alias("result")).show()
        ----------------
        |"RESULT"      |
        ----------------
        |orange        |
        |orange pie    |
        |orange juice  |
        ----------------
        <BLANKLINE>
    replaceNFr}   ry   r2  )	r  r  r.  rQ   rn   r#  r$  r%  r3  s	            rV   r6  r6    s    4  	I+'FG 
 M
-
0C0'c'U6SC k6* 	. 
 -c3SIVVrY   target_exprsource_exprc           	          |rt        d|| |gn| ||g      nd}t        | d      }t        |d      }|.t        d||t        |t              r|nt        |d      ||      S t        d||||      S )a  Searches for ``target_expr`` in ``source_expr`` and, if successful,
    returns the position (1-based) of the ``target_expr`` in ``source_expr``.

    Args:
        target_expr: A string or binary expression representing the value to look for.
        source_expr: A string or binary expression representing the value to search.
        position: A number indication the position (1-based) from where to start the search. Defaults to None.

    Examples::
        >>> df = session.create_dataframe(["banana"], schema=['a'])
        >>> df.select(charindex(lit("an"), df.a, 1).as_("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |2         |
        ------------
        <BLANKLINE>

        >>> df.select(charindex(lit("an"), df.a, 3).as_("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |4         |
        ------------
        <BLANKLINE>
    	charindexNFr}   ry   r%   r9   r   r   r6   rj   )r7  r8  r  rQ   rn   r  r@  s          rV   r:  r:    s    R  	 +&{H5		
   	{K0A{K0A  	(F+ X/		
 KAC9MrY   collation_specc                 8    t        | d      }t        d|||      S )u_  Returns a copy of the original :class:`Column` with the specified ``collation_spec``
    property, rather than the original collation specification property.

    For details, see the Snowflake documentation on
    `collation specifications <https://docs.snowflake.com/en/sql-reference/collation.html#label-collation-specification>`_.

    Example::
        >>> df = session.create_dataframe(['ñ'], schema=['v'])
        >>> df.select(df.v == lit('Ñ'), collate(df.v, 'sp-upper') == lit('Ñ')).show()
        ----------------------------------------------------------
        |"(""V"" = 'Ñ')"  |"(COLLATE(""V"", 'SP-UPPER') = 'Ñ')"  |
        ----------------------------------------------------------
        |False            |True                                  |
        ----------------------------------------------------------
        <BLANKLINE>
    collater}   r   )r   r<  rQ   r   s       rV   r>  r>  B  s!    $ 	q)$A)Q)LLrY   c                 6    t        | d      }t        d||      S )u  Returns the collation specification of expr.

    Example::
        >>> df = session.create_dataframe(['ñ'], schema=['v'])
        >>> df.select(collation(collate(df.v, 'sp-upper'))).show()
        -------------------------------------------
        |"COLLATION(COLLATE(""V"", 'SP-UPPER'))"  |
        -------------------------------------------
        |sp-upper                                 |
        -------------------------------------------
        <BLANKLINE>
    	collationr}   r   r   s      rV   r@  r@  X       	q+&A+qI>>rY   c                 \    |D cg c]  }t        |d       }}t        dg|d| iS c c}w )a  Concatenates one or more strings, or concatenates one or more binary values. If any of the values is null, the result is also null.

    Example::
        >>> df = session.create_dataframe([['Hello', 'World']], schema=['a', 'b'])
        >>> df.select(concat(df.a, df.b)).show()
        --------------------------
        |"CONCAT(""A"", ""B"")"  |
        --------------------------
        |HelloWorld              |
        --------------------------
        <BLANKLINE>
    concatrQ   r   r-  s       rV   rC  rC  j  s8     599q~a*9G9(BWB	BB :r/  c                 \    |D cg c]  }t        |d       }}t        dg|d| iS c c}w )ad  Concatenates two or more strings, or concatenates two or more binary values. If any of the values is null, the result is also null.
    The CONCAT_WS operator requires at least two arguments, and uses the first argument to separate all following arguments.

    Examples::
        >>> from snowflake.snowpark.functions import lit
        >>> df = session.create_dataframe([['Hello', 'World']], schema=['a', 'b'])
        >>> df.select(concat_ws(lit(','), df.a, df.b)).show()
        ----------------------------------
        |"CONCAT_WS(',', ""A"", ""B"")"  |
        ----------------------------------
        |Hello,World                     |
        ----------------------------------
        <BLANKLINE>

        >>> df = session.create_dataframe([['Hello', 'World', ',']], schema=['a', 'b', 'sep'])
        >>> df.select(concat_ws('sep', df.a, df.b)).show()
        --------------------------------------
        |"CONCAT_WS(""SEP"", ""A"", ""B"")"  |
        --------------------------------------
        |Hello,World                         |
        --------------------------------------
        <BLANKLINE>
    	concat_wsrQ   r   r-  s       rV   rE  rE  |  s8    2 8<<!~a-<G<+EE9EE =r/  sepc                   |rt        d| g|      nd}|D cg c]  }t        |d       }}dj                  t        |      D cg c]  \  }}|j	                         xs d|  c}}      }dt
        dt
        fd}t         |t        t        |D cg c]  }|j                  t               d	       c}d
did	            t        | d	      d      j                  d|  d| d      }	||	_        |	S c c}w c c}}w c c}w )a;  Concatenates two or more strings, or concatenates two or more binary values. Null values are ignored.

    Args:
        sep: The separator to use between the strings.

    Examples::
        >>> df = session.create_dataframe([
        ...     ['Hello', 'World', None],
        ...     [None, None, None],
        ...     ['Hello', None, None],
        ... ], schema=['a', 'b', 'c'])
        >>> df.select(_concat_ws_ignore_nulls(',', df.a, df.b, df.c)).show()
        ----------------------------------------------------
        |"CONCAT_WS_IGNORE_NULLS(',', ""A"",""B"",""C"")"  |
        ----------------------------------------------------
        |Hello,World                                       |
        |                                                  |
        |Hello                                             |
        ----------------------------------------------------
        <BLANKLINE>

        >>> df.select(_concat_ws_ignore_nulls('--', df.a, df.b, df.c)).show()
        -----------------------------------------------------
        |"CONCAT_WS_IGNORE_NULLS('--', ""A"",""B"",""C"")"  |
        -----------------------------------------------------
        |Hello--World                                       |
        |                                                   |
        |Hello                                              |
        -----------------------------------------------------
        <BLANKLINE>

        >>> df = session.create_dataframe([
        ...     (['Hello', 'World', None], None, '!'),
        ...     (['Hi', 'World', "."], "I'm Dad", '.'),
        ... ], schema=['a', 'b', 'c'])
        >>> df.select(_concat_ws_ignore_nulls(", ", "a", "b", "c")).show()
        -----------------------------------------------------
        |"CONCAT_WS_IGNORE_NULLS(', ', ""A"",""B"",""C"")"  |
        -----------------------------------------------------
        |Hello, World, !                                    |
        |Hi, World, ., I'm Dad, .                           |
        -----------------------------------------------------
        <BLANKLINE>
    _concat_ws_ignore_nullsN,COLrW   rR   c                 6    t        d| t        dd      d      S )z9Expects an array and returns an array with nulls removed.filterzx -> NOT IS_NULL_VALUE(x)Fr}   )r   rm   rW   s    rV   array_remove_nullsz3_concat_ws_ignore_nulls.<locals>.array_remove_nulls  s#    0EB	
 	
rY   Fr}   rQ   )r%  	separatorrQ   zCONCAT_WS_IGNORE_NULLS('z', ))r%   r9   join	enumerateget_namer6   r  array_flattenarray_construct_compactrI  r=   rj   _aliasrz   )
rF  rQ   r   rn   r   r.  inamesrN  ress
             rV   rH  rH    s%   d  	5|d|D 
 FJJ~a!:;JGJHHIg<NODAqajjl/A3i/OPE
 
6 
  'DKLqaffY[Ef:L#  
 cU+ f'uCwa89  CHJO KO8 Ms   C8!C=
"Dsrcsource_alphabettarget_alphabetc                 j    t        | d      }t        |d      }t        |d      }t        d||||      S )ac  Translates src from the characters in source_alphabet to the characters in
    target_alphabet. Each character matching a character at position i in the source_alphabet is replaced
    with the character at position i in the target_alphabet. If target_alphabet is shorter, and there is no corresponding
    character the character is omitted. target_alphabet can not be longer than source_alphabet.

    Example::

        >>> df = session.create_dataframe(["abcdef", "abba"], schema=["a"])
        >>> df.select(translate(col("a"), lit("abc"), lit("ABC")).as_("ans")).collect()
        [Row(ANS='ABCdef'), Row(ANS='ABBA')]

        >>> df = session.create_dataframe(["file with spaces.txt", "\ttest"], schema=["a"])
        >>> df.select(translate(col("a"), lit(" \t"), lit("_")).as_("ans")).collect()
        [Row(ANS='file_with_spaces.txt'), Row(ANS='test')]

    	translater}   r   )rZ  r[  r\  rQ   sources        rV   r^  r^    s@    . C-F$_kBO$_kBOV_o rY   stringc                 P    t        | d      }t        |d      }t        d|||      S )a  Returns if `col` contains `string` for each row. See `CONTAINS <https://docs.snowflake.com/en/sql-reference/functions/contains>`

    Example:
        >>> df = session.create_dataframe([[1,2], [3,4], [5,5] ], schema=["a","b"])
        >>> df.select(contains(col("a"), col("b")).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |False     |
        |False     |
        |True      |
        ------------
        <BLANKLINE>
    containsr}   r   )rW   r`  rQ   r   r@  s        rV   rb  rb    s-      	sJ'Avz*A*ai@@rY   c                 P    t        | d      }t        |d      }t        d|||      S )aL  Returns true if col starts with str.

    Example::
        >>> df = session.create_dataframe(
        ...     [["abc", "a"], ["abc", "s"]],
        ...     schema=["S", "P"],
        ... ).select(startswith(col("S"), col("P")))
        >>> df.collect()
        [Row(STARTSWITH("S", "P")=True), Row(STARTSWITH("S", "P")=False)]
    r  r}   r   rW   r  rQ   r   r@  s        rV   r  r  ,  s-     	sL)AsL)A,1	BBrY   c                 P    t        | d      }t        |d      }t        d|||      S )a*  
    Returns true if col ends with str.

    Example::

        >>> df = session.create_dataframe(["apple", "banana", "peach"], schema=["a"])
        >>> df.select(endswith(df["a"], lit("ana")).alias("endswith")).collect()
        [Row(ENDSWITH=False), Row(ENDSWITH=True), Row(ENDSWITH=False)]
    r  r}   r   rd  s        rV   r  r  =  s-     	sJ'AsJ'A*ai@@rY   	base_exprr  insert_exprc           	          |rt        d| |||g      nd}t        | d      }t        |d      }t        d|t        |t              r|nt        |d      t        |t              r|nt        |d      |||      S )a@  
    Replaces a substring of the specified length, starting at the specified position,
    with a new string or binary value.

    Examples::

        >>> df = session.create_dataframe(["abc"], schema=["a"])
        >>> df.select(insert(df["a"], 1, 2, lit("Z")).alias("insert")).collect()
        [Row(INSERT='Zc')]
    insertNFr}   ry   r;  )rf  r  r  rg  rQ   rn   r  rW  s           rV   ri  ri  M  s    *  	Hy(FK&PQ 
 	y(+A{H-A	x0c(e6TVV,#f2N	 rY   str_exprc                     |rt        d| |g      nd}t        | d      }t        d|t        |t              r|nt        |d      ||      S )aa  Returns a left most substring of ``str_expr``.

    Example::

        >>> df = session.create_dataframe([["abc"], ["def"]], schema=["a"])
        >>> df.select(left(col("a"), 2).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |ab        |
        |de        |
        ------------
        <BLANKLINE>
    r  NFr}   ry   r;  rj  r  rQ   rn   r@  s        rV   r  r  r  sU    & >G
fx&8
9DCx(A	VV,#f2N rY   c                     |rt        d| |g      nd}t        | d      }t        d|t        |t              r|nt        |d      ||      S )ac  Returns a right most substring of ``str_expr``.

    Example::

        >>> df = session.create_dataframe([["abc"], ["def"]], schema=["a"])
        >>> df.select(right(col("a"), 2).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |bc        |
        |ef        |
        ------------
        <BLANKLINE>
    r  NFr}   ry   r;  rl  s        rV   r  r    sU    & ?H
g&'9
:TCx)A	VV,#f2N rY   c                 6    t        | d      }t        d||      S )u  Converts a Unicode code point (including 7-bit ASCII) into the character that
    matches the input Unicode.

    Example::

        >>> df = session.create_dataframe([83, 33, 169, 8364, None], schema=['a'])
        >>> df.select(df.a, char(df.a).as_('char')).sort(df.a).show()
        -----------------
        |"A"   |"CHAR"  |
        -----------------
        |NULL  |NULL    |
        |33    |!       |
        |83    |S       |
        |169   |©       |
        |8364  |€       |
        -----------------
        <BLANKLINE>
    charr}   r   r  s      rV   ro  ro    s    ( 	sF#A&!y99rY   r   formatc                     |rt        d|| gn| |g      nd}t        | d      } |-t        d| t        |t              r|nt        |d      ||      S t        d| ||      S )a  Converts a Unicode code point (including 7-bit ASCII) into the character that
    matches the input Unicode.

    Example::
        >>> df = session.create_dataframe([1, 2, 3, 4], schema=['a'])
        >>> df.select(to_char(col('a')).as_('ans')).collect()
        [Row(ANS='1'), Row(ANS='2'), Row(ANS='3'), Row(ANS='4')]

    Example::

        >>> import datetime
        >>> df = session.create_dataframe([datetime.datetime(2023, 4, 16), datetime.datetime(2017, 4, 3, 2, 59, 37, 153)], schema=['a'])
        >>> df.select(to_char(col('a')).as_('ans')).collect()
        [Row(ANS='2023-04-16 00:00:00.000'), Row(ANS='2017-04-03 02:59:37.000')]

    to_charNFr}   ry   r;  )r   rp  rQ   rn   s       rV   rr  rr    s    .  	Ifns1f+N 
 	q)$A  	 0Fc&E6R	

 IqsiH
rY   c                     |rt        d| |g      nd}t        t        t        | d      t               d      |d      }||_        |S )a'  Converts an input expression into the corresponding date in the specified date format.

    Example::
        >>> df = session.create_dataframe([("2023-10-10",), ("2022-05-15",), ("invalid",)], schema=['date'])
        >>> df.select(date_format('date', 'YYYY/MM/DD').as_('formatted_date')).show()
        --------------------
        |"FORMATTED_DATE"  |
        --------------------
        |2023/10/10        |
        |2022/05/15        |
        |NULL              |
        --------------------
        <BLANKLINE>

    Example::
        >>> df = session.create_dataframe([("2023-10-10 15:30:00",), ("2022-05-15 10:45:00",)], schema=['timestamp'])
        >>> df.select(date_format('timestamp', 'YYYY/MM/DD HH:mi:ss').as_('formatted_ts')).show()
        -----------------------
        |"FORMATTED_TS"       |
        -----------------------
        |2023/10/10 15:30:00  |
        |2022/05/15 10:45:00  |
        -----------------------
        <BLANKLINE>

    Example::
        >>> df = session.sql("select '2023-10-10'::DATE as date_col, '2023-10-10 15:30:00'::TIMESTAMP as timestamp_col")
        >>> df.select(
        ...     date_format('date_col', 'YYYY/MM/DD').as_('formatted_dt'),
        ...     date_format('timestamp_col', 'YYYY/MM/DD HH:mi:ss').as_('formatted_ts')
        ... ).show()
        ----------------------------------------
        |"FORMATTED_DT"  |"FORMATTED_TS"       |
        ----------------------------------------
        |2023/10/10      |2023/10/10 15:30:00  |
        ----------------------------------------
        <BLANKLINE>
    date_formatNFr}   )r%   rr  try_castrD   rz   )r   re  rQ   rn   r   s        rV   rt  rt    sN    X ;D
maX
6C
e,moOC
 CHJrY   c                 X    t        | d      }|t        d|||      S t        d||      S )a  Converts an input expression into the corresponding time.

    Example::

        >>> df = session.create_dataframe(['04:15:29.999'], schema=['a'])
        >>> df.select(to_time(col("a"))).collect()
        [Row(TO_TIME("A")=datetime.time(4, 15, 29, 999000))]
    to_timer}   r   r   re  rQ   r   s       rV   rw  rw  %  s?     	q)$A ? 	y!SI> IqI>rY   r6   c                 X    t        | d      }|t        d|||      S t        d||      S )a
  Converts an input expression into the corresponding timestamp.

    Per default fmt is set to auto, which makes Snowflake detect the format automatically. With `to_timestamp` strings
    can be converted to timestamps. The format has to be specified according to the rules set forth in
    <https://docs.snowflake.com/en/sql-reference/functions-conversion#date-and-time-formats-in-conversion-functions>

    Example::
        >>> df = session.create_dataframe(['2019-01-31 01:02:03.004'], schema=['a'])
        >>> df.select(to_timestamp(col("a")).as_("ans")).collect()
        [Row(ANS=datetime.datetime(2019, 1, 31, 1, 2, 3, 4000))]
        >>> df = session.create_dataframe(["2020-05-01 13:11:20.000"], schema=['a'])
        >>> df.select(to_timestamp(col("a"), lit("YYYY-MM-DD HH24:MI:SS.FF3")).as_("ans")).collect()
        [Row(ANS=datetime.datetime(2020, 5, 1, 13, 11, 20))]

    Another option is to convert dates into timestamps

    Example::
        >>> import datetime
        >>> df = session.createDataFrame([datetime.datetime(2022, 12, 25, 13, 59, 38, 467)], schema=["a"])
        >>> df.select(to_timestamp(col("a"))).collect()
        [Row(TO_TIMESTAMP("A")=datetime.datetime(2022, 12, 25, 13, 59, 38, 467))]
        >>> df = session.createDataFrame([datetime.date(2023, 3, 1)], schema=["a"])
        >>> df.select(to_timestamp(col("a"))).collect()
        [Row(TO_TIMESTAMP("A")=datetime.datetime(2023, 3, 1, 0, 0))]

    Integers can be converted into a timestamp as well, by providing optionally a scale as an integer as lined out in
    <https://docs.snowflake.com/en/sql-reference/functions/to_timestamp#usage-notes>. Currently Snowpark does support
    integers in the range of an 8-byte signed integer only.

    Example::
        >>> df = session.createDataFrame([20, 31536000000], schema=['a'])
        >>> df.select(to_timestamp(col("a"))).collect()
        [Row(TO_TIMESTAMP("A")=datetime.datetime(1970, 1, 1, 0, 0, 20)), Row(TO_TIMESTAMP("A")=datetime.datetime(2969, 5, 3, 0, 0))]
        >>> df.select(to_timestamp(col("a"), lit(9))).collect()
        [Row(TO_TIMESTAMP("A", 9)=datetime.datetime(1970, 1, 1, 0, 0)), Row(TO_TIMESTAMP("A", 9)=datetime.datetime(1970, 1, 1, 0, 0, 31, 536000))]

    Larger numbers stored in a string can be also converted via this approach

    Example::
        >>> df = session.createDataFrame(['20', '31536000000', '31536000000000', '31536000000000000'], schema=['a'])
        >>> df.select(to_timestamp(col("a")).as_("ans")).collect()
        [Row(ANS=datetime.datetime(1970, 1, 1, 0, 0, 20)), Row(ANS=datetime.datetime(1971, 1, 1, 0, 0)), Row(ANS=datetime.datetime(1971, 1, 1, 0, 0)), Row(ANS=datetime.datetime(1971, 1, 1, 0, 0))]
    to_timestampr}   r   rx  s       rV   rz  rz  9  s@    ^ 	q.)A ? 	~q#C NACrY   c                     |rt        d|| gn| |g      nd}t        | d      }|t        d|t        |d      ||      S t        d|||      S )a  Converts an input expression into the corresponding timestamp without a timezone.

    Per default fmt is set to auto, which makes Snowflake detect the format automatically. With `to_timestamp` strings
    can be converted to timestamps. The format has to be specified according to the rules set forth in
    <https://docs.snowflake.com/en/sql-reference/functions-conversion#date-and-time-formats-in-conversion-functions>

    Example::
        >>> import datetime
        >>> df = session.createDataFrame([datetime.datetime(2022, 12, 25, 13, 59, 38, 467)], schema=["a"])
        >>> df.select(to_timestamp_ntz(col("a"))).collect()
        [Row(TO_TIMESTAMP_NTZ("A")=datetime.datetime(2022, 12, 25, 13, 59, 38, 467))]
        >>> df = session.createDataFrame([datetime.date(2023, 3, 1)], schema=["a"])
        >>> df.select(to_timestamp_ntz(col("a"))).collect()
        [Row(TO_TIMESTAMP_NTZ("A")=datetime.datetime(2023, 3, 1, 0, 0))]
    to_timestamp_ntzNry   r%   r9   r   r7   r   re  rQ   rn   r   s        rV   r|  r|  p  sz    .  	.s{CQ  	q,-A ? 	3 23	

 .yQ
rY   c                     |rt        d|| gn| |g      nd}t        | d      }|t        d|t        |d      ||      S t        d|||      S )a  Converts an input expression into the corresponding timestamp using the local timezone.

    Per default fmt is set to auto, which makes Snowflake detect the format automatically. With `to_timestamp` strings
    can be converted to timestamps. The format has to be specified according to the rules set forth in
    <https://docs.snowflake.com/en/sql-reference/functions-conversion#date-and-time-formats-in-conversion-functions>
    to_timestamp_ltzNry   r}  r~  s        rV   r  r    sz      	.s{CQ  	q,-A ? 	3 23	

 .yQ
rY   c                     |rt        d|| gn| |g      nd}t        | d      }|t        d|t        |d      ||      S t        d|||      S )a  Converts an input expression into the corresponding timestamp with the timezone represented in each row.

    Per default fmt is set to auto, which makes Snowflake detect the format automatically. With `to_timestamp` strings
    can be converted to timestamps. The format has to be specified according to the rules set forth in
    <https://docs.snowflake.com/en/sql-reference/functions-conversion#date-and-time-formats-in-conversion-functions>
    to_timestamp_tzNry   r}  r~  s        rV   r  r    sz      	-cks3xP  	q+,A ? 	3 12	

 -qsiP
rY   tzc                 x    |rt        d| |g      nd}t        | d      }t        |d      }t        dd||||      S )a  Interprets an input expression as a UTC timestamp and converts it to the given time zone.

    Note:
        Time zone names are case-sensitive.
        Snowflake does not support the majority of timezone abbreviations (e.g. PDT, EST, etc.). Instead you can
        specify a time zone name or a link name from release 2021a of the IANA Time Zone Database (e.g.
        America/Los_Angeles, Europe/London, UTC, Etc/GMT, etc.).
        See the following for more information:
        <https://data.iana.org/time-zones/tzdb-2021a/zone1970.tab>
        <https://data.iana.org/time-zones/tzdb-2021a/backward>

    Example::
        >>> df = session.create_dataframe(['2019-01-31 01:02:03.004'], schema=['t'])
        >>> df.select(from_utc_timestamp(col("t"), "America/Los_Angeles").alias("ans")).collect()
        [Row(ANS=datetime.datetime(2019, 1, 30, 17, 2, 3, 4000))]

    Example::
        >>> df = session.create_dataframe([('2019-01-31 01:02:03.004', "America/Los_Angeles")], schema=['t', 'tz'])
        >>> df.select(from_utc_timestamp(col("t"), col("tz")).alias("ans")).collect()
        [Row(ANS=datetime.datetime(2019, 1, 30, 17, 2, 3, 4000))]
    from_utc_timestampNr   UTCry   rh  r   r  rQ   rn   r   tz_cs         rV   r  r    sP    4 AJ
2QG
<tCq./A"23DE4	 rY   c                 x    |rt        d| |g      nd}t        | d      }t        |d      }t        d|d|||      S )a|  Interprets an input expression as a timestamp and converts from given time zone to UTC.

    Note:
        Time zone names are case-sensitive.
        Snowflake does not support the majority of timezone abbreviations (e.g. PDT, EST, etc.). Instead you can
        specify a time zone name or a link name from release 2021a of the IANA Time Zone Database (e.g.
        America/Los_Angeles, Europe/London, UTC, Etc/GMT, etc.).
        See the following for more information:
        <https://data.iana.org/time-zones/tzdb-2021a/zone1970.tab>
        <https://data.iana.org/time-zones/tzdb-2021a/backward>

    Example::
        >>> df = session.create_dataframe(['2019-01-31 01:02:03.004'], schema=['t'])
        >>> df.select(to_utc_timestamp(col("t"), "America/Los_Angeles").alias("ans")).collect()
        [Row(ANS=datetime.datetime(2019, 1, 31, 9, 2, 3, 4000))]

    Example::
        >>> df = session.create_dataframe([('2019-01-31 01:02:03.004', "America/Los_Angeles")], schema=['t', 'tz'])
        >>> df.select(to_utc_timestamp(col("t"), col("tz")).alias("ans")).collect()
        [Row(ANS=datetime.datetime(2019, 1, 31, 9, 2, 3, 4000))]
    to_utc_timestampNr   r  ry   rh  r  s         rV   r  r    sO    4 ?H
01b'
:TCq,-A"01DD%	 rY   c                     |rt        d|| gn| |g      nd}t        | d      }|t        d|||      S t        d|t        j                  |      ||      S )a   Converts an input expression into a date.

    Example::

        >>> df = session.create_dataframe(['2013-05-17', '2013-05-17'], schema=['a'])
        >>> df.select(to_date(col('a')).as_('ans')).collect()
        [Row(ANS=datetime.date(2013, 5, 17)), Row(ANS=datetime.date(2013, 5, 17))]

        >>> df = session.create_dataframe(['2013-05-17', '2013-05-17'], schema=['a'])
        >>> df.select(to_date(col('a'), 'YYYY-MM-DD').as_('ans')).collect()
        [Row(ANS=datetime.date(2013, 5, 17)), Row(ANS=datetime.date(2013, 5, 17))]

        >>> df = session.create_dataframe(['2013-05-17', '2013-05-17'], schema=['a'])
        >>> df.select(to_date(col('a'), 'YYYY-MM-DD').as_('ans')).collect()
        [Row(ANS=datetime.date(2013, 5, 17)), Row(ANS=datetime.date(2013, 5, 17))]

        >>> df = session.create_dataframe(['31536000000000', '71536004000000'], schema=['a'])
        >>> df.select(to_date(col('a')).as_('ans')).collect()
        [Row(ANS=datetime.date(1971, 1, 1)), Row(ANS=datetime.date(1972, 4, 7))]

    to_dateNry   r%   r9   r   r6   _to_exprr~  s        rV   r  r    st    8  	Icks3xH  	q)$A ; 	y!#C q&//#.SI
rY   c                     t        d|       S )a  Returns the current timestamp for the system.

    Example:
        >>> import datetime
        >>> result = session.create_dataframe([1]).select(current_timestamp()).collect()
        >>> assert isinstance(result[0]["CURRENT_TIMESTAMP()"], datetime.datetime)
    current_timestampr}   r~   r}   s    rV   r  r  J  s     -CCrY   c                     t        d|       S )zReturns the current date for the system.

    Example:
        >>> import datetime
        >>> result = session.create_dataframe([1]).select(current_date()).collect()
        >>> assert isinstance(result[0]["CURRENT_DATE()"], datetime.date)
    current_dater}   r~   r}   s    rV   r  r  V  r   rY   c                     t        d|       S )zReturns the current time for the system.

    Example:
        >>> import datetime
        >>> result = session.create_dataframe([1]).select(current_time()).collect()
        >>> assert isinstance(result[0]["CURRENT_TIME()"], datetime.time)
    current_timer}   r~   r}   s    rV   r  r  b  r   rY   c                 6    t        | d      }t        d||      S )a  
    Extracts the hour from a date or timestamp.

    Example::

        >>> import datetime
        >>> df = session.create_dataframe([
        ...     datetime.datetime.strptime("2020-05-01 13:11:20.000", "%Y-%m-%d %H:%M:%S.%f"),
        ...     datetime.datetime.strptime("2020-08-21 01:30:05.000", "%Y-%m-%d %H:%M:%S.%f")
        ... ], schema=["a"])
        >>> df.select(hour("a")).collect()
        [Row(HOUR("A")=13), Row(HOUR("A")=1)]
    hourr}   r   r   s      rV   r  r  n  r  rY   c                 6    t        | d      }t        d||      S )a  
    Extracts the day from a date or timestamp.

    Example::

        >>> import datetime
        >>> df = session.create_dataframe([
        ...     datetime.datetime.strptime("2020-05-01 13:11:20.000", "%Y-%m-%d %H:%M:%S.%f"),
        ...     datetime.datetime.strptime("2020-08-21 01:30:05.000", "%Y-%m-%d %H:%M:%S.%f")
        ... ], schema=["a"])
        >>> df.select(day("a")).collect()
        [Row(DAY("A")=1), Row(DAY("A")=21)]
    dayr}   r   r   s      rV   r  r    r   rY   r   partc                     |rt        d|| gn| |g      nd}t        | d      }|t        d|||      S t        |d      }t        d||||      S )a  
    Returns the last day of the specified date part for a date or timestamp.
    Commonly used to return the last day of the month for a date or timestamp.

    Args:
        expr: The array column
        part: The date part used to compute the last day of the given array column, default is "MONTH".
            Valid values are "YEAR", "MONTH", "QUARTER", "WEEK" or any of their supported variations.

    Example::

        >>> import datetime
        >>> df = session.create_dataframe([
        ...     datetime.datetime.strptime("2020-05-01 13:11:20.000", "%Y-%m-%d %H:%M:%S.%f"),
        ...     datetime.datetime.strptime("2020-08-21 01:30:05.000", "%Y-%m-%d %H:%M:%S.%f")
        ... ], schema=["a"])
        >>> df.select(last_day("a")).collect()
        [Row(LAST_DAY("A")=datetime.date(2020, 5, 31)), Row(LAST_DAY("A")=datetime.date(2020, 8, 31))]
        >>> df.select(last_day("a", "YEAR")).collect()
        [Row(LAST_DAY("A", "YEAR")=datetime.date(2020, 12, 31)), Row(LAST_DAY("A", "YEAR")=datetime.date(2020, 12, 31))]
    last_dayNry   r  )r   r  rQ   rn   expr_colpart_cols         rV   r  r    sj    6  	J$,T4LQ  dJ/H|j(	RRdJ/H*hsiXXrY   c                 6    t        | d      }t        d||      S )a  
    Extracts the minute from a date or timestamp.

    Example::

        >>> import datetime
        >>> df = session.create_dataframe([
        ...     datetime.datetime.strptime("2020-05-01 13:11:20.000", "%Y-%m-%d %H:%M:%S.%f"),
        ...     datetime.datetime.strptime("2020-08-21 01:30:05.000", "%Y-%m-%d %H:%M:%S.%f")
        ... ], schema=["a"])
        >>> df.select(minute("a")).collect()
        [Row(MINUTE("A")=11), Row(MINUTE("A")=30)]
    minuter}   r   r   s      rV   r  r         	q(#A(A;;rY   dateday_of_weekc                     |rt        d| |g      nd}t        | d      }t        d|t        j                  |      ||      S )a  
    Returns the date of the first specified DOW (day of week) that occurs after the input date.

    Example::

        >>> import datetime
        >>> df = session.create_dataframe([
        ...     (datetime.date.fromisoformat("2020-08-01"), "mo"),
        ...     (datetime.date.fromisoformat("2020-12-01"), "we"),
        ... ], schema=["a", "b"])
        >>> df.select(next_day("a", col("b"))).collect()
        [Row(NEXT_DAY("A", "B")=datetime.date(2020, 8, 3)), Row(NEXT_DAY("A", "B")=datetime.date(2020, 12, 2))]
        >>> df.select(next_day("a", "fr")).collect()
        [Row(NEXT_DAY("A", 'FR')=datetime.date(2020, 8, 7)), Row(NEXT_DAY("A", 'FR')=datetime.date(2020, 12, 4))]
    next_dayNry   r  r  r  rQ   rn   r   s        rV   r  r    sJ    * CL
j4*=
>QUCtZ(AAv{3# rY   c                     |rt        d| |g      nd}t        | d      }t        d|t        j                  |      ||      S )a  
    Returns the date of the first specified DOW (day of week) that occurs before the input date.

    Example::

        >>> import datetime
        >>> df = session.create_dataframe([
        ...     (datetime.date.fromisoformat("2020-08-01"), "mo"),
        ...     (datetime.date.fromisoformat("2020-12-01"), "we"),
        ... ], schema=["a", "b"])
        >>> df.select(previous_day("a", col("b"))).collect()
        [Row(PREVIOUS_DAY("A", "B")=datetime.date(2020, 7, 27)), Row(PREVIOUS_DAY("A", "B")=datetime.date(2020, 11, 25))]
        >>> df.select(previous_day("a", "fr")).collect()
        [Row(PREVIOUS_DAY("A", 'FR')=datetime.date(2020, 7, 31)), Row(PREVIOUS_DAY("A", 'FR')=datetime.date(2020, 11, 27))]
    previous_dayNry   r  r  s        rV   r  r    sO    , ENNT;,?@SW  	t^,A6??;7cY rY   c                 6    t        | d      }t        d||      S )a  
    Extracts the second from a date or timestamp.

    Example::

        >>> import datetime
        >>> df = session.create_dataframe([
        ...     datetime.datetime.strptime("2020-05-01 13:11:20.000", "%Y-%m-%d %H:%M:%S.%f"),
        ...     datetime.datetime.strptime("2020-08-21 01:30:05.000", "%Y-%m-%d %H:%M:%S.%f")
        ... ], schema=["a"])
        >>> df.select(second("a")).collect()
        [Row(SECOND("A")=20), Row(SECOND("A")=5)]
    secondr}   r   r   s      rV   r  r  	  r  rY   c                 6    t        | d      }t        d||      S )a  
    Extracts the month from a date or timestamp.

    Example::

        >>> import datetime
        >>> df = session.create_dataframe([
        ...     datetime.datetime.strptime("2020-05-01 13:11:20.000", "%Y-%m-%d %H:%M:%S.%f"),
        ...     datetime.datetime.strptime("2020-08-21 01:30:05.000", "%Y-%m-%d %H:%M:%S.%f")
        ... ], schema=["a"])
        >>> df.select(month("a")).collect()
        [Row(MONTH("A")=5), Row(MONTH("A")=8)]
    monthr}   r   r   s      rV   r  r    s     	q'"A'1	::rY   c                 6    t        | d      }t        d||      S )a  
    Extracts the three-letter month name from the specified date or timestamp.

    Example::

        >>> import datetime
        >>> df = session.create_dataframe([
        ...     datetime.datetime.strptime("2020-05-01 13:11:20.000", "%Y-%m-%d %H:%M:%S.%f"),
        ...     datetime.datetime.strptime("2020-08-21 01:30:05.000", "%Y-%m-%d %H:%M:%S.%f")
        ... ], schema=["a"])
        >>> df.select(monthname("a")).collect()
        [Row(MONTHNAME("A")='May'), Row(MONTHNAME("A")='Aug')]
    	monthnamer}   r   r   s      rV   r  r  /  s     	q+&A+qI>>rY   c                 6    t        | d      }t        d||      S )a  
    Extracts the quarter from a date or timestamp.

    Example::

        >>> import datetime
        >>> df = session.create_dataframe([
        ...     datetime.datetime.strptime("2020-05-01 13:11:20.000", "%Y-%m-%d %H:%M:%S.%f"),
        ...     datetime.datetime.strptime("2020-08-21 01:30:05.000", "%Y-%m-%d %H:%M:%S.%f")
        ... ], schema=["a"])
        >>> df.select(quarter("a")).collect()
        [Row(QUARTER("A")=2), Row(QUARTER("A")=3)]
    quarterr}   r   r   s      rV   r  r  B  s     	q)$A)Q)<<rY   c                 6    t        | d      }t        d||      S )a  
    Extracts the year from a date or timestamp.

    Example::

        >>> import datetime
        >>> df = session.create_dataframe([
        ...     datetime.datetime.strptime("2020-05-01 13:11:20.000", "%Y-%m-%d %H:%M:%S.%f"),
        ...     datetime.datetime.strptime("2020-08-21 01:30:05.000", "%Y-%m-%d %H:%M:%S.%f")
        ... ], schema=["a"])
        >>> df.select(year("a")).collect()
        [Row(YEAR("A")=2020), Row(YEAR("A")=2020)]
    yearr}   r   r   s      rV   r  r  U  r  rY   num_bucketsc                     |rt        d| |g      nd}t        | t              rt        | d      nt	        | d      } t	        |d      }t        d| |||      S )a  
    Performs an Iceberg partition bucket transform.
    This function should only be used in the iceberg_config['partition_by'] parameter when creating Iceberg tables.

    Example::

        >>> iceberg_config = {
        ...     "external_volume": "example_volume",
        ...     "partition_by": [bucket(10, "a")]
        ... }
        >>> df.write.save_as_table("my_table", iceberg_config=iceberg_config) # doctest: +SKIP
    bucketNFr}   ry   r%   r   rG  rj   r9   r   )r  rW   rQ   rn   s       rV   r  r  h  sd      @I
hc(:
;dC k3' 	K5)K2 
 h
'C(K3)TTrY   widthc                     |rt        d| |g      nd}t        | t              rt        | d      nt	        | d      } t	        |d      }t        d| |||      S )a  
    Performs an Iceberg partition truncate transform.
    This function should only be used in the iceberg_config['partition_by'] parameter when creating Iceberg tables.

    Example::

        >>> iceberg_config = {
        ...     "external_volume": "example_volume",
        ...     "partition_by": [truncate(3, "a")]
        ... }
        >>> df.write.save_as_table("my_table", iceberg_config=iceberg_config) # doctest: +SKIP
    truncateNFr}   ry   r  )r  rW   rQ   rn   s       rV   r  r    sb      <E
j5#,
7$C eS! 	EU#E:. 

 j
)C*eSsiPPrY   c                     t        d|       S )z
    Returns the current timestamp for the system, but in the UTC time zone.

    Example::

        >>> df = session.create_dataframe([1], schema=["a"])
        >>> df.select(sysdate()).collect() is not None
        True
    sysdater}   r~   r}   s    rV   r  r    s     )y99rY   date1date2c                 P    t        | d      }t        |d      }t        d|||      S )a  
    Returns the number of months between two DATE or TIMESTAMP values.

    Example::

        >>> import datetime
        >>> df = session.create_dataframe([[
        ...     datetime.datetime.strptime("2020-05-01 13:11:20.000", "%Y-%m-%d %H:%M:%S.%f"),
        ...     datetime.datetime.strptime("2020-08-21 01:30:05.000", "%Y-%m-%d %H:%M:%S.%f")
        ... ]], schema=["a", "b"])
        >>> df.select(months_between("a", "b")).collect()
        [Row(MONTHS_BETWEEN("A", "B")=Decimal('-3.629452'))]
    months_betweenr}   r   )r  r  rQ   r   r   s        rV   r  r    s0    " 
/	0B	/	0B*BiHHrY   c                 6    t        | d      }t        d||      S )a  Parses an input and returns a value of type GEOGRAPHY. Supported inputs are strings in

        - WKT (well-known text).
        - WKB (well-known binary) in hexadecimal format (without a leading 0x).
        - EWKT (extended well-known text).
        - EWKB (extended well-known binary) in hexadecimal format (without a leading 0x).
        - GeoJSON.

    format.

    Example::
        >>> df = session.create_dataframe(['POINT(-122.35 37.55)', 'POINT(20.92 43.33)'], schema=['a'])
        >>> df.select(to_geography(col("a"))).collect()
        [Row(TO_GEOGRAPHY("A")='{\n  "coordinates": [\n    -122.35,\n    37.55\n  ],\n  "type": "Point"\n}'), Row(TO_GEOGRAPHY("A")='{\n  "coordinates": [\n    20.92,\n    43.33\n  ],\n  "type": "Point"\n}')]

    Besides strings, binary representation in WKB and EWKB format can be parsed, or objects adhering to GeoJSON format.
    For all supported formats confer https://docs.snowflake.com/en/sql-reference/data-types-geospatial#supported-geospatial-object-types.
    to_geographyr}   r   r   s      rV   r  r    s    ( 	q.)A.!yAArY   c                 6    t        | d      }t        d||      S )a  Parses an input and returns a value of type GEOMETRY. Supported inputs are strings in

        - WKT (well-known text).
        - WKB (well-known binary) in hexadecimal format (without a leading 0x).
        - EWKT (extended well-known text).
        - EWKB (extended well-known binary) in hexadecimal format (without a leading 0x).
        - GeoJSON.

    format.

    Example::
        >>> df = session.create_dataframe(['POINT(-122.35 37.55)', 'POINT(20.92 43.33)'], schema=['a'])
        >>> df.select(to_geometry(col("a"))).collect(statement_params={"GEOMETRY_OUTPUT_FORMAT": "WKT"})
        [Row(TO_GEOMETRY("A")='POINT(-122.35 37.55)'), Row(TO_GEOMETRY("A")='POINT(20.92 43.33)')]

    Besides strings, binary representation in WKB and EWKB format can be parsed, or objects adhering to GeoJSON format.
    For all supported formats confer https://docs.snowflake.com/en/sql-reference/data-types-geospatial#supported-geospatial-object-types.
    to_geometryr}   r   r   s      rV   r  r    s    ( 	q-(A-i@@rY   array1array2c                 P    t        | d      }t        |d      }t        d|||      S )az  Compares whether two ARRAYs have at least one element in common. Returns TRUE
    if there is at least one element in common; otherwise returns FALSE. The function
    is NULL-safe, meaning it treats NULLs as known values for comparing equality.

    Example::
        >>> from snowflake.snowpark import Row
        >>> df = session.create_dataframe([Row([1, 2], [1, 3]), Row([1, 2], [3, 4])], schema=["a", "b"])
        >>> df.select(arrays_overlap("a", "b").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |True      |
        |False     |
        ------------
        <BLANKLINE>
    arrays_overlapr}   r   r  r  rQ   a1a2s        rV   r  r    s0    ( 
 0	1B	 0	1B*BiHHrY   c                 6    t        | d      } t        d| |      S )a  The function excludes any duplicate elements that are present in the input ARRAY.
    The function is not guaranteed to return the elements in the ARRAY in a specific order.
    The function is NULL safe, which means that it treats NULLs as known values when identifying duplicate elements.

    Args:
        col: The array column

    Returns:
        Returns a new ARRAY that contains only the distinct elements from the input ARRAY.

    Example::

        >>> from snowflake.snowpark.functions import array_construct,array_distinct,lit
        >>> df = session.createDataFrame([["1"]], ["A"])
        >>> df = df.withColumn("array", array_construct(lit(1), lit(1), lit(1), lit(2), lit(3), lit(2), lit(2)))
        >>> df.withColumn("array_d", array_distinct("ARRAY")).show()
        -----------------------------
        |"A"  |"ARRAY"  |"ARRAY_D"  |
        -----------------------------
        |1    |[        |[          |
        |     |  1,     |  1,       |
        |     |  1,     |  2,       |
        |     |  1,     |  3        |
        |     |  2,     |]          |
        |     |  3,     |           |
        |     |  2,     |           |
        |     |  2      |           |
        |     |]        |           |
        -----------------------------
        <BLANKLINE>
    array_distinctr}   r   r  s     rV   r  r    s"    B .
/C*C9EErY   c                 P    t        | d      }t        |d      }t        d|||      S )a  Returns an array that contains the matching elements in the two input arrays.

    The function is NULL-safe, meaning it treats NULLs as known values for comparing equality.

    Args:
        array1: An ARRAY that contains elements to be compared.
        array2: An ARRAY that contains elements to be compared.

    Example::
        >>> from snowflake.snowpark import Row
        >>> df = session.create_dataframe([Row([1, 2], [1, 3])], schema=["a", "b"])
        >>> df.select(array_intersection("a", "b").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |[         |
        |  1       |
        |]         |
        ------------
        <BLANKLINE>
    array_intersectionr}   r   r  s        rV   r  r  2  s0    2 
 4	5B	 4	5B.B)LLrY   source_arrayarray_of_elements_to_excludeallow_duplicatesc           	          |rt        d| ||g      nd}t        | d      }t        |d      }|rt        d||||      S t        dt        d|d      t        d|d      ||      S )aC  Returns a new ARRAY that contains the elements from one input ARRAY that are not in another input ARRAY.

    The function is NULL-safe, meaning it treats NULLs as known values for comparing equality.

    When allow_duplicates is set to True (default), this function is the same as the Snowflake ARRAY_EXCEPT semantic:

    This function compares arrays by using multi-set semantics (sometimes called "bag semantics"). If source_array
    includes multiple copies of a value, the function only removes the number of copies of that value that are specified
    in array_of_elements_to_exclude.

    For example, if source_array contains 5 elements with the value 'A' and array_of_elements_to_exclude contains 2
    elements with the value 'A', the returned array contains 3 elements with the value 'A'.

    When allow_duplicates is set to False:

    This function compares arrays by using set semantics. Specifically, it will first do an element deduplication
    for both arrays, and then compute the array_except result.

    For example, if source_array contains 5 elements with the value 'A' and array_of_elements_to_exclude contains 2
    elements with the value 'A', the returned array is empty.

    Args:
        source_array: An array that contains elements to be included in the new ARRAY.
        array_of_elements_to_exclude: An array that contains elements to be excluded from the new ARRAY.
        allow_duplicates: If True, we use multi-set semantic. Otherwise use set semantic.

    Example::
        >>> from snowflake.snowpark import Row
        >>> df = session.create_dataframe([Row(["A", "B"], ["B", "C"])], schema=["source_array", "array_of_elements_to_exclude"])
        >>> df.select(array_except("source_array", "array_of_elements_to_exclude").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |[         |
        |  "A"     |
        |]         |
        ------------
        <BLANKLINE>
        >>> df = session.create_dataframe([Row(["A", "B", "B", "B", "C"], ["B"])], schema=["source_array", "array_of_elements_to_exclude"])
        >>> df.select(array_except("source_array", "array_of_elements_to_exclude").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |[         |
        |  "A",    |
        |  "B",    |
        |  "B",    |
        |  "C"     |
        |]         |
        ------------
        <BLANKLINE>
        >>> df = session.create_dataframe([Row(["A", None, None], ["B", None])], schema=["source_array", "array_of_elements_to_exclude"])
        >>> df.select(array_except("source_array", "array_of_elements_to_exclude").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |[         |
        |  "A",    |
        |  null    |
        |]         |
        ------------
        <BLANKLINE>
        >>> df = session.create_dataframe([Row([{'a': 1, 'b': 2}, 1], [{'a': 1, 'b': 2}, 3])], schema=["source_array", "array_of_elements_to_exclude"])
        >>> df.select(array_except("source_array", "array_of_elements_to_exclude").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |[         |
        |  1       |
        |]         |
        ------------
        <BLANKLINE>
        >>> df = session.create_dataframe([Row(["A", "B"], None)], schema=["source_array", "array_of_elements_to_exclude"])
        >>> df.select(array_except("source_array", "array_of_elements_to_exclude").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |NULL      |
        ------------
        <BLANKLINE>
        >>> df = session.create_dataframe([Row(["A", "B"], ["B", "C"])], schema=["source_array", "array_of_elements_to_exclude"])
        >>> df.select(array_except("source_array", "array_of_elements_to_exclude", False).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |[         |
        |  "A"     |
        |]         |
        ------------
        <BLANKLINE>
        >>> df = session.create_dataframe([Row(["A", "B", "B", "B", "C"], ["B"])], schema=["source_array", "array_of_elements_to_exclude"])
        >>> df.select(array_except("source_array", "array_of_elements_to_exclude", False).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |[         |
        |  "A",    |
        |  "C"     |
        |]         |
        ------------
        <BLANKLINE>
        >>> df = session.create_dataframe([Row(["A", None, None], ["B", None])], schema=["source_array", "array_of_elements_to_exclude"])
        >>> df.select(array_except("source_array", "array_of_elements_to_exclude", False).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |[         |
        |  "A"     |
        |]         |
        ------------
        <BLANKLINE>
    array_exceptNry   r  Fr}   r  )r  r  r  rQ   rn   r  r  s          rV   r  r  P  s    z 	 	79IJ	

   L.9F8.IF  	~vvC9U
 +VuE+VuE

rY   r%  c                 6    t        | d      } t        d| |      S )a  Returns smallest defined non-NULL element in the input array. If the input
    array is empty, or there is no defined element in the input array, then the
    function returns NULL.

    Args:
        array: the input array

    Returns:
        a VARIANT containing the smallest defined element in the array, or NULL

    Examples::
            Behavior with SQL nulls:
                >>> df = session.sql("select array_construct(20, 0, null, 10) as A")
                >>> df.select(array_min(df.a).as_("min_a")).collect()
                [Row(MIN_A='0')]
                >>> df = session.sql("select array_construct() as A")
                >>> df.select(array_min(df.a).as_("min_a")).collect()
                [Row(MIN_A=None)]
                >>> df = session.sql("select array_construct(null, null, null) as A")
                >>> df.select(array_min(df.a).as_("min_a")).collect()
                [Row(MIN_A=None)]

            Behavior with JSON nulls:
                >>> df = session.create_dataframe([[[None, None, None]]], schema=["A"])
                >>> df.select(array_min(df.a).as_("min_a")).collect()
                [Row(MIN_A='null')]
    	array_minr}   r   r%  rQ   s     rV   r  r        : 5+.E+u	BBrY   c                 6    t        | d      } t        d| |      S )aO  Returns largest defined non-NULL element in the input array. If the input
    array is empty, or there is no defined element in the input array, then the
    function returns NULL.

    Args:
        array: the input array

    Returns:
        a VARIANT containing the largest defined element in the array, or NULL

    Examples::
        Behavior with SQL nulls:
            >>> df = session.sql("select array_construct(20, 0, null, 10) as A")
            >>> df.select(array_max(df.a).as_("max_a")).collect()
            [Row(MAX_A='20')]
            >>> df = session.sql("select array_construct() as A")
            >>> df.select(array_max(df.a).as_("max_a")).collect()
            [Row(MAX_A=None)]
            >>> df = session.sql("select array_construct(null, null, null) as A")
            >>> df.select(array_max(df.a).as_("max_a")).collect()
            [Row(MAX_A=None)]

        Behavior with JSON nulls:
            >>> df = session.create_dataframe([[[None, None, None]]], schema=["A"])
            >>> df.select(array_max(df.a).as_("max_a")).collect()
            [Row(MAX_A='null')]
    	array_maxr}   r   r  s     rV   r  r    r  rY   c                 6    t        | d      } t        d| |      S )a  Returns a single array from an array or arrays. If the array is nested more than
    two levels deep, then only a single level of nesting is removed.

    Must enable parameter `ENABLE_ARRAY_FLATTEN_FUNCTION` in your session.

    Args:
        array: the input array
    rT  r}   r   r  s     rV   rT  rT  "  s     5/2E/5IFFrY   c                 6    t        | d      }t        d||      S )ao  Returns an array with the elements of the input array in reverse order.

    Args:
        col: The source array.

    Example::
        >>> df = session.sql("select [1, 2, 3, 4] :: ARRAY(INT) as A")
        >>> df.select(array_reverse("A")).show()
        --------------------------
        |"ARRAY_REVERSE(""A"")"  |
        --------------------------
        |[                       |
        |  4,                    |
        |  3,                    |
        |  2,                    |
        |  1                     |
        |]                       |
        --------------------------
        <BLANKLINE>
    array_reverser}   r   )rW   rQ   r%  s      rV   r  r  0  s    , 30E/5IFFrY   sort_ascendingnulls_firstc           	          |rt        d| ||g      nd}t        | d      } t        d| t        |d      t        |d      ||      S )aP  Returns rows of array column in sorted order. Users can choose the sort order and decide where to keep null elements.

    Args:
        array: name of the column or column element which describes the column
        sort_ascending: Boolean that decides if array elements are sorted in ascending order.
            Defaults to True.
        nulls_first: Boolean that decides if SQL null elements will be placed in the beginning
            of the array. Note that this does not affect JSON null. Defaults to False.

    Examples::
        Behavior with SQL nulls:
            >>> df = session.sql("select array_construct(20, 0, null, 10) as A")
            >>> df.select(array_sort(df.a).as_("sorted_a")).show()
            ---------------
            |"SORTED_A"   |
            ---------------
            |[            |
            |  0,         |
            |  10,        |
            |  20,        |
            |  undefined  |
            |]            |
            ---------------
            <BLANKLINE>
            >>> df.select(array_sort(df.a, False).as_("sorted_a")).show()
            ---------------
            |"SORTED_A"   |
            ---------------
            |[            |
            |  20,        |
            |  10,        |
            |  0,         |
            |  undefined  |
            |]            |
            ---------------
            <BLANKLINE>
            >>> df.select(array_sort(df.a, False, True).as_("sorted_a")).show()
            ----------------
            |"SORTED_A"    |
            ----------------
            |[             |
            |  undefined,  |
            |  20,         |
            |  10,         |
            |  0           |
            |]             |
            ----------------
            <BLANKLINE>

        Behavior with JSON nulls:
            >>> df = session.create_dataframe([[[20, 0, None, 10]]], schema=["a"])
            >>> df.select(array_sort(df.a, False, False).as_("sorted_a")).show()
            --------------
            |"SORTED_A"  |
            --------------
            |[           |
            |  null,     |
            |  20,       |
            |  10,       |
            |  0         |
            |]           |
            --------------
            <BLANKLINE>
            >>> df.select(array_sort(df.a, False, True).as_("sorted_a")).show()
            --------------
            |"SORTED_A"  |
            --------------
            |[           |
            |  null,     |
            |  20,       |
            |  10,       |
            |  0         |
            |]           |
            --------------
            <BLANKLINE>

    See Also:
        - https://docs.snowflake.com/en/user-guide/semistructured-considerations#null-values
        - :func:`~snowflake.snowpark.functions.sort_array` which is an alias of :meth:`~snowflake.snowpark.functions.array_sort`.
    
array_sortNFr}   ry   rd  )r%  r  r  rQ   rn   s        rV   r  r  J  s^    t  	L5.+*NO 
 5,/ENe,K5) rY   keysvaluesc                 P    t        | d      }t        |d      }t        d|||      S )a  Returns an object constructed from 2 arrays.

    Args:
        keys: The column containing keys of the object.
        values: The column containing values of the object.
    Examples::
        >>> df = session.sql("select array_construct('10', '20', '30') as A, array_construct(10, 20, 30) as B")
        >>> df.select(arrays_to_object(df.a, df.b).as_("object")).show()
        ---------------
        |"OBJECT"     |
        ---------------
        |{            |
        |  "10": 10,  |
        |  "20": 20,  |
        |  "30": 30   |
        |}            |
        ---------------
        <BLANKLINE>
        >>> df = session.create_dataframe([[["a"], [1]], [["b", "c"],[2, 3]]], schema=["k", "v"])
        >>> df.select(arrays_to_object(df.k, df.v).as_("objects")).show()
        -------------
        |"OBJECTS"  |
        -------------
        |{          |
        |  "a": 1   |
        |}          |
        |{          |
        |  "b": 2,  |
        |  "c": 3   |
        |}          |
        -------------
        <BLANKLINE>

    See Also:
        - https://docs.snowflake.com/en/sql-reference/data-types-semistructured#label-data-type-object for information on Objects
    arrays_to_objectr}   r   )r  r  rQ   keys_cvalues_cs        rV   r  r    s1    P D"45Ff&89H,fh)TTrY   c                 \    |D cg c]  }t        |d       }}t        dg|d| iS c c}w )aL  Returns an array of structured objects, where the N-th object contains the N-th elements of the input arrays.

    Args:
        cols: The columns to zip together.

    Returns:
        A new array of structured objects.

    Examples::
        >>> df = session.sql("select array_construct('10', '20', '30') as A, array_construct(10, 20, 30) as B")
        >>> df.select(arrays_zip(df.a, df.b).as_("zipped")).show(statement_params={"enable_arrays_zip_function": "TRUE"})
        -------------------
        |"ZIPPED"         |
        -------------------
        |[                |
        |  {              |
        |    "$1": "10",  |
        |    "$2": 10     |
        |  },             |
        |  {              |
        |    "$1": "20",  |
        |    "$2": 20     |
        |  },             |
        |  {              |
        |    "$1": "30",  |
        |    "$2": 30     |
        |  }              |
        |]                |
        -------------------
        <BLANKLINE>
        >>> df = session.sql("select array_construct('10', '20', '30') as A, array_construct(1, 2) as B, array_construct(1.1) as C")
        >>> df.select(arrays_zip(df.a, df.b, df.c).as_("zipped")).show(statement_params={"enable_arrays_zip_function": "TRUE"})
        -------------------
        |"ZIPPED"         |
        -------------------
        |[                |
        |  {              |
        |    "$1": "10",  |
        |    "$2": 1,     |
        |    "$3": 1.1    |
        |  },             |
        |  {              |
        |    "$1": "20",  |
        |    "$2": 2,     |
        |    "$3": null   |
        |  },             |
        |  {              |
        |    "$1": "30",  |
        |    "$2": null,  |
        |    "$3": null   |
        |  }              |
        |]                |
        -------------------
        <BLANKLINE>
    
arrays_ziprQ   r   )rQ   r   r   s      rV   r  r    s9    r 6::N1l+:D:,CCCC ;r/  startstopstepc                     t        | d      }t        |d      }|t        d|||      S t        |d      }t        d||||      S )a  Generate a range of integers from `start` to `stop`, incrementing by `step`.
    If `step` is not set, incrementing by 1.

    Args:
        start: the column that contains the integer to start with (inclusive).
        stop: the column that contains the integer to stop (exclusive).
        step: the column that contains the integer to increment.

    Example::
        >>> from snowflake.snowpark import Row
        >>> df1 = session.create_dataframe([(-2, 2)], ["a", "b"])
        >>> df1.select(array_generate_range("a", "b").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |[         |
        |  -2,     |
        |  -1,     |
        |  0,      |
        |  1       |
        |]         |
        ------------
        <BLANKLINE>
        >>> df2 = session.create_dataframe([(4, -4, -2)], ["a", "b", "c"])
        >>> df2.select(array_generate_range("a", "b", "c").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |[         |
        |  4,      |
        |  2,      |
        |  0,      |
        |  -2      |
        |]         |
        ------------
        <BLANKLINE>
    array_generate_ranger}   r   )r  r  r  rQ   	start_colstop_colstep_cols          rV   r  r    sa    X u&<=Id$:;H|"Ix9
 	
 d$:;H	8X rY   c                 N   |rt        d|| |gn| ||g      nd}t        | d      }t        |d      }|5t        t        d||z
  d      dkD  ddd      }t        d	|||z   |||
      S t        |d      }t        t        d|d      dkD  ddd      }t        d	|||z   |||
      S )a  Generate a sequence of integers from `start` to `stop`, incrementing by `step`.
    If `step` is not set, incrementing by 1 if start is less than or equal to stop, otherwise -1.

    Args:
        start: the column that contains the integer to start with (inclusive).
        stop: the column that contains the integer to stop (inclusive).
        step: the column that contains the integer to increment.

    Example::
        >>> from snowflake.snowpark import Row
        >>> df1 = session.create_dataframe([(-2, 2)], ["a", "b"])
        >>> df1.select(sequence("a", "b").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |[         |
        |  -2,     |
        |  -1,     |
        |  0,      |
        |  1,      |
        |  2       |
        |]         |
        ------------
        <BLANKLINE>
        >>> df2 = session.create_dataframe([(4, -4, -2)], ["a", "b", "c"])
        >>> df2.select(sequence("a", "b", "c").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |[         |
        |  4,      |
        |  2,      |
        |  0,      |
        |  -2,     |
        |  -4      |
        |]         |
        ------------
        <BLANKLINE>
    sequenceNrR  Fr}   r   r   r  r  ry   )r%   r9   r   r   )	r  r  r  rQ   rn   r  r  r  	step_signs	            rV   r  r  T  s    h  	E4;N	
   uj1IdJ/H|68i#75IAM	
 "tO
 	
 dJ/Hvx59A=q"PUI 9 rY   num_of_daysc                     |rt        d| |g      nd}t        | d      } t        |t              rt	        |d      nt        |d      }t        d|| d      }||_        |S )a.  
    Adds a number of days to a date column.

    Args:
        col: The column to add to.
        num_of_days: The number of days to add.

    Example::

        >>> from snowflake.snowpark.functions import date_add, to_date
        >>> df = session.createDataFrame([("1976-01-06")], ["date"])
        >>> df = df.withColumn("date", to_date("date"))
        >>> res = df.withColumn("date", date_add("date", 4)).show()
        --------------
        |"DATE"      |
        --------------
        |1976-01-10  |
        --------------
        <BLANKLINE>
    date_addNFr}   r  r%   r9   r   rG  rj   dateaddrz   rW   r  rQ   rn   r   s        rV   r  r    sp    2 BK
j3*<
=PTC j
)C k3' 	K5)K4  %cU
;CCHJrY   c                     |rt        d| |g      nd}t        | d      } t        |t              rt	        |d      nt        |d      }t        dd|z  | d      }||_        |S )a;  
    Subtracts a number of days from a date column.

    Args:
        col: The column to subtract from.
        num_of_days: The number of days to subtract.

    Example::

        >>> from snowflake.snowpark.functions import date_sub, to_date
        >>> df = session.createDataFrame([("1976-01-06")], ["date"])
        >>> df = df.withColumn("date", to_date("date"))
        >>> df.withColumn("date", date_sub("date", 2)).show()
        --------------
        |"DATE"      |
        --------------
        |1976-01-04  |
        --------------
        <BLANKLINE>
    date_subNFr}   r  r  r  r  s        rV   r  r    su    2 BK
j3*<
=PTC j
)C k3' 	K5)K4  %k)3%
@CCHJrY   r   r   c                     t        | t              st        d      t        |d      }t        |d      }t	        d| |||      S )a  Calculates the difference between two date, time, or timestamp columns based on the date or time part requested, and
    returns result of ``col2 - col1`` based on the requested date or time part.

    `Supported date and time parts <https://docs.snowflake.com/en/sql-reference/functions-date-time.html#label-supported-date-time-parts>`_

    Example::

        >>> # year difference between two date columns
        >>> import datetime
        >>> date_df = session.create_dataframe([[datetime.date(2020, 1, 1), datetime.date(2021, 1, 1)]], schema=["date_col1", "date_col2"])
        >>> date_df.select(datediff("year", col("date_col1"), col("date_col2")).alias("year_diff")).show()
        ---------------
        |"YEAR_DIFF"  |
        ---------------
        |1            |
        ---------------
        <BLANKLINE>

    Args:
        part: The time part to use for calculating the difference
        col1: The first timestamp column or subtrahend in the datediff
        col2: The second timestamp column or the minuend in the datediff

    See Also:
        - `Snowflake Datediff <https://docs.snowflake.com/en/sql-reference/functions/datediff>`_
    part must be a stringdatediffr}   r   r  r  r9   r   r  r   r   rQ   r   r   s         rV   r  r    sE    < dC 011	j	)B	j	)B*dBiHHrY   c                     |rt        d| |g      nd}t        | d      } t        |d      }t        dt        dd      || ||      S )a  Calculates the difference between two dates, or timestamp columns based in days.
    The result will reflect the difference between ``col1 - col2``

    Example::
        >>> from snowflake.snowpark.functions import daydiff, to_date
        >>> df = session.createDataFrame([("2015-04-08", "2015-05-10")], ["d1", "d2"])
        >>> res = df.select(daydiff(to_date(df.d2), to_date(df.d1)).alias("diff")).show()
        ----------
        |"DIFF"  |
        ----------
        |32      |
        ----------
        <BLANKLINE>
    daydiffNr  r  Fr}   ry   rd  )r   r   rQ   rn   s       rV   r  r  !  sX    " ;D
i$
6C$	*D$	*DEU# rY   c                     |rt        d| |g      nd}t        | d      }t        |t        t        f      rt        |d      nt        |d      }t        d||||      S )a  Rounds the input expression down to the nearest (or equal) integer closer to zero,
    or to the nearest equal or smaller value with the specified number of
    places after the decimal point.

    Example::

        >>> df = session.createDataFrame([-1.0, -0.9, -.5, -.2, 0.0, 0.2, 0.5, 0.9, 1.1, 3.14159], schema=["a"])
        >>> df.select(trunc(col("a"))).collect()
        [Row(TRUNC("A", 0)=-1.0), Row(TRUNC("A", 0)=0.0), Row(TRUNC("A", 0)=0.0), Row(TRUNC("A", 0)=0.0), Row(TRUNC("A", 0)=0.0), Row(TRUNC("A", 0)=0.0), Row(TRUNC("A", 0)=0.0), Row(TRUNC("A", 0)=0.0), Row(TRUNC("A", 0)=1.0), Row(TRUNC("A", 0)=3.0)]

        >>> df = session.createDataFrame([-1.323, 4.567, 0.0123], schema=["a"])
        >>> df.select(trunc(col("a"), lit(0))).collect()
        [Row(TRUNC("A", 0)=-1.0), Row(TRUNC("A", 0)=4.0), Row(TRUNC("A", 0)=0.0)]
        >>> df.select(trunc(col("a"), lit(1))).collect()
        [Row(TRUNC("A", 1)=-1.3), Row(TRUNC("A", 1)=4.5), Row(TRUNC("A", 1)=0.0)]
        >>> df.select(trunc(col("a"), lit(2))).collect()
        [Row(TRUNC("A", 2)=-1.32), Row(TRUNC("A", 2)=4.56), Row(TRUNC("A", 2)=0.01)]

    Note that the function ``trunc`` is overloaded with ``date_trunc`` for datetime types. It allows to round datetime
    objects.

    Example::

        >>> import datetime
        >>> df = session.createDataFrame([datetime.date(2022, 12, 25), datetime.date(2022, 1, 10), datetime.date(2022, 7, 7)], schema=["a"])
        >>> df.select(trunc(col("a"), lit("QUARTER"))).collect()
        [Row(TRUNC("A", 'QUARTER')=datetime.date(2022, 10, 1)), Row(TRUNC("A", 'QUARTER')=datetime.date(2022, 1, 1)), Row(TRUNC("A", 'QUARTER')=datetime.date(2022, 7, 1))]

        >>> df = session.createDataFrame([datetime.datetime(2022, 12, 25, 13, 59, 38, 467)], schema=["a"])
        >>> df.collect()
        [Row(A=datetime.datetime(2022, 12, 25, 13, 59, 38, 467))]
        >>> df.select(trunc(col("a"), lit("MINUTE"))).collect()
        [Row(TRUNC("A", 'MINUTE')=datetime.datetime(2022, 12, 25, 13, 59))]

    truncNFr}   ry   r  r  s         rV   r  r  @  sg    P 7@
g5z
2TCq'"A ec5\* 	EU#E7+ 
 '1icYOOrY   c                     t        | t              st        d      t        |d      }t        |d      }t	        d| |||      S )a2  Adds the specified value for the specified date or time part to date or time expr.

    `Supported date and time parts <https://docs.snowflake.com/en/sql-reference/functions-date-time.html#label-supported-date-time-parts>`_

    Example::

        >>> # add one year on dates
        >>> import datetime
        >>> date_df = session.create_dataframe([[datetime.date(2020, 1, 1)]], schema=["date_col"])
        >>> date_df.select(dateadd("year", lit(1), col("date_col")).alias("year_added")).show()
        ----------------
        |"YEAR_ADDED"  |
        ----------------
        |2021-01-01    |
        ----------------
        <BLANKLINE>
        >>> date_df.select(dateadd("month", lit(1), col("date_col")).alias("month_added")).show()
        -----------------
        |"MONTH_ADDED"  |
        -----------------
        |2020-02-01     |
        -----------------
        <BLANKLINE>
        >>> date_df.select(dateadd("day", lit(1), col("date_col")).alias("day_added")).show()
        ---------------
        |"DAY_ADDED"  |
        ---------------
        |2020-01-02   |
        ---------------
        <BLANKLINE>

    Args:
        part: The time part to use for the addition
        col1: The first timestamp column or addend in the dateadd
        col2: The second timestamp column or the addend in the dateadd
    r  r  r}   r  r  s         rV   r  r  s  sF    P dC 011	i	(B	i	(B)T2rYGGrY   c                 n    t        | t              st        d      t        |d      }t	        d| ||      S )a&  
    Extracts the specified date or time part from a date, time, or timestamp. See
    `DATE_PART <https://docs.snowflake.com/en/sql-reference/functions/date_part.html>`_ for details.

    Args:
        part: The time part to use for the addition.
        e: The column expression of a date, time, or timestamp.

    Example::

        >>> import datetime
        >>> df = session.create_dataframe([[datetime.datetime(2023, 1, 1, 1, 1, 1)]], schema=["ts_col"])
        >>> df.select(date_part("year", col("ts_col")).alias("year"), date_part("epoch_second", col("ts_col")).alias("epoch_second")).show()
        ---------------------------
        |"YEAR"  |"EPOCH_SECOND"  |
        ---------------------------
        |2023    |1672534861      |
        ---------------------------
        <BLANKLINE>
    r  	date_partr}   r  )r  r   rQ   r   s       rV   r  r    s7    , dC 011q+&A+tQ)DDrY   mc                     |rt        d| ||g      nd}t        | d      }t        |d      }t        |d      }t        d|||||      S )a
  
    Creates a date from individual numeric components that represent the year, month, and day of the month.

    Example::
        >>> df = session.create_dataframe([[2022, 4, 1]], schema=["year", "month", "day"])
        >>> df.select(date_from_parts("year", "month", "day")).collect()
        [Row(DATE_FROM_PARTS("YEAR", "MONTH", "DAY")=datetime.date(2022, 4, 1))]
        >>> session.table("dual").select(date_from_parts(2022, 4, 1)).collect()
        [Row(DATE_FROM_PARTS(2022, 4, 1)=datetime.date(2022, 4, 1))]
    date_from_partsNry   )r%   r:   r   )r  r  r  rQ   rn   r  m_cold_cols           rV   r	  r	    s_    $ @I
/!Q
;dC!!%67E!!%67E!!%67E5%SI rY   c                 n    t        | t              st        d      t        |d      }t	        d| ||      S )a  
    Truncates a DATE, TIME, or TIMESTAMP to the specified precision.

    Note that truncation is not the same as extraction. For example:
    - Truncating a timestamp down to the quarter returns the timestamp corresponding to midnight of the first day of the
    quarter for the input timestamp.
    - Extracting the quarter date part from a timestamp returns the quarter number of the year in the timestamp.

    Example::
        >>> import datetime
        >>> df = session.create_dataframe(
        ...     [[datetime.datetime.strptime("2020-05-01 13:11:20.000", "%Y-%m-%d %H:%M:%S.%f")]],
        ...     schema=["a"],
        ... )
        >>> df.select(date_trunc("YEAR", "a"), date_trunc("MONTH", "a"), date_trunc("DAY", "a")).collect()
        [Row(DATE_TRUNC('YEAR', "A")=datetime.datetime(2020, 1, 1, 0, 0), DATE_TRUNC('MONTH', "A")=datetime.datetime(2020, 5, 1, 0, 0), DATE_TRUNC('DAY', "A")=datetime.datetime(2020, 5, 1, 0, 0))]
        >>> df.select(date_trunc("HOUR", "a"), date_trunc("MINUTE", "a"), date_trunc("SECOND", "a")).collect()
        [Row(DATE_TRUNC('HOUR', "A")=datetime.datetime(2020, 5, 1, 13, 0), DATE_TRUNC('MINUTE', "A")=datetime.datetime(2020, 5, 1, 13, 11), DATE_TRUNC('SECOND', "A")=datetime.datetime(2020, 5, 1, 13, 11, 20))]
        >>> df.select(date_trunc("QUARTER", "a")).collect()
        [Row(DATE_TRUNC('QUARTER', "A")=datetime.datetime(2020, 4, 1, 0, 0))]
    r  
date_truncr}   r  )r  r   rQ   r  s       rV   r  r    s7    . dC 011dL1H,h)LLrY   c                 6    t        | d      }t        d||      S )a  
    Extracts the three-letter day-of-week name from the specified date or timestamp.

    Example::
        >>> import datetime
        >>> df = session.create_dataframe(
        ...     [[datetime.datetime.strptime("2020-05-01 13:11:20.000", "%Y-%m-%d %H:%M:%S.%f")]],
        ...     schema=["a"],
        ... )
        >>> df.select(dayname("a")).collect()
        [Row(DAYNAME("A")='Fri')]
    daynamer}   r   r   s      rV   r  r    s     	q)$A)Q)<<rY   c                 6    t        | d      }t        d||      S )a  
    Extracts the corresponding day (number) of the month from a date or timestamp.

    Example::
        >>> import datetime
        >>> df = session.create_dataframe(
        ...     [[datetime.datetime.strptime("2020-05-01 13:11:20.000", "%Y-%m-%d %H:%M:%S.%f")]],
        ...     schema=["a"],
        ... )
        >>> df.select(dayofmonth("a")).collect()
        [Row(DAYOFMONTH("A")=1)]
    
dayofmonthr}   r   r   s      rV   r  r  	  s     	q,'A,Y??rY   c                 6    t        | d      }t        d||      S )a  
    Extracts the corresponding day (number) of the week from a date or timestamp.

    Example::
        >>> import datetime
        >>> df = session.create_dataframe(
        ...     [[datetime.datetime.strptime("2020-05-01 13:11:20.000", "%Y-%m-%d %H:%M:%S.%f")]],
        ...     schema=["a"],
        ... )
        >>> df.select(dayofweek("a")).collect()
        [Row(DAYOFWEEK("A")=5)]
    	dayofweekr}   r   r   s      rV   r  r    rA  rY   c                 6    t        | d      }t        d||      S )a  
    Extracts the corresponding day (number) of the year from a date or timestamp.

    Example::
        >>> import datetime
        >>> df = session.create_dataframe(
        ...     [[datetime.datetime.strptime("2020-05-01 13:11:20.000", "%Y-%m-%d %H:%M:%S.%f")]],
        ...     schema=["a"],
        ... )
        >>> df.select(dayofyear("a")).collect()
        [Row(DAYOFYEAR("A")=122)]
    	dayofyearr}   r   r   s      rV   r  r  -  rA  rY   time_columnwindow_durationslide_duration
start_timec                 j   |rt        d      |rt        d| |g|g n|gz   |g n|gz         nd}t        dd      j                  t	        t
        j                        d      }t        | d      }t        |      \  }}t        |d      }| d}|}	|r%t        |      \  }
}|	t        di | d|
id	diz  }	t        t        ||	|d      |z  d      }t        |||z  |	d      }t        t        d
d      |t        dd      t        |||d      d      j                  d      }||_        |S )aI  
    Converts a time column into a window object with start and end times. Window start times are
    inclusive while end times are exclusive. For example 9:30 is in the window [9:30, 10:00), but not [9:00, 9:30).

    Args:
        time_column: The column to apply the window transformation to.
        window_duration: An interval string that determines the length of each window.
        slide_duration: An interval string representing the amount of time in-between the start of
            each window. Note that this parameter is not supported yet. Specifying it will raise a
            NotImplementedError exception.
        start_time: An interval string representing the amount of time the start of each window is
            offset. eg. a five minute window with start_time of '2 minutes' will be from [9:02, 9:07)
            instead of [9:00, 9:05)

    Note:
        Interval strings are of the form 'quantity unit' where quantity is an integer and unitis
        is a supported time unit. This function supports the same time units as dateadd. see
        `supported time units <https://docs.snowflake.com/en/sql-reference/functions-date-time#label-supported-date-time-parts>`_
        for more information.

    Example::

        >>> import datetime
        >>> from snowflake.snowpark.functions import window
        >>> df = session.createDataFrame(
        ...      [(datetime.datetime.strptime("2024-10-31 09:05:00.000", "%Y-%m-%d %H:%M:%S.%f"),)],
        ...      schema=["time"]
        ... )
        >>> df.select(window(df.time, "5 minutes")).show()
        ----------------------------------------
        |"WINDOW"                              |
        ----------------------------------------
        |{                                     |
        |  "end": "2024-10-31 09:10:00.000",   |
        |  "start": "2024-10-31 09:05:00.000"  |
        |}                                     |
        ----------------------------------------
        <BLANKLINE>

        >>> df.select(window(df.time, "5 minutes", start_time="2 minutes")).show()
        ----------------------------------------
        |"WINDOW"                              |
        ----------------------------------------
        |{                                     |
        |  "end": "2024-10-31 09:07:00.000",   |
        |  "start": "2024-10-31 09:02:00.000"  |
        |}                                     |
        ----------------------------------------
        <BLANKLINE>

    Example::

        >>> import datetime
        >>> from snowflake.snowpark.functions import sum, window
        >>> df = session.createDataFrame([
        ...         (datetime.datetime(2024, 10, 31, 1, 0, 0), 1),
        ...         (datetime.datetime(2024, 10, 31, 2, 0, 0), 1),
        ...         (datetime.datetime(2024, 10, 31, 3, 0, 0), 1),
        ...         (datetime.datetime(2024, 10, 31, 4, 0, 0), 1),
        ...         (datetime.datetime(2024, 10, 31, 5, 0, 0), 1),
        ...     ], schema=["time", "value"]
        ... )
        >>> df.group_by(window(df.time, "2 hours")).agg(sum(df.value)).sort("window").show()
        -------------------------------------------------------
        |"WINDOW"                              |"SUM(VALUE)"  |
        -------------------------------------------------------
        |{                                     |1             |
        |  "end": "2024-10-31 02:00:00.000",   |              |
        |  "start": "2024-10-31 00:00:00.000"  |              |
        |}                                     |              |
        |{                                     |2             |
        |  "end": "2024-10-31 04:00:00.000",   |              |
        |  "start": "2024-10-31 02:00:00.000"  |              |
        |}                                     |              |
        |{                                     |2             |
        |  "end": "2024-10-31 06:00:00.000",   |              |
        |  "start": "2024-10-31 04:00:00.000"  |              |
        |}                                     |              |
        -------------------------------------------------------
        <BLANKLINE>
    zRsnowflake.snowpark.functions.window does not support slide_duration parameter yet.windowNz1970-01-01 00:00:00Fr}   )timezoner@  rQ   r  endrT   )NotImplementedErrorr%   rj   rI  rD   rC   NTZr9   r-   make_intervalr  r  r  r   rV  rz   )r  r  r  r  rQ   rn   epochtimewindow_unitr  start_duration
start_unitr  window_startr   s                  rV   r  r  ?  s   r  "`
 	
  	/*#+r.1AC'rj\;	
   %7<<0445 = E +x0D#8#I O[/U;O M#KD%::%F"
TJ<q!1> BTeTTdDE:_LF ;(@$RWXL
$Gu%EU#_leL fX  CHJrY   c                 6    t        | d      }t        d||      S )aS  
    Returns true if the specified VARIANT column contains an ARRAY value.

    Examples::

        >>> df = session.create_dataframe([[["element"], True]], schema=["a", "b"])
        >>> df.select(is_array(df["a"]).alias("is_array_a"), is_array(df["b"]).alias("is_array_b")).collect()
        [Row(IS_ARRAY_A=True, IS_ARRAY_B=False)]
    is_arrayr}   r   r  s      rV   r(  r(    s     	sJ'A*a9==rY   c                 6    t        | d      }t        d||      S )a  
    Returns true if the specified VARIANT column contains a boolean value.

    Examples::

        >>> from snowflake.snowpark.types import StructField, VariantType
        >>> df = session.create_dataframe([[True, 'X']], schema=["a", "b"])
        >>> df.select(is_boolean(to_variant(df["a"])).alias("boolean"), is_boolean(to_variant(df["b"])).alias("varchar")).collect()
        [Row(BOOLEAN=True, VARCHAR=False)]
    
is_booleanr}   r   r  s      rV   r*  r*         	sL)A,Y??rY   c                 6    t        | d      }t        d||      S )a  
    Returns true if the specified VARIANT column contains a binary value.

    Examples::

        >>> from snowflake.snowpark.types import StructField, VariantType
        >>> df = session.create_dataframe([[b"snow", "snow"]], schema=["a", "b"])
        >>> df.select(is_binary(to_variant(df["a"])).alias("binary"), is_binary(to_variant(df["b"])).alias("varchar")).collect()
        [Row(BINARY=True, VARCHAR=False)]
    	is_binaryr}   r   r  s      rV   r-  r-         	sK(A+qI>>rY   c                 6    t        | d      }t        d||      S )a  
    Returns true if the specified VARIANT column contains a string.

    Examples::

        >>> from snowflake.snowpark.types import StructField, VariantType
        >>> df = session.create_dataframe([["abc", 123]], schema=["a", "b"])
        >>> df.select(is_char(to_variant(df["a"])).alias("varchar"), is_char(to_variant(df["b"])).alias("int")).collect()
        [Row(VARCHAR=True, INT=False)]
    is_charr}   r   r  s      rV   r0  r0         	sI&A)Q)<<rY   c                 6    t        | d      }t        d||      S )a  
    Returns true if the specified VARIANT column contains a date value.

    Examples::

        >>> import datetime
        >>> from snowflake.snowpark.types import StructField, VariantType
        >>> df = session.create_dataframe([[datetime.date(2023, 3, 2), 123]], schema=["a", "b"])
        >>> df.select(is_date(to_variant(df["a"])).alias("date"), is_date(to_variant(df["b"])).alias("int")).collect()
        [Row(DATE=True, INT=False)]
    is_dater}   r   r  s      rV   r3  r3  
       	sI&A)Q)<<rY   c                 6    t        | d      }t        d||      S )a  
    Returns true if the specified VARIANT column contains a fixed-point decimal value or integer.

    Examples::

        >>> import decimal
        >>> from snowflake.snowpark.types import StructField, VariantType
        >>> df = session.create_dataframe([[decimal.Decimal(1), "X"]], schema=["a", "b"])
        >>> df.select(is_decimal(to_variant(df["a"])).alias("decimal"), is_decimal(to_variant(df["b"])).alias("varchar")).collect()
        [Row(DECIMAL=True, VARCHAR=False)]
    
is_decimalr}   r   r  s      rV   r6  r6    s     	sL)A,Y??rY   c                 6    t        | d      }t        d||      S )a  
    Returns true if the specified VARIANT column contains a floating-point value, fixed-point decimal, or integer.

    Examples::

        >>> from snowflake.snowpark.types import StructField, VariantType
        >>> df = session.create_dataframe([[1.2, "X"]], schema=["a", "b"])
        >>> df.select(is_double(to_variant(df["a"])).alias("double"), is_double(to_variant(df["b"])).alias("varchar")).collect()
        [Row(DOUBLE=True, VARCHAR=False)]
    	is_doubler}   r   r  s      rV   r8  r8  /  r.  rY   c                 6    t        | d      }t        d||      S )a  
    Returns true if the specified VARIANT column contains a floating-point value, fixed-point decimal, or integer.

    Example::

        >>> from snowflake.snowpark.functions import to_variant, is_real
        >>> df = session.create_dataframe([[1.2, "X"]], schema=["a", "b"])
        >>> df.select(is_real(to_variant("a")).as_("a"), is_real(to_variant("b")).as_("b")).collect()
        [Row(A=True, B=False)]
    is_realr}   r   r  s      rV   r:  r:  ?  r1  rY   c                 6    t        | d      }t        d||      S )a  
    Returns true if the specified VARIANT column contains a integer value.

    Examples::

        >>> from snowflake.snowpark.types import StructField, VariantType
        >>> df = session.create_dataframe([[1, "X"]], schema=["a", "b"])
        >>> df.select(is_integer(to_variant(df["a"])).alias("int"), is_integer(to_variant(df["b"])).alias("varchar")).collect()
        [Row(INT=True, VARCHAR=False)]
    
is_integerr}   r   r  s      rV   r<  r<  O  r+  rY   c                 6    t        | d      }t        d||      S )a  
    Returns true if the specified VARIANT column contains a JSON null value.

    Example::

        >>> from snowflake.snowpark.functions import to_variant, is_null_value
        >>> df = session.create_dataframe([[{"a": "foo"}], [{"a": None}], [None]], schema=["a"])
        >>> df.select(is_null_value(to_variant("a")["a"]).as_("a")).collect()
        [Row(A=False), Row(A=True), Row(A=None)]
    is_null_valuer}   r   r  s      rV   r>  r>  _  s     	sO,A/1	BBrY   c                 6    t        | d      }t        d||      S )a  
    Returns true if the specified VARIANT column contains an OBJECT value.

    Example::

        >>> from snowflake.snowpark.functions import to_variant, is_object
        >>> df = session.create_dataframe([[[1, 2], {"a": "snow"}]], schema=["a", "b"])
        >>> df.select(is_object(to_variant("a")).as_("a"), is_object(to_variant("b")).as_("b")).collect()
        [Row(A=False, B=True)]
    	is_objectr}   r   r  s      rV   r@  r@  o  r.  rY   c                 6    t        | d      }t        d||      S )a  
    Returns true if the specified VARIANT column contains a TIME value.

    Example::

        >>> import datetime
        >>> from snowflake.snowpark.functions import to_variant, is_time
        >>> df = session.create_dataframe([[datetime.time(10, 10), "X"]], schema=["a", "b"])
        >>> df.select(is_time(to_variant("a")).as_("a"), is_time(to_variant("b")).as_("b")).collect()
        [Row(A=True, B=False)]
    is_timer}   r   r  s      rV   rB  rB    r4  rY   c                 6    t        | d      }t        d||      S )a5  
    Returns true if the specified VARIANT column contains a TIMESTAMP_LTZ value to be
    interpreted using the local time zone.

    Example::

        >>> from snowflake.snowpark.functions import to_variant, is_timestamp_ltz
        >>> df = session.sql("select to_timestamp_ntz('2017-02-24 12:00:00.456') as timestamp_ntz1, "
        ...                  "to_timestamp_ltz('2017-02-24 13:00:00.123 +01:00') as timestamp_ltz1, "
        ...                  "to_timestamp_tz('2017-02-24 13:00:00.123 +01:00') as timestamp_tz1")
        >>> df.select(is_timestamp_ltz(to_variant("timestamp_ntz1")).as_("a"),
        ...           is_timestamp_ltz(to_variant("timestamp_ltz1")).as_("b"),
        ...           is_timestamp_ltz(to_variant("timestamp_tz1")).as_("c")).collect()
        [Row(A=False, B=True, C=False)]
    is_timestamp_ltzr}   r   r  s      rV   rD  rD    s!    " 	s./A,a9EErY   c                 6    t        | d      }t        d||      S )a  
    Returns true if the specified VARIANT column contains a TIMESTAMP_NTZ value with no time zone.

    Example::

        >>> from snowflake.snowpark.functions import to_variant, is_timestamp_ntz
        >>> df = session.sql("select to_timestamp_ntz('2017-02-24 12:00:00.456') as timestamp_ntz1, "
        ...                  "to_timestamp_ltz('2017-02-24 13:00:00.123 +01:00') as timestamp_ltz1, "
        ...                  "to_timestamp_tz('2017-02-24 13:00:00.123 +01:00') as timestamp_tz1")
        >>> df.select(is_timestamp_ntz(to_variant("timestamp_ntz1")).as_("a"),
        ...           is_timestamp_ntz(to_variant("timestamp_ltz1")).as_("b"),
        ...           is_timestamp_ntz(to_variant("timestamp_tz1")).as_("c")).collect()
        [Row(A=True, B=False, C=False)]
    is_timestamp_ntzr}   r   r  s      rV   rF  rF    s!      	s./A,a9EErY   c                 6    t        | d      }t        d||      S )a  
    Returns true if the specified VARIANT column contains a TIMESTAMP_TZ value with a time zone.

    Example::

        >>> from snowflake.snowpark.functions import to_variant, is_timestamp_tz
        >>> df = session.sql("select to_timestamp_ntz('2017-02-24 12:00:00.456') as timestamp_ntz1, "
        ...                  "to_timestamp_ltz('2017-02-24 13:00:00.123 +01:00') as timestamp_ltz1, "
        ...                  "to_timestamp_tz('2017-02-24 13:00:00.123 +01:00') as timestamp_tz1")
        >>> df.select(is_timestamp_tz(to_variant("timestamp_ntz1")).as_("a"),
        ...           is_timestamp_tz(to_variant("timestamp_ltz1")).as_("b"),
        ...           is_timestamp_tz(to_variant("timestamp_tz1")).as_("c")).collect()
        [Row(A=False, B=False, C=True)]
    is_timestamp_tzr}   r   r  s      rV   rH  rH    s!      	s-.A+Q)DDrY   	func_nameargs.c                 f     t        |      dvrt        d        t         fd|D              }|S )N)rK      z#Incorrect number of args passed to c              3   6   K   | ]  }t        |        y wN)r:   ).0r  rI  s     rV   	<genexpr>z0_columns_from_timestamp_parts.<locals>.<genexpr>  s     G3&sI6Gs   )r   r  r   )rI  rJ  s   ` rV   _columns_from_timestamp_partsrQ    s9     4y>ykJKKG$GGDKrY   kwargsc           
         t        |      }|dk(  r"t        |d   |       }t        |d   |       }||fS d|cxk  rdk  rn nt        | g|d d  \  }}}}	}
}|dk\  r|d   n|j                  d      }|dk(  r|d   n|j                  d      }|| d	k7  rt	        |  d
      |d nt        ||       }|d nt        ||       }||
||||	|
|||fS |	||||	|
||fS |||||	|
|t        dd      |fS ||||	|
|fS t	        |  d|       )Nr  r   r   rL        nanosecondsr  timestamp_from_partsz( does not accept timezone as an argumentFr}   z0 expected 2, 6, 7 or 8  required arguments, got )r   r9   rQ  getr  r:   r8   rj   )rI  rJ  rR  num_args	date_expr	time_exprr  r  r  hrA  r@  ns_argtz_argnsr  s                   rV   _timestamp_from_parts_internalr`    su    4yH1}"47I6	"47I6	)##	
h	!	;IQRaQ1aD!$Mavzz-/H$Mavzz*/E)/E"E	{*RSTT^T)>vy)Q^T)<VY)O>bnaAtQB..^aAtQ**^aAtQA(?CCaAtQ&&kI(T
 	
rY   r  r  r  rV  c           
          |rt        d| ||g|g n|gz         nd}t        d| ||      \  }}}|rt        d|||t        |d      ||      S t        d|||||      S )a9  
    Creates a time from individual numeric components.

    TIME_FROM_PARTS is typically used to handle values in "normal" ranges (e.g. hours 0-23, minutes 0-59),
    but it also handles values from outside these ranges. This allows, for example, choosing the N-th minute
    in a day, which can be used to simplify some computations.

    Example::

        >>> df = session.create_dataframe(
        ...     [[11, 11, 0, 987654321], [10, 10, 0, 987654321]],
        ...     schema=["hour", "minute", "second", "nanoseconds"],
        ... )
        >>> df.select(time_from_parts(
        ...     "hour", "minute", "second", nanoseconds="nanoseconds"
        ... ).alias("TIME_FROM_PARTS")).collect()
        [Row(TIME_FROM_PARTS=datetime.time(11, 11, 0, 987654)), Row(TIME_FROM_PARTS=datetime.time(10, 10, 0, 987654))]
    time_from_partsNry   )r%   rQ  r   r:   )	r  r  r  rV  rQ   rn   r\  r  r@  s	            rV   rb  rb    s    B 	 	66"K,?bk]S	

   ,,=tVVTGAq!  	!+/@A	
 -q!QSIVrY   rZ  r[  c                      y rN  rT   rZ  r[  rQ   s      rV   rW  rW  /      
 rY   r  r  r  
nanosecondr  c	                      y rN  rT   )	r  r  r  r  r  r  rf  r  rQ   s	            rV   rW  rW  7  s     rY   c                 \    | rt        d|      nd}t        dgt        dg|i ||| dS )a  
    Creates a timestamp from individual numeric components. If no time zone is in effect,
    the function can be used to create a timestamp from a date expression and a time expression.

    Example 1::

        >>> df = session.create_dataframe(
        ...     [[2022, 4, 1, 11, 11, 0], [2022, 3, 31, 11, 11, 0]],
        ...     schema=["year", "month", "day", "hour", "minute", "second"],
        ... )
        >>> df.select(timestamp_from_parts(
        ...     "year", "month", "day", "hour", "minute", "second"
        ... ).alias("TIMESTAMP_FROM_PARTS")).collect()
        [Row(TIMESTAMP_FROM_PARTS=datetime.datetime(2022, 4, 1, 11, 11)), Row(TIMESTAMP_FROM_PARTS=datetime.datetime(2022, 3, 31, 11, 11))]

    Example 2::

        >>> df = session.create_dataframe(
        ...     [['2022-04-01', '11:11:00'], ['2022-03-31', '11:11:00']],
        ...     schema=["date", "time"]
        ... )
        >>> df.select(
        ...     timestamp_from_parts(to_date("date"), to_time("time")
        ... ).alias("TIMESTAMP_FROM_PARTS")).collect()
        [Row(TIMESTAMP_FROM_PARTS=datetime.datetime(2022, 4, 1, 11, 11)), Row(TIMESTAMP_FROM_PARTS=datetime.datetime(2022, 3, 31, 11, 11))]
    rW  Nry   r%   r   r`  rQ   rJ  rR  rn   s       rV   rW  rW  G  sM    : @I
4d
;dC	'(>	P	P	P 	 rY   c                     |rt        d| |||||g|g n|gz         nd}d}	t        |	| |||||      \  }
}}}}}|dnt        ||	      }|t        |	|
|||||||	      S t        |	|
||||||||
      S )a  
    Creates a timestamp from individual numeric components.

    Example::

        >>> import datetime
        >>> df = session.create_dataframe(
        ...     [[2022, 4, 1, 11, 11, 0], [2022, 3, 31, 11, 11, 0]],
        ...     schema=["year", "month", "day", "hour", "minute", "second"],
        ... )
        >>> df.select(timestamp_ltz_from_parts(
        ...     "year", "month", "day", "hour", "minute", "second"
        ... ).alias("TIMESTAMP_LTZ_FROM_PARTS")).collect()
        [Row(TIMESTAMP_LTZ_FROM_PARTS=datetime.datetime(2022, 4, 1, 11, 11, tzinfo=<DstTzInfo 'America/Los_Angeles' PDT-1 day, 17:00:00 DST>)), Row(TIMESTAMP_LTZ_FROM_PARTS=datetime.datetime(2022, 3, 31, 11, 11, tzinfo=<DstTzInfo 'America/Los_Angeles' PDT-1 day, 17:00:00 DST>))]
    timestamp_ltz_from_partsNry   )r%   rQ  r:   r   )r  r  r  r  r  r  rV  rQ   rn   rI  r  r  r  r\  rA  r@  r_  s                    rV   rl  rl  m  s    B  	&5#tVV4 (r{m=	
   +I74T66Aq!Qa $*?Y*WB : 	y!Q1dAC9U q!Q4BSI
rY   c                      y rN  rT   rd  s      rV   timestamp_ntz_from_partsrn    re  rY   c                      y rN  rT   )r  r  r  r  r  r  rf  rQ   s           rV   rn  rn    s     rY   c                 \    | rt        d|      nd}t        dgt        dg|i ||| dS )a  
    Creates a timestamp from individual numeric components. The function can be used to
    create a timestamp from a date expression and a time expression.

    Example 1::

        >>> df = session.create_dataframe(
        ...     [[2022, 4, 1, 11, 11, 0], [2022, 3, 31, 11, 11, 0]],
        ...     schema=["year", "month", "day", "hour", "minute", "second"],
        ... )
        >>> df.select(timestamp_ntz_from_parts(
        ...     "year", "month", "day", "hour", "minute", "second"
        ... ).alias("TIMESTAMP_NTZ_FROM_PARTS")).collect()
        [Row(TIMESTAMP_NTZ_FROM_PARTS=datetime.datetime(2022, 4, 1, 11, 11)), Row(TIMESTAMP_NTZ_FROM_PARTS=datetime.datetime(2022, 3, 31, 11, 11))]

    Example 2::

        >>> df = session.create_dataframe(
        ...     [['2022-04-01', '11:11:00'], ['2022-03-31', '11:11:00']],
        ...     schema=["date", "time"]
        ... )
        >>> df.select(
        ...     timestamp_ntz_from_parts(to_date("date"), to_time("time")
        ... ).alias("TIMESTAMP_NTZ_FROM_PARTS")).collect()
        [Row(TIMESTAMP_NTZ_FROM_PARTS=datetime.datetime(2022, 4, 1, 11, 11)), Row(TIMESTAMP_NTZ_FROM_PARTS=datetime.datetime(2022, 3, 31, 11, 11))]
    rn  Nry   ri  rj  s       rV   rn  rn    sX    8 DM
8$
?RVC"		'&



 

	 	 	rY   c	                    |r"t        d| |||||g|g n|gz   |g n|gz         nd}	d}
t        |
| |||||      \  }}}}}}|dnt        ||
      }|dnt        ||
      }||t	        |
|||||||||	|      S |t	        |
||||||||	|
      S |!t	        |
||||||t        dd      ||	|      S t	        |
|||||||	|	      S )a  
    Creates a timestamp from individual numeric components and a string timezone.

    Example::

        >>> df = session.create_dataframe(
        ...     [[2022, 4, 1, 11, 11, 0, 'America/Los_Angeles'], [2022, 3, 31, 11, 11, 0, 'America/Los_Angeles']],
        ...     schema=["year", "month", "day", "hour", "minute", "second", "timezone"],
        ... )
        >>> df.select(timestamp_tz_from_parts(
        ...     "year", "month", "day", "hour", "minute", "second", timezone="timezone"
        ... ).alias("TIMESTAMP_TZ_FROM_PARTS")).collect()
        [Row(TIMESTAMP_TZ_FROM_PARTS=datetime.datetime(2022, 4, 1, 11, 11, tzinfo=pytz.FixedOffset(-420))), Row(TIMESTAMP_TZ_FROM_PARTS=datetime.datetime(2022, 3, 31, 11, 11, tzinfo=pytz.FixedOffset(-420)))]
    timestamp_tz_from_partsNry   r   Fr}   )r%   rQ  r:   r8   r   rj   )r  r  r  r  r  r  rV  r  rQ   rn   rI  r  r  r  r\  rA  r@  r_  r  s                      rV   rr  rr    s[   D  	%5#tVV4 (r{m=%rH:7	
   *I74T66Aq!Qa $*?Y*WB!':8Y'OB8#7q!Q4B	
 	
 
	 q!Q4BSI
 	
 
	U#
 	
 )Q1aqsiXXrY   c                 6    t        | d      }t        d||      S )a  
    Extracts the corresponding week (number) of the year from a date or timestamp.

    Example::

        >>> import datetime
        >>> df = session.create_dataframe(
        ...     [[datetime.datetime.strptime("2020-05-01 13:11:20.000", "%Y-%m-%d %H:%M:%S.%f")]],
        ...     schema=["a"],
        ... )
        >>> df.select(weekofyear("a")).collect()
        [Row(WEEKOFYEAR("A")=18)]
    
weekofyearr}   r   r   s      rV   rt  rt  (  s     	q,'A,Y??rY   c                 6    t        | d      }t        d||      S )ai  Reports the type of a value stored in a VARIANT column. The type is returned as a string.

    For columns where all rows share the same type, the result of `typeof` is the underlying Snowflake column type.

    Example::

        >>> df = session.create_dataframe([1, 2, 3], schema=["A"])
        >>> df.select(typeof(col("A")).as_("ans")).collect()
        [Row(ANS='INTEGER'), Row(ANS='INTEGER'), Row(ANS='INTEGER')]

    For columns of VARIANT type, the underlying stored type is returned.

    Example::

        >>> from snowflake.snowpark.types import VariantType, StructType, StructField
        >>> schema = StructType([StructField("A", VariantType())])
        >>> df = session.create_dataframe([1, 3.1, 'test'], schema=schema)
        >>> df.select(typeof(col("A")).as_("ans")).collect()
        [Row(ANS='INTEGER'), Row(ANS='DECIMAL'), Row(ANS='VARCHAR')]

    typeofr}   r   r  s      rV   rv  rv  ;  s    . 	sH%A(A;;rY   c                 6    t        | d      }t        d||      S )a  Checks the validity of a JSON document.
    If the input string is a valid JSON document or a NULL (i.e. no error would occur when
    parsing the input string), the function returns NULL.
    In case of a JSON parsing error, the function returns a string that contains the error
    message.

    Example::

        >>> df = session.create_dataframe(["{'ValidKey1': 'ValidValue1'}", "{'Malformed -- missing val':}", None], schema=['a'])
        >>> df.select(check_json(df.a)).show()
        -----------------------
        |"CHECK_JSON(""A"")"  |
        -----------------------
        |NULL                 |
        |misplaced }, pos 29  |
        |NULL                 |
        -----------------------
        <BLANKLINE>
    
check_jsonr}   r   r  s      rV   rx  rx  V  s    * 	sL)A,Y??rY   c                 6    t        | d      }t        d||      S )a  Checks the validity of an XML document.
    If the input string is a valid XML document or a NULL (i.e. no error would occur when parsing
    the input string), the function returns NULL.
    In case of an XML parsing error, the output string contains the error message.

    Example::

        >>> df = session.create_dataframe(["<name> Valid </name>", "<name> Invalid </WRONG_CLOSING_TAG>", None], schema=['a'])
        >>> df.select(check_xml(df.a)).show()
        ---------------------------------------------------
        |"CHECK_XML(""A"")"                               |
        ---------------------------------------------------
        |NULL                                             |
        |no opening tag for </WRONG_CLOSING_TAG>, pos 35  |
        |NULL                                             |
        ---------------------------------------------------
        <BLANKLINE>
    	check_xmlr}   r   r  s      rV   rz  rz  o  s    ( 	sK(A+qI>>rY   c                 P    t        | d      }t        |d      }t        d|||      S )a  
    Parses a JSON string and returns the value of an element at a specified path in the resulting
    JSON document.

    Example::

        >>> from snowflake.snowpark.functions import json_extract_path_text, to_variant
        >>> df = session.create_dataframe([[{"a": "foo"}, "a"], [{"a": None}, "a"], [{"a": "foo"}, "b"], [None, "a"]], schema=["k", "v"])
        >>> df.select(json_extract_path_text(to_variant("k"), "v").as_("res")).collect()
        [Row(RES='foo'), Row(RES=None), Row(RES=None), Row(RES=None)]
    json_extract_path_textr}   r   )rW   r!  rQ   r   r  s        rV   r|  r|    s0     	s45At56A2AqINNrY   c                 6    t        | d      }t        d||      S )a  Parse the value of the specified column as a JSON string and returns the
    resulting JSON document.

    Example::

        >>> df = session.create_dataframe([['{"key": "1"}']], schema=["a"])
        >>> df.select(parse_json(df["a"]).alias("result")).show()
        ----------------
        |"RESULT"      |
        ----------------
        |{             |
        |  "key": "1"  |
        |}             |
        ----------------
        <BLANKLINE>
    
parse_jsonr}   r   r   s      rV   r~  r~    s    $ 	q,'A,Y??rY   c                 6    t        | d      }t        d||      S )a3  Parse the value of the specified column as a JSON string and returns the
    resulting JSON document. Returns NULL if an error occurs during parsing.

    Example::
        >>> df = session.create_dataframe([['{"key": "1"}'], ['{"Open": "parenthesis"']], schema=["a"])
        >>> df.select(try_parse_json(df["a"]).alias("result")).show()
        ----------------
        |"RESULT"      |
        ----------------
        |{             |
        |  "key": "1"  |
        |}             |
        |NULL          |
        ----------------
        <BLANKLINE>
    try_parse_jsonr}   r   r   s      rV   r  r    s!    $ 	q*+A*ACCrY   schemac                    |rt        d| |g      nd}t        | d      }t        |t              rt	        |      }t        | d      j                  |d      j                  d|j                          d      }||_	        |S )a\  Parses a column contains a JSON string value into a column of the type specified by schema.
    Schema can be defined as a DataType object or as a compatible type string.

    Example::

        >>> from snowflake.snowpark.types import MapType, StringType
        >>> df = session.create_dataframe([('{"key": "value"}',),], schema=["a"])
        >>> df.select(from_json(df.a, MapType(StringType(), StringType()))).show()
        ----------------------
        |"from_json(""A"")"  |
        ----------------------
        |{                   |
        |  "key": "value"    |
        |}                   |
        ----------------------
        <BLANKLINE>

    Example::

        >>> df = session.create_dataframe([('[1, 2, 3]',),], schema=["b"])
        >>> df.select(from_json(df.b, "array<integer>")).show()
        ----------------------
        |"from_json(""B"")"  |
        ----------------------
        |[                   |
        |  1,                |
        |  2,                |
        |  3                 |
        |]                   |
        ----------------------
        <BLANKLINE>
    	from_jsonNFr}   z
from_json(rP  )
r%   r9   r   r  r+   r~  rI  rV  rS  rz   )r   r  rQ   rn   r   r   s         rV   r  r    s    H <E
kAv;
7$Cq+&A&#+F31&	f	&	*QZZ\N!,	- 
 CHJrY   c                 6    t        | d      }t        d||      S )a  Parse the value of the specified column as a JSON string and returns the
    resulting XML document.

    Example::

        >>> df = session.sql(
        ...     "select (column1) as v from values ('<t1>foo<t2>bar</t2><t3></t3></t1>'), "
        ...     "('<t1></t1>')"
        ... )
        >>> df.select(parse_xml("v").alias("result")).show()
        ------------------
        |"RESULT"        |
        ------------------
        |<t1>            |
        |  foo           |
        |  <t2>bar</t2>  |
        |  <t3></t3>     |
        |</t1>           |
        |<t1></t1>       |
        ------------------
        <BLANKLINE>
    	parse_xmlr}   r   r   s      rV   r  r    s    0 	q+&A+qI>>rY   c                 6    t        | d      }t        d||      S )a  Converts a JSON "null" value in the specified column to a SQL NULL value.
    All other VARIANT values in the column are returned unchanged.

    Example::
        >>> df = session.create_dataframe(
        ...     ["null", "1"],
        ...     schema=["S"],
        ... ).select(strip_null_value(parse_json(col("S"))).as_("B")).where(
        ...     sql_expr("B is null")
        ... )
        >>> df.collect()
        [Row(B=None)]
    strip_null_valuer}   r   r  s      rV   r  r    s!     	s./A,a9EErY   r   c                 ^    |rt        d| |g      nd}t        | d      }t        d||||      S )a  Returns the input values, pivoted into an ARRAY. If the input is empty, an empty
    ARRAY is returned.

    Example::
        >>> df = session.create_dataframe([[1], [2], [3], [1]], schema=["a"])
        >>> df.select(array_agg("a", True).within_group("a").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |[         |
        |  1,      |
        |  2,      |
        |  3       |
        |]         |
        ------------
        <BLANKLINE>
    	array_aggNr   r  )rW   r   rQ   rn   r   s        rV   r  r  '  sA    * CL
kC+=
>QUCsK(AQKcY rY   elementc                 P    t        | d      }t        |d      }t        d|||      S )ac  Returns an ARRAY containing all elements from the source ARRAY as well as the new element.
    The new element is located at end of the ARRAY.

    Args:
        array: The column containing the source ARRAY.
        element: The column containing the element to be appended. The element may be of almost
            any data type. The data type does not need to match the data type(s) of the
            existing elements in the ARRAY.

    Example::
        >>> from snowflake.snowpark import Row
        >>> df = session.create_dataframe([Row(a=[1, 2, 3])])
        >>> df.select(array_append("a", lit(4)).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |[         |
        |  1,      |
        |  2,      |
        |  3,      |
        |  4       |
        |]         |
        ------------
        <BLANKLINE>
    array_appendr}   r   r%  r  rQ   ar   s        rV   r  r  C  s-    : 	un-Aw/A.!Q)DDrY   c                     |rt        d| |g      nd}t        | d      }t        |t              rt	        |d      j                  dd      n|}t        d||||      S )a  Given a source ARRAY, returns an ARRAY with elements of the specified value removed.

    Args:
        array: name of column containing array.
        element: element to be removed from the array. If the element is a VARCHAR, it needs
            to be casted into VARIANT data type.

    Examples::
        >>> from snowflake.snowpark.types import VariantType
        >>> df = session.create_dataframe([([1, '2', 3.1, 1, 1],)], ['data'])
        >>> df.select(array_remove(df.data, 1).alias("objects")).show()
        -------------
        |"OBJECTS"  |
        -------------
        |[          |
        |  "2",     |
        |  3.1      |
        |]          |
        -------------
        <BLANKLINE>

        >>> df.select(array_remove(df.data, lit('2').cast(VariantType())).alias("objects")).show()
        -------------
        |"OBJECTS"  |
        -------------
        |[          |
        |  1,       |
        |  3.1,     |
        |  1,       |
        |  1        |
        |]          |
        -------------
        <BLANKLINE>

        >>> df.select(array_remove(df.data, None).alias("objects")).show()
        -------------
        |"OBJECTS"  |
        -------------
        |NULL       |
        -------------
        <BLANKLINE>

        >>> df.select(array_remove(array_remove(df.data, 1), "2").alias("objects")).show()
        -------------
        |"OBJECTS"  |
        -------------
        |[          |
        |  3.1      |
        |]          |
        -------------
        <BLANKLINE>

    See Also:
        - `ARRAY <https://docs.snowflake.com/en/sql-reference/data-types-semistructured#label-data-type-array>`_ for more details on semi-structured arrays.
    array_removeNFr}   VARIANTry   )r%   r9   r   r  rj   rI  r   )r%  r  rQ   rn   r  r   s         rV   r  r  e  so    z DM
nug.>
?RVCun-A gs# 	Gu%**9*F 
 .!QSINNrY   c                 P    t        | d      }t        |d      }t        d|||      S )au  Returns the concatenation of two ARRAYs.

    Args:
        array1: Column containing the source ARRAY.
        array2: Column containing the ARRAY to be appended to array1.

    Example::
        >>> from snowflake.snowpark import Row
        >>> df = session.create_dataframe([Row(a=[1, 2, 3], b=[4, 5])])
        >>> df.select(array_cat("a", "b").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |[         |
        |  1,      |
        |  2,      |
        |  3,      |
        |  4,      |
        |  5       |
        |]         |
        ------------
        <BLANKLINE>
    	array_catr}   r   r  s        rV   r  r    s-    6 
	,B		,B+r2CCrY   c                 6    t        | d      }t        d||      S )a  Returns a compacted ARRAY with missing and null values removed,
    effectively converting sparse arrays into dense arrays.

    Args:
        array: Column containing the source ARRAY to be compacted

    Example::
        >>> from snowflake.snowpark import Row
        >>> df = session.create_dataframe([Row(a=[1, None, 3])])
        >>> df.select("a", array_compact("a").alias("compacted")).show()
        -------------------------
        |"A"      |"COMPACTED"  |
        -------------------------
        |[        |[            |
        |  1,     |  1,         |
        |  null,  |  3          |
        |  3      |]            |
        |]        |             |
        -------------------------
        <BLANKLINE>
    array_compactr}   r   r%  rQ   r  s      rV   r  r    s    . 	uo.A/1	BBrY   c                 \    |D cg c]  }t        |d       }}t        dg|d| iS c c}w )a  Returns an ARRAY constructed from zero, one, or more inputs.

    Args:
        cols: Columns containing the values (or expressions that evaluate to values). The
            values do not all need to be of the same data type.

    Example::
        >>> df = session.create_dataframe([[1, 2], [3, 4]], schema=["a", "b"])
        >>> df.select(array_construct("a", "b").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |[         |
        |  1,      |
        |  2       |
        |]         |
        |[         |
        |  3,      |
        |  4       |
        |]         |
        ------------
        <BLANKLINE>
    array_constructrQ   r   rQ   r   r   r   s       rV   r  r    s:    2 9=	=1.-
.	=B	=+FbFIFF 
>r/  c                 \    |D cg c]  }t        |d       }}t        dg|d| iS c c}w )a  Returns an ARRAY constructed from zero, one, or more inputs.
    The constructed ARRAY omits any NULL input values.

    Args:
        cols: Columns containing the values (or expressions that evaluate to values). The
            values do not all need to be of the same data type.

    Example::
        >>> df = session.create_dataframe([[1, None, 2], [3, None, 4]], schema=["a", "b", "c"])
        >>> df.select(array_construct_compact("a", "b", "c").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |[         |
        |  1,      |
        |  2       |
        |]         |
        |[         |
        |  3,      |
        |  4       |
        |]         |
        ------------
        <BLANKLINE>
    rU  rQ   r   r  s       rV   rU  rU    s=    4 AE	E1.5
6	EB	E3NbNINN 
Fr/  variantc                 P    t        | d      }t        |d      }t        d|||      S )a  Returns True if the specified VARIANT is found in the specified ARRAY.

    Args:
        variant: Column containing the VARIANT to find.
        array: Column containing the ARRAY to search.

            If this is a semi-structured array, you're required to explicitly cast the following SQL types into a VARIANT:

            - `String & Binary <https://docs.snowflake.com/en/sql-reference/data-types-text>`_
            - `Date & Time <https://docs.snowflake.com/en/sql-reference/data-types-datetime>`_

    Example::
        >>> from snowflake.snowpark import Row
        >>> df = session.create_dataframe([Row(["apple", "banana"]), Row(["apple", "orange"])], schema=["a"])
        >>> df.select(array_contains(lit("banana").cast("variant"), "a").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |True      |
        |False     |
        ------------
        <BLANKLINE>
    array_containsr}   r   r  r%  rQ   vr  s        rV   r  r  #  s0    6 	w 01Au./A*AqIFFrY   c                 j    t        | d      }t        |d      }t        |d      }t        d||||      S )a  Returns an ARRAY containing all elements from the source ARRAY as well as the new element.

    Args:
        array: Column containing the source ARRAY.
        pos: Column containing a (zero-based) position in the source ARRAY.
            The new element is inserted at this position. The original element from this
            position (if any) and all subsequent elements (if any) are shifted by one position
            to the right in the resulting array (i.e. inserting at position 0 has the same
            effect as using array_prepend).
            A negative position is interpreted as an index from the back of the array (e.g.
            -1 results in insertion before the last element in the array).
        element: Column containing the element to be inserted. The new element is located at
            position pos. The relative order of the other elements from the source
            array is preserved.

    Example::
        >>> from snowflake.snowpark import Row
        >>> df = session.create_dataframe([Row([1, 2]), Row([1, 3])], schema=["a"])
        >>> df.select(array_insert("a", lit(0), lit(10)).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |[         |
        |  10,     |
        |  1,      |
        |  2       |
        |]         |
        |[         |
        |  10,     |
        |  1,      |
        |  3       |
        |]         |
        ------------
        <BLANKLINE>
    array_insertr}   r   )r%  r  r  rQ   r  r  r   s          rV   r  r  C  s<    T 	un-AsN+Aw/A.!QYGGrY   c                 P    t        | d      }t        |d      }t        d|||      S )a  Returns the index of the first occurrence of an element in an ARRAY.

    Args:
        variant: Column containing the VARIANT value that you want to find. The function
            searches for the first occurrence of this value in the array.
        array: Column containing the ARRAY to be searched.

    Example::
        >>> from snowflake.snowpark import Row
        >>> df = session.create_dataframe([Row([2, 1]), Row([1, 3])], schema=["a"])
        >>> df.select(array_position(lit(1), "a").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |1         |
        |0         |
        ------------
        <BLANKLINE>
    array_positionr}   r   r  s        rV   r  r  s  s0    . 	w 01Au./A*AqIFFrY   c                 P    t        | d      }t        |d      }t        d|||      S )a  Returns an ARRAY containing the new element as well as all elements from the source ARRAY.
    The new element is positioned at the beginning of the ARRAY.

    Args:
        array Column containing the source ARRAY.
        element Column containing the element to be prepended.

    Example::
        >>> from snowflake.snowpark import Row
        >>> df = session.create_dataframe([Row(a=[1, 2, 3])])
        >>> df.select(array_prepend("a", lit(4)).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |[         |
        |  4,      |
        |  1,      |
        |  2,      |
        |  3       |
        |]         |
        ------------
        <BLANKLINE>
    array_prependr}   r   r  s        rV   r  r    s-    6 	uo.Aw0A/1a9EErY   c                 6    t        | d      }t        d||      S )a  Returns the size of the input ARRAY.

    If the specified column contains a VARIANT value that contains an ARRAY, the size of the ARRAY
    is returned; otherwise, NULL is returned if the value is not an ARRAY.

    Example::
        >>> from snowflake.snowpark import Row
        >>> df = session.create_dataframe([Row(a=[1, 2, 3])])
        >>> df.select(array_size("a").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |3         |
        ------------
        <BLANKLINE>
    r  r}   r   r  s      rV   r  r    s    $ 	ul+A,Y??rY   from_toc                 j    t        | d      }t        |d      }t        |d      }t        d||||      S )a  Returns an ARRAY constructed from a specified subset of elements of the input ARRAY.

    Args:
        array: Column containing the source ARRAY.
        from_: Column containing a position in the source ARRAY. The position of the first
            element is 0. Elements from positions less than this parameter are
            not included in the resulting ARRAY.
        to: Column containing a position in the source ARRAY. Elements from positions equal to
            or greater than this parameter are not included in the resulting array.

    Example::
        >>> from snowflake.snowpark import Row
        >>> df = session.create_dataframe([Row(a=[1, 2, 3, 4, 5])])
        >>> df.select(array_slice("a", lit(1), lit(3)).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |[         |
        |  2,      |
        |  3       |
        |]         |
        ------------
        <BLANKLINE>
    r  r}   r   )r%  r  r  rQ   r  fr  s          rV   r  r    s;    8 	um,Aum,Ar=)A-AqIFFrY   rO  c                 P    t        | d      }t        |d      }t        d|||      S )a  Returns an input ARRAY converted to a string by casting all values to strings (using
    TO_VARCHAR) and concatenating them (using the string from the second argument to separate
    the elements).

    Args:
        array: Column containing the ARRAY of elements to convert to a string.
        separator: Column containing the string to put between each element (e.g. a space,
            comma, or other human-readable separator).

    Example::
        >>> from snowflake.snowpark import Row
        >>> df = session.create_dataframe([Row(a=[1, True, "s"])])
        >>> df.select(array_to_string("a", lit(",")).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |1,true,s  |
        ------------
        <BLANKLINE>
    r  r}   r   )r%  rO  rQ   r  r@  s        rV   r  r    s0    0 	u/0Ay"34A+QYGGrY   c                 6    t        | d      }t        d||      S )a
  Returns a Column containing the distinct values in the specified column col.
    The values in the Column are in no particular order, and the order is not deterministic.
    The function ignores NULL values in col.
    If col contains only NULL values or col is empty, the function returns an empty Column.

    Args:
        col: A :class:`Column` object or column name that determines the values.

    Example::
        >>> df = session.create_dataframe([[5], [2], [1], [2], [1]], schema=["a"])
        >>> df.select(array_unique_agg("a").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |[         |
        |  5,      |
        |  2,      |
        |  1       |
        |]         |
        ------------
        <BLANKLINE>
    array_unique_aggr}   r   r  s      rV   r  r    s!    0 	s./A,a9EErY   c                    t        | d      }t        |d      }|rt        d| |g|      nd}d }||g}|D ]  }	|j                  t        |	d              t        ||      }
||
_        |
S )a~  Returns the concatenatation of two or more MAPs.

    Args:
        col1: The source map
        col2: The map to be appended to col1
        cols: More maps to be appended

    Example::
        >>> df = session.sql("select {'k1': 'v1'} :: MAP(STRING,STRING) as A, {'k2': 'v2'} :: MAP(STRING,STRING) as B")
        >>> df.select(map_cat("A", "B")).show()  # doctest: +SKIP
        ---------------------------
        |"MAP_CAT(""A"", ""B"")"  |
        ---------------------------
        |{                        |
        |  "k1": "v1",            |
        |  "k2": "v2"             |
        |}                        |
        ---------------------------
        <BLANKLINE>
        >>> df = session.sql("select {'k1': 'v1'} :: MAP(STRING,STRING) as A, {'k2': 'v2'} :: MAP(STRING,STRING) as B, {'k3': 'v3'} :: MAP(STRING,STRING) as C")
        >>> df.select(map_cat("A", "B", "C")).show()  # doctest: +SKIP
        -------------------------------------------
        |"MAP_CAT(MAP_CAT(""A"", ""B""), ""C"")"  |
        -------------------------------------------
        |{                                        |
        |  "k1": "v1",                            |
        |  "k2": "v2",                            |
        |  "k3": "v3"                             |
        |}                                        |
        -------------------------------------------
        <BLANKLINE>
    map_catNc                      t        d| |d      S )Nr  Fr}   r~   )firstr  s     rV   map_cat_two_mapsz!map_cat.<locals>.map_cat_two_mapsH  s    i%HHrY   )r9   r%   r  r   rz   )r   r   rQ   r   m1m2rn   r  cols_to_concatr   r   s              rV   r  r     s    H 
i	(B	i	(BAJ
i$)<t)<
=PTCI "XN <nQ	:;< !>
2CCHJrY   c                 8    t        |d      }t        d| ||      S )a  Determines whether the specified MAP contains the specified key.

    Args:
        value: The key to find.
        col: The map to be searched.

    Example 1::
        >>> df = session.sql("select {'k1': 'v1'} :: MAP(STRING,STRING) as M, 'k1' as V")
        >>> df.select(map_contains_key(col("V"), "M")).show()
        ------------------------------------
        |"MAP_CONTAINS_KEY(""V"", ""M"")"  |
        ------------------------------------
        |True                              |
        ------------------------------------
        <BLANKLINE>

    Example 2::
        >>> df = session.sql("select {'k1': 'v1'} :: MAP(STRING,STRING) as M")
        >>> df.select(map_contains_key("k1", "M")).show()
        -----------------------------------
        |"MAP_CONTAINS_KEY('K1', ""M"")"  |
        -----------------------------------
        |True                             |
        -----------------------------------
        <BLANKLINE>
    map_containsmap_contains_keyr}   r   )r'  rW   rQ   r  s       rV   r  r  T  s"    8 	sN+A,eQ)LLrY   c                 6    t        | d      }t        d||      S )a  Returns the keys in a MAP.

    Args:
        col: The input map.

    Example 1::
        >>> df = session.sql("select {'k1': 'v1', 'k2': 'v2'} :: MAP(STRING,STRING) as M")
        >>> df.select(map_keys("M")).show()
        ---------------------
        |"MAP_KEYS(""M"")"  |
        ---------------------
        |[                  |
        |  "k1",            |
        |  "k2"             |
        |]                  |
        ---------------------
        <BLANKLINE>
    map_keysr}   r   )rW   rQ   r  s      rV   r  r  t  s    ( 	sJ'A*a9==rY   c           	         |rt        d| g      nd}t        | d      }t        |d      }t        t	        |d      t        |d      d      j                  t        |d      t        t        |d      d      d      j                  t        d      d      j                  d|j                          d      }||_        |S )a  Returns the size of the input ARRAY, OBJECT or MAP. Returns NULL if the
    input column does not match any of these types.

    Args:
        col: A :class:`Column` object or column name that determines the values.

    Example::
        >>> df = session.create_dataframe([([1,2,3], {'a': 1, 'b': 2}, 3)], ['col1', 'col2', 'col3'])
        >>> df.select(size(df.col1), size(df.col2), size(df.col3)).show()
        ----------------------------------------------------------
        |"SIZE(""COL1"")"  |"SIZE(""COL2"")"  |"SIZE(""COL3"")"  |
        ----------------------------------------------------------
        |3                 |2                 |NULL              |
        ----------------------------------------------------------
        <BLANKLINE>
    sizeNFr}   zSIZE(rP  )r%   r9   
to_variantwhenr(  r  r@  object_keys	otherwiserj   rV  rS  rz   )rW   rQ   rn   r   r  results         rV   r  r    s    ( 1:
fse
,tCsF#A1&A 	Q%(qE*	

 
a5){16%H 
 


 
3t9	.	%

~Q'	(  FKMrY   keyc                 P    t        | d      }t        |d      }t        d|||      S )a=  Returns one OBJECT per group. For each key-value input pair, where key must be a VARCHAR
    and value must be a VARIANT, the resulting OBJECT contains a key-value field.

    Example::

        >>> from snowflake.snowpark.types import StructType, StructField, VariantType, StringType
        >>> df = session.create_dataframe(
        ...     [["name", "Joe"], ["zip", "98004"]],
        ...     schema=StructType([StructField("k", StringType()), StructField("v", VariantType())])
        ... )
        >>> df.select(object_agg(col("k"), col("v")).alias("result")).show()
        --------------------
        |"RESULT"          |
        --------------------
        |{                 |
        |  "name": "Joe",  |
        |  "zip": "98004"  |
        |}                 |
        --------------------
        <BLANKLINE>
    
object_aggr}   r   )r  r'  rQ   kr  s        rV   r  r    s-    2 	sL)Aul+A,1	BBrY   
key_valuesc                 \    |D cg c]  }t        |d       }}t        dg|d| iS c c}w )a]  Returns an OBJECT constructed from the arguments.

    Example::

        >>> from snowflake.snowpark.types import StructType, StructField, VariantType, StringType
        >>> df = session.create_dataframe(
        ...     [["name", "Joe"], ["zip", "98004"],["age", None], [None, "value"]],
        ...     schema=StructType([StructField("k", StringType()), StructField("v", VariantType())])
        ... )
        >>> df.select(object_construct(col("k"), col("v")).alias("result")).show()
        --------------------
        |"RESULT"          |
        --------------------
        |{                 |
        |  "name": "Joe"   |
        |}                 |
        |{                 |
        |  "zip": "98004"  |
        |}                 |
        |{}                |
        |{}                |
        --------------------
        <BLANKLINE>
    object_constructrQ   r   rQ   r  kvkvss       rV   r  r    s<    4 =G
Gb>"01
GC
G,HsHiHH Hr/  c                 \    |D cg c]  }t        |d       }}t        dg|d| iS c c}w )aK  Returns an object containing the contents of the input (i.e. source) object with one or more
    keys removed.

    Example::

        >>> from snowflake.snowpark.types import StructType, StructField, VariantType, StringType
        >>> df = session.create_dataframe(
        ...     [["key_1", "one"], ["key_2", None]],
        ...     schema=StructType([StructField("k", StringType()), StructField("v", VariantType())])
        ... )
        >>> df.select(object_construct_keep_null(col("k"), col("v")).alias("result")).show()
        --------------------
        |"RESULT"          |
        --------------------
        |{                 |
        |  "key_1": "one"  |
        |}                 |
        |{                 |
        |  "key_2": null   |
        |}                 |
        --------------------
        <BLANKLINE>
    r   rQ   r   r  s       rV   r   r     s=    6 GQ
Q>":;
QC
Q6RR	RR Rr/  r  key1c                    t        | d      }t        |d      }|D cg c]  }t        |d       }}t        d||g|d|iS c c}w )a  Returns an object consisting of the input object with one or more keys removed.
    The input key must not exist in the object.

    Example::

        >>> from snowflake.snowpark.functions import lit
        >>> df = session.sql(
        ...     "select object_construct(a,b,c,d,e,f) as obj from "
        ...     "values('age', 21, 'zip', 21021, 'name', 'Joe'),"
        ...     "('age', 26, 'zip', 94021, 'name', 'Jay') as T(a,b,c,d,e,f)"
        ... )
        >>> df.select(object_delete(col("obj"), lit("age")).alias("result")).show()
        --------------------
        |"RESULT"          |
        --------------------
        |{                 |
        |  "name": "Joe",  |
        |  "zip": 21021    |
        |}                 |
        |{                 |
        |  "name": "Jay",  |
        |  "zip": 94021    |
        |}                 |
        --------------------
        <BLANKLINE>
    object_deleterQ   r   r  r  rQ   r  ok1r  kss           rV   r  r    sT    < 	sO,A	o	.B6:	;.O
,	;B	;/1bK2KKK 
<   Aupdate_flagc                     t        | d      }t        |d      }t        |d      }|t        |d      nd}|t        d|||||      S t        d||||      S )a2  Returns an object consisting of the input object with a new key-value pair inserted (or an
    existing key updated with a new value).

    Example::
        >>> from snowflake.snowpark.functions import lit
        >>> df = session.sql(
        ...     "select object_construct(a,b,c,d,e,f) as obj, k, v from "
        ...     "values('age', 21, 'zip', 21021, 'name', 'Joe', 'age', 0),"
        ...     "('age', 26, 'zip', 94021, 'name', 'Jay', 'age', 0) as T(a,b,c,d,e,f,k,v)"
        ... )
        >>> df.select(object_insert(col("obj"), lit("key"), lit("v")).alias("result")).show()
        --------------------
        |"RESULT"          |
        --------------------
        |{                 |
        |  "age": 21,      |
        |  "key": "v",     |
        |  "name": "Joe",  |
        |  "zip": 21021    |
        |}                 |
        |{                 |
        |  "age": 26,      |
        |  "key": "v",     |
        |  "name": "Jay",  |
        |  "zip": 94021    |
        |}                 |
        --------------------
        <BLANKLINE>
    object_insertNr  r}   r   )	r  r  r'  r  rQ   r  r  r  ufs	            rV   r  r  6  sj    J 	sO,AsO,Auo.A7B7N]	3TXB	~oq!QiPPoq!Q)LLrY   c                    t        | d      }t        |d      }|D cg c]  }t        |d       }}t        d||g|d|iS c c}w )a^  Returns a new OBJECT containing some of the key-value pairs from an existing object.

    To identify the key-value pairs to include in the new object, pass in the keys as arguments,
    or pass in an array containing the keys.

    If a specified key is not present in the input object, the key is ignored.

    Example::
        >>> from snowflake.snowpark.functions import lit
        >>> df = session.sql(
        ...     "select object_construct(a,b,c,d,e,f) as obj, k, v from "
        ...     "values('age', 21, 'zip', 21021, 'name', 'Joe', 'age', 0),"
        ...     "('age', 26, 'zip', 94021, 'name', 'Jay', 'age', 0) as T(a,b,c,d,e,f,k,v)"
        ... )
        >>> df.select(object_pick(col("obj"), col("k"), lit("name")).alias("result")).show()
        -------------------
        |"RESULT"         |
        -------------------
        |{                |
        |  "age": 21,     |
        |  "name": "Joe"  |
        |}                |
        |{                |
        |  "age": 26,     |
        |  "name": "Jay"  |
        |}                |
        -------------------
        <BLANKLINE>
    object_pickrQ   r   r  s           rV   r  r  e  sU    B 	sM*A	m	,B48	9q.M
*	9B	9-BIIyII 
:r  v1v2c                 P    t        | d      } t        |d      }t        d| ||      S )a  Returns the cosine distance between two vectors of equal dimension and element type.

    Example::
        >>> from snowflake.snowpark.functions import vector_cosine_distance
        >>> df = session.sql("select [1,2,3]::vector(int,3) as a, [2,3,4]::vector(int,3) as b")
        >>> df.select(vector_cosine_distance(df.a, df.b).as_("dist")).show()
        ----------------------
        |"DIST"              |
        ----------------------
        |0.9925833339709303  |
        ----------------------
        <BLANKLINE>
    vector_cosine_distancer}   r   r  r  rQ   s      rV   r  r    s0    " 
4	5B	4	5B2BiPPrY   c                 P    t        | d      } t        |d      }t        d| ||      S )a  Returns the l2 distance between two vectors of equal dimension and element type.

    Example::
        >>> from snowflake.snowpark.functions import vector_l2_distance
        >>> df = session.sql("select [1,2,3]::vector(int,3) as a, [2,3,4]::vector(int,3) as b")
        >>> df.select(vector_l2_distance(df.a, df.b).as_("dist")).show()
        ----------------------
        |"DIST"              |
        ----------------------
        |1.7320508075688772  |
        ----------------------
        <BLANKLINE>
    vector_l2_distancer}   r   r  s      rV   r  r    s0    " 
0	1B	0	1B.B)LLrY   c                 P    t        | d      } t        |d      }t        d| ||      S )a  Returns the inner product between two vectors of equal dimension and element type.

    Example::
        >>> from snowflake.snowpark.functions import vector_inner_product
        >>> df = session.sql("select [1,2,3]::vector(int,3) as a, [2,3,4]::vector(int,3) as b")
        >>> df.select(vector_inner_product(df.a, df.b).as_("dist")).show()
        ----------
        |"DIST"  |
        ----------
        |20.0    |
        ----------
        <BLANKLINE>
    vector_inner_productr}   r   r  s      rV   r  r    s0    " 
2	3B	2	3B0"bINNrY   c                 6    t        | d      } t        d| |      S )a  Returns the natrual logarithm of given column expression.

    Example::
        >>> from snowflake.snowpark.functions import ln
        >>> from math import e
        >>> df = session.create_dataframe([[e]], schema=["ln_value"])
        >>> df.select(ln(col("ln_value")).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |1.0       |
        ------------
        <BLANKLINE>
    r  r}   r   )r   rQ   s     rV   r  r    s      	q$A$Y77rY   c                 r    |rt        d| g      nd}t        | d      } | j                  d      }||_        |S )a  Returns a Column expression with values sorted in ascending order.

    Example::

        >>> df = session.create_dataframe([None, 3, 2, 1, None], schema=["a"])
        >>> df.sort(asc(df["a"])).collect()
        [Row(A=None), Row(A=None), Row(A=1), Row(A=2), Row(A=3)]
    ascNFr}   )r%   r9   r  rz   r   rQ   rn   r   s       rV   r  r    s?     .7
eaS
)DCq% A
%%%%
 CCHJrY   c                 r    |rt        d| g      nd}t        | d      } | j                  d      }||_        |S )aO  Returns a Column expression with values sorted in ascending order
    (null values sorted before non-null values).

    Example::

        >>> df = session.create_dataframe([None, 3, 2, 1, None], schema=["a"])
        >>> df.sort(asc_nulls_first(df["a"])).collect()
        [Row(A=None), Row(A=None), Row(A=1), Row(A=2), Row(A=3)]
    asc_nulls_firstNFr}   )r%   r9   r  rz   r  s       rV   r  r    E     :C
/!
5Cq+,A


e

,CCHJrY   c                 r    |rt        d| g      nd}t        | d      } | j                  d      }||_        |S )aM  Returns a Column expression with values sorted in ascending order
    (null values sorted after non-null values).

    Example::

        >>> df = session.create_dataframe([None, 3, 2, 1, None], schema=["a"])
        >>> df.sort(asc_nulls_last(df["a"])).collect()
        [Row(A=1), Row(A=2), Row(A=3), Row(A=None), Row(A=None)]
    asc_nulls_lastNFr}   )r%   r9   r  rz   r  s       rV   r  r    sE     9B
.
4tCq*+A


U

+CCHJrY   c                 r    |rt        d| g      nd}t        | d      } | j                  d      }||_        |S )a  
    Returns a Column expression with values sorted in descending order.

    Example::

        >>> df = session.create_dataframe([1, 2, 3, None, None], schema=["a"])
        >>> df.sort(desc(df["a"])).collect()
        [Row(A=3), Row(A=2), Row(A=1), Row(A=None), Row(A=None)]
    descNFr}   )r%   r9   r  rz   r  s       rV   r  r  !  s?     /8
fqc
*TCq&!A
&&5&
!CCHJrY   c                 r    |rt        d| g      nd}t        | d      } | j                  d      }||_        |S )aV  
    Returns a Column expression with values sorted in descending order
    (null values sorted before non-null values).

    Example::

        >>> df = session.create_dataframe([1, 2, 3, None, None], schema=["a"])
        >>> df.sort(desc_nulls_first(df["a"])).collect()
        [Row(A=None), Row(A=None), Row(A=3), Row(A=2), Row(A=1)]
    desc_nulls_firstNFr}   )r%   r9   r  rz   r  s       rV   r  r  5  sE     ;D
01#
6Cq,-A


u

-CCHJrY   c                 r    |rt        d| g      nd}t        | d      } | j                  d      }||_        |S )aS  
    Returns a Column expression with values sorted in descending order
    (null values sorted after non-null values).

    Example::
        >>> df = session.create_dataframe([1, 2, 3, None, None], schema=["a"])
        >>> df.sort(desc_nulls_last(df["a"])).collect()
        [Row(A=3), Row(A=2), Row(A=1), Row(A=None), Row(A=None)]
    desc_nulls_lastNFr}   )r%   r9   r  rz   r  s       rV   r  r  J  r  rY   c                 6    t        | d      }t        d||      S )ay  Casts a VARIANT value to an array.

    Example::
        >>> df = session.sql("select array_construct(1, 2)::variant as a")
        >>> df.select(as_array("a").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |[         |
        |  1,      |
        |  2       |
        |]         |
        ------------
        <BLANKLINE>
    as_arrayr}   r   r  rQ   r   s      rV   r  r  ^  s    " 	w
+A*a9==rY   c                 6    t        | d      }t        d||      S )u  Casts a VARIANT value to a binary string.

    Example::
        >>> df = session.sql("select to_binary('F0A5')::variant as a")
        >>> df.select(as_binary("a").alias("result")).show()
        --------------------------
        |"RESULT"                |
        --------------------------
        |bytearray(b'ð¥')  |
        --------------------------
        <BLANKLINE>
    	as_binaryr}   r   r  s      rV   r  r  s       	w,A+qI>>rY   c                 6    t        | d      }t        d||      S )a  Casts a VARIANT value to a string.

    Example::

        >>> from snowflake.snowpark.functions import as_char, to_variant
        >>> df = session.sql("select 'some string' as char")
        >>> df.char_v = to_variant(df.char)
        >>> df.select(df.char_v.as_("char")).collect() == df.select(df.char).collect()
        False
        >>> df.select(as_char(df.char_v).as_("char")).collect() == df.select(df.char).collect()
        True
    as_charr}   r   r  s      rV   r  r         	w	*A)Q)<<rY   c                 6    t        | d      }t        d||      S )a  Casts a VARIANT value to a string.

    Example::

        >>> from snowflake.snowpark.functions import as_varchar, to_variant
        >>> df = session.sql("select 'some string' as char")
        >>> df.char_v = to_variant(df.char)
        >>> df.select(df.char_v.as_("char")).collect() == df.select(df.char).collect()
        False
        >>> df.select(as_varchar(df.char_v).as_("char")).collect() == df.select(df.char).collect()
        True
    
as_varcharr}   r   r  s      rV   r  r         	w-A,Y??rY   c                 6    t        | d      }t        d||      S )a:  Casts a VARIANT value to a date.

    Example::
        >>> df = session.sql("select date'2020-1-1'::variant as a")
        >>> df.select(as_date("a").alias("result")).show()
        --------------
        |"RESULT"    |
        --------------
        |2020-01-01  |
        --------------
        <BLANKLINE>
    as_dater}   r   r  s      rV   r   r     r  rY   rc   c                 v    |rt        d| |g      nd}t        | d      }|j                  |d      }||_        |S )a  Converts a value of one data type into another data type.
    The semantics of CAST are the same as the semantics of the corresponding to datatype conversion functions.
    If the cast is not possible, a ``SnowparkSQLException`` exception is thrown.

    Example::

        >>> from snowflake.snowpark.types import DecimalType, IntegerType
        >>> df = session.create_dataframe([[1.5432]], schema=["d"])
        >>> df.select(cast(df.d, DecimalType(15, 2)).as_("DECIMAL"), cast(df.d, IntegerType()).as_("INT")).show()
        ---------------------
        |"DECIMAL"  |"INT"  |
        ---------------------
        |1.54       |2      |
        ---------------------
        <BLANKLINE>
    rI  NFr}   )r%   r9   rI  rz   rc   r  rQ   rn   r   r   s         rV   rI  rI    sD    * 8A
fvrl
3dCvv&A
&&u&
%CCHJrY   c                 v    |rt        d| |g      nd}t        | d      }|j                  |d      }||_        |S )u  A special version of CAST for a subset of data type conversions.
    It performs the same operation (i.e. converts a value of one data type into another data type),
    but returns a NULL value instead of raising an error when the conversion can not be performed.

    The ``column`` argument must be a string column in Snowflake.

    Example::

        >>> from snowflake.snowpark.types import IntegerType, FloatType
        >>> df = session.create_dataframe(['0', '-12', '22', '1001'], schema=["a"])
        >>> df.select(try_cast(col("a"), IntegerType()).as_('ans')).collect()
        [Row(ANS=0), Row(ANS=-12), Row(ANS=22), Row(ANS=1001)]

    Example::

        >>> df = session.create_dataframe(['0.12', 'USD 27.90', '13.97 USD', '€97.0', '17,-'], schema=["a"])
        >>> df.select(try_cast(col("a"), FloatType()).as_('ans')).collect()
        [Row(ANS=0.12), Row(ANS=None), Row(ANS=None), Row(ANS=None), Row(ANS=None)]

    ru  NFr}   )r%   r9   ru  rz   r  s         rV   ru  ru    sD    2 <E
j62,
7$Cvz*A
**R5*
)CCHJrY   c           	      ,   |rt        d| g|g n|gz   |g n|gz         nd}d}t        | |      }|r|st        d      |r)|r't        ||t	        |d      t	        |d      ||      S |rt        ||t	        |d      ||      S t        ||||      S )ag  Casts a VARIANT value to a fixed-point decimal (does not match floating-point values).

    Example::
        >>> df = session.sql("select 1.2345::variant as a")
        >>> df.select(as_decimal("a", 4, 1).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |1.2       |
        ------------
        <BLANKLINE>
    
as_decimalNz%Cannot define scale without precisionFr}   ry   )r%   r9   r  r   rj   )r  ra  r   rQ   rn   	cast_typer   s          rV   r  r    s    6  	I&rYK9]r1	
   Iw	*AY@AAU	U+'
 	
 
q#i59y
 	
 i	JJrY   c                 6    t        | d      }t        d||      S )a:  Casts a VARIANT value to a floating-point value.

    Example::
        >>> df = session.sql("select 1.2345::variant as a")
        >>> df.select(as_double("a").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |1.2345    |
        ------------
        <BLANKLINE>
    	as_doubler}   r   r  s      rV   r  r  0   r  rY   c                 6    t        | d      }t        d||      S )a  Casts a VARIANT value to a floating-point value.

    Example::

        >>> from snowflake.snowpark.types import VariantType, StructType, StructField, DoubleType
        >>> schema=StructType([StructField("radius", DoubleType()),  StructField("radius_v", VariantType())])
        >>> df = session.create_dataframe(data=[[2.0, None]], schema=schema)
        >>> df.radius_v = to_variant(df.radius)
        >>> df.select(df.radius_v.as_("radius_v"), df.radius).collect()
        [Row(RADIUS_V='2.000000000000000e+00', RADIUS=2.0)]
        >>> df.select(as_real(df.radius_v).as_("real_radius_v"), df.radius).collect()
        [Row(REAL_RADIUS_V=2.0, RADIUS=2.0)]
    as_realr}   r   r  s      rV   r
  r
  B   s     	w	*A)Q)<<rY   c                 6    t        | d      }t        d||      S )a/  Casts a VARIANT value to an integer.

    Example::
        >>> df = session.sql("select 1.2345::variant as a")
        >>> df.select(as_integer("a").alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |1         |
        ------------
        <BLANKLINE>
    
as_integerr}   r   r  s      rV   r  r  U   r  rY   c                 6    t        | d      }t        d||      S )a  Casts a VARIANT value to an object.

    Example::
        >>> df = session.sql("select object_construct('A',1,'B','BBBB')::variant as a")
        >>> df.select(as_object("a").alias("result")).show()
        -----------------
        |"RESULT"       |
        -----------------
        |{              |
        |  "A": 1,      |
        |  "B": "BBBB"  |
        |}              |
        -----------------
        <BLANKLINE>
    	as_objectr}   r   r  s      rV   r  r  g   s    " 	w,A+qI>>rY   c                 6    t        | d      }t        d||      S )a  Casts a VARIANT value to a time value.

    Example::

        >>> from snowflake.snowpark.functions import as_time, to_variant
        >>> df = session.sql("select TO_TIME('12:34:56') as alarm")
        >>> df.alarm_v = to_variant(df.alarm)
        >>> df.select(df.alarm_v.as_("alarm")).collect() == df.select(df.alarm).collect()
        False
        >>> df.select(as_time(df.alarm_v).as_("alarm")).collect() == df.select(df.alarm).collect()
        True
    as_timer}   r   r  s      rV   r  r  |   r  rY   c                 6    t        | d      }t        d||      S )a	  Casts a VARIANT value to a TIMESTAMP with a local timezone.

    Example::

        >>> from snowflake.snowpark.functions import as_timestamp_ltz, to_variant
        >>> df = session.sql("select TO_TIMESTAMP_LTZ('2018-10-10 12:34:56') as alarm")
        >>> df.alarm_v = to_variant(df.alarm)
        >>> df.select(df.alarm_v.as_("alarm")).collect() == df.select(df.alarm).collect()
        False
        >>> df.select(as_timestamp_ltz(df.alarm_v).as_("alarm")).collect() == df.select(df.alarm).collect()
        True
    as_timestamp_ltzr}   r   r  s      rV   r  r     !     	w 23A,a9EErY   c                 6    t        | d      }t        d||      S )a  Casts a VARIANT value to a TIMESTAMP with no timezone.

    Example::

        >>> from snowflake.snowpark.functions import as_timestamp_ntz, to_variant
        >>> df = session.sql("select TO_TIMESTAMP_NTZ('2018-10-10 12:34:56') as alarm")
        >>> df.alarm_v = to_variant(df.alarm)
        >>> df.select(df.alarm_v.as_("alarm")).collect() == df.select(df.alarm).collect()
        False
        >>> df.select(as_timestamp_ntz(df.alarm_v).as_("alarm")).collect() == df.select(df.alarm).collect()
        True
    as_timestamp_ntzr}   r   r  s      rV   r  r     r  rY   c                 6    t        | d      }t        d||      S )a  Casts a VARIANT value to a TIMESTAMP with a timezone.

    Example::

        >>> from snowflake.snowpark.functions import as_timestamp_tz, to_variant
        >>> df = session.sql("select TO_TIMESTAMP_TZ('2018-10-10 12:34:56 +0000') as alarm")
        >>> df.alarm_v = to_variant(df.alarm)
        >>> df.select(df.alarm_v.as_("alarm")).collect() == df.select(df.alarm).collect()
        False
        >>> df.select(as_timestamp_tz(df.alarm_v).as_("alarm")).collect() == df.select(df.alarm).collect()
        True
    as_timestamp_tzr}   r   r  s      rV   r  r     s!     	w 12A+Q)DDrY   c                 X    t        | d      }|rt        d|||      S t        d||      S )a  Converts the input expression to a binary value. For NULL input, the output is NULL.

    Example::

        >>> df = session.create_dataframe(['00', '67', '0312'], schema=['a'])
        >>> df.select(to_binary(col('a')).as_('ans')).collect()
        [Row(ANS=bytearray(b'\x00')), Row(ANS=bytearray(b'g')), Row(ANS=bytearray(b'\x03\x12'))]

        >>> df = session.create_dataframe(['aGVsbG8=', 'd29ybGQ=', 'IQ=='], schema=['a'])
        >>> df.select(to_binary(col('a'), 'BASE64').as_('ans')).collect()
        [Row(ANS=bytearray(b'hello')), Row(ANS=bytearray(b'world')), Row(ANS=bytearray(b'!'))]

        >>> df.select(to_binary(col('a'), 'UTF-8').as_('ans')).collect()
        [Row(ANS=bytearray(b'aGVsbG8=')), Row(ANS=bytearray(b'd29ybGQ=')), Row(ANS=bytearray(b'IQ=='))]
    	to_binaryr}   r   rx  s       rV   r  r     s=    & 	q+&A  	{Asi@ Ki@rY   c                 6    t        | d      }t        d||      S )a0  Converts any value to an ARRAY value or NULL (if input is NULL).

    Example::

        >>> df = session.create_dataframe([1, 2, 3, 4], schema=['a'])
        >>> df.select(to_array(col('a')).as_('ans')).collect()
        [Row(ANS='[\n  1\n]'), Row(ANS='[\n  2\n]'), Row(ANS='[\n  3\n]'), Row(ANS='[\n  4\n]')]


        >>> from snowflake.snowpark import Row
        >>> df = session.create_dataframe([Row(a=[1, 2, 3]), Row(a=None)])
        >>> df.select(to_array(col('a')).as_('ans')).collect()
        [Row(ANS='[\n  1,\n  2,\n  3\n]'), Row(ANS=None)]
    to_arrayr}   r   r   s      rV   r  r     s      	q*%A*a9==rY   c                 6    t        | d      }t        d||      S )a  Converts any VARIANT value to a string containing the JSON representation of the
    value. If the input is NULL, the result is also NULL.

    Example::
        >>> from snowflake.snowpark.types import VariantType, StructField, StructType
        >>> from snowflake.snowpark import Row
        >>> schema = StructType([StructField("a", VariantType())])
        >>> df = session.create_dataframe([Row(a=None),Row(a=12),Row(a=3.141),Row(a={'a':10,'b':20}),Row(a=[1,23,456])], schema=schema)
        >>> df.select(to_json(col("a")).as_('ans')).collect()
        [Row(ANS=None), Row(ANS='12'), Row(ANS='3.141'), Row(ANS='{"a":10,"b":20}'), Row(ANS='[1,23,456]')]
    to_jsonr}   r   r   s      rV   r  r     s     	q)$A)Q)<<rY   c                 6    t        | d      }t        d||      S )a  Converts any value to a OBJECT value or NULL (if input is NULL).

    Example::
        >>> from snowflake.snowpark.types import VariantType, StructField, StructType
        >>> from snowflake.snowpark import Row
        >>> schema = StructType([StructField("a", VariantType())])
        >>> df = session.create_dataframe(["{'a':10,'b':20}", None], schema=schema)
        >>> df.select(to_object(col("a")).as_('ans')).collect()
        [Row(ANS='{\n  "a": 10,\n  "b": 20\n}'), Row(ANS=None)]
    	to_objectr}   r   r   s      rV   r  r  !  r  rY   c                 6    t        | d      }t        d||      S )a  Converts any value to a VARIANT value or NULL (if input is NULL).

    Example::

        >>> df = session.create_dataframe([1, 2, 3, 4], schema=['a'])
        >>> df_conv = df.select(to_variant(col("a")).as_("ans")).sort("ans")
        >>> df_conv.collect()
        [Row(ANS='1'), Row(ANS='2'), Row(ANS='3'), Row(ANS='4')]

        After conversion via to_variant, another variant dataframe can be merged.

        >>> from snowflake.snowpark.types import VariantType, StructField, StructType
        >>> from snowflake.snowpark import Row
        >>> schema = StructType([StructField("a", VariantType())])
        >>> df_other = session.create_dataframe([Row(a=10), Row(a='test'), Row(a={'a': 10, 'b': 20}), Row(a=[1, 2, 3])], schema=schema)
        >>> df_conv.union(df_other).select(typeof(col("ans")).as_("ans")).sort("ans").collect()
        [Row(ANS='ARRAY'), Row(ANS='INTEGER'), Row(ANS='INTEGER'), Row(ANS='INTEGER'), Row(ANS='INTEGER'), Row(ANS='INTEGER'), Row(ANS='OBJECT'), Row(ANS='VARCHAR')]
    r  r}   r   r   s      rV   r  r  !  s    ( 	q,'A,Y??rY   c                 6    t        | d      }t        d||      S )a  Converts any VARIANT value to a string containing the XML representation of the
    value. If the input is NULL, the result is also NULL.

    Example::
        >>> from snowflake.snowpark.types import VariantType, StructField, StructType
        >>> from snowflake.snowpark import Row
        >>> schema = StructType([StructField("a", VariantType())])
        >>> df = session.create_dataframe([Row(a=10), Row(a='test'), Row(a={'a': 10, 'b': 20}), Row(a=[1, 2, 3])], schema=schema)
        >>> df.select(to_xml(col("A")).as_("ans")).collect()
        [Row(ANS='<SnowflakeData type="INTEGER">10</SnowflakeData>'), Row(ANS='<SnowflakeData type="VARCHAR">test</SnowflakeData>'), Row(ANS='<SnowflakeData type="OBJECT"><a type="INTEGER">10</a><b type="INTEGER">20</b></SnowflakeData>'), Row(ANS='<SnowflakeData type="ARRAY"><e type="INTEGER">1</e><e type="INTEGER">2</e><e type="INTEGER">3</e></SnowflakeData>')]
    to_xmlr}   r   r   s      rV   r"  r"  ,!  r  rY   fieldc                 P    t        | d      }t        |d      }t        d|||      S )a  
    Extracts a field value from an object. Returns NULL if either of the arguments is NULL.
    This function is similar to :meth:`get` but applies case-insensitive matching to field names.

    Examples::

        >>> df = session.create_dataframe([{"a": {"aa": 1, "bb": 2, "cc": 3}}])
        >>> df.select(get_ignore_case(df["a"], lit("AA")).alias("get_ignore_case")).collect()
        [Row(GET_IGNORE_CASE='1')]
    get_ignore_caser}   r   )r  r#  rQ   r   r   s        rV   r%  r%  =!  s0     
.	/B	0	1B+RyIIrY   c                 6    t        | d      }t        d||      S )a:  Returns an array containing the list of keys in the input object.


    Example::
        >>> from snowflake.snowpark.functions import lit
        >>> df = session.sql(
        ...     "select object_construct(a,b,c,d,e,f) as obj, k, v from "
        ...     "values('age', 21, 'zip', 21021, 'name', 'Joe', 'age', 0),"
        ...     "('age', 26, 'zip', 94021, 'name', 'Jay', 'age', 0) as T(a,b,c,d,e,f,k,v)"
        ... )
        >>> df.select(object_keys(col("obj")).alias("result")).show()
        -------------
        |"RESULT"   |
        -------------
        |[          |
        |  "age",   |
        |  "name",  |
        |  "zip"    |
        |]          |
        |[          |
        |  "age",   |
        |  "name",  |
        |  "zip"    |
        |]          |
        -------------
        <BLANKLINE>
    r  r}   r   )r  rQ   r   s      rV   r  r  P!  s    : 	sM*A-i@@rY   xmltaginstance_numc                     t        | d      }t        |d      }t        |t              r|nt        |d      }t        d||||      S )a+  Extracts an XML element object (often referred to as simply a tag) from a content of outer
    XML element object by the name of the tag and its instance number (counting from 0).

    The following example returns the first inner level (level2) from the XML object created via `parse_xml`.

    Example::

        >>> df = session.create_dataframe(['<level1 attr1="a">1<level2 attr2="b">2<level3>3a</level3><level3>3b</level3></level2></level1>'], schema=["str"]).select(parse_xml("str").as_("obj"))
        >>> df.collect()
        [Row(OBJ='<level1 attr1="a">\n  1\n  <level2 attr2="b">\n    2\n    <level3>3a</level3>\n    <level3>3b</level3>\n  </level2>\n</level1>')]
        >>> df.select(xmlget("obj", lit("level2")).as_("ans")).collect()
        [Row(ANS='<level2 attr2="b">\n  2\n  <level3>3a</level3>\n  <level3>3b</level3>\n</level2>')]

    When multiple tags exist at a level, instance_num can be used to distinguish which element to return.

    Example::

        >>> df.select(xmlget(xmlget("obj", lit("level2")), lit("level3"), lit(0)).as_("ans")).collect()
        [Row(ANS='<level3>3a</level3>')]
        >>> df.select(xmlget(xmlget("obj", lit("level2")), lit("level3"), lit(1)).as_("ans")).collect()
        [Row(ANS='<level3>3b</level3>')]
        >>> df.select(xmlget("obj", lit("level2"), lit(5)).as_("ans")).collect()
        [Row(ANS=None)]

    In order to get the tagname, the value of an attribute or the content within a tag the `get` function can be used.

    Example::

        >>> df.select(get(xmlget("obj", lit("level2")), lit("@")).as_("ans")).collect()
        [Row(ANS='"level2"')]
        >>> df.select(get(xmlget("obj", lit("level2")), lit("$")).as_("ans")).collect()
        [Row(ANS='[\n  2,\n  {\n    "$": "3a",\n    "@": "level3"\n  },\n  {\n    "$": "3b",\n    "@": "level3"\n  }\n]')]
        >>> df.select(get(xmlget(xmlget("obj", lit("level2")), lit("level3")), lit("$")).as_("ans")).collect()
        [Row(ANS='"3a"')]
        >>> df.select(get(xmlget("obj", lit("level2")), lit("@attr2")).as_("ans")).collect()
        [Row(ANS='"b"')]
    xmlgetr}   )r9   r   rG  r   )r'  r(  r)  rQ   r   r   c3s          rV   r+  r+  q!  sR    X 
X	&B	X	&B lC( 	L(3 
 (BB)DDrY   c                 P    t        | d      }t        |d      }t        d|||      S )a  
    Extracts a value from semi-structured data using a path name.

    Examples::

        >>> df = session.create_dataframe([{"a": {"aa": {"dd": 4}, "bb": 2, "cc": 3}}])
        >>> df.select(get_path(df["a"], lit("aa.dd")).alias("get_path")).collect()
        [Row(GET_PATH='4')]
    get_pathr}   r   )rW   r!  rQ   r   r   s        rV   r.  r.  !  s-     
Z	(B	j	)B*b"	BBrY   c                 P    t        | d      }t        |d      }t        d|||      S )a  Extracts a value from an object or array; returns NULL if either of the arguments is NULL.

    Example::

        >>> from snowflake.snowpark.functions import lit
        >>> df = session.createDataFrame([({"a": 1.0, "b": 2.0}, [1, 2, 3],), ({}, [],)], ["map", "list"])
        >>> df.select(get(df.list, 1).as_("idx1")).sort(col("idx1")).show()
        ----------
        |"IDX1"  |
        ----------
        |NULL    |
        |2       |
        ----------
        <BLANKLINE>

        >>> df.select(get(df.map, lit("a")).as_("get_a")).sort(col("get_a")).show()
        -----------
        |"GET_A"  |
        -----------
        |NULL     |
        |1        |
        -----------
        <BLANKLINE>rX  r}   r:   r   )r   r   rQ   r   r   s        rV   rX  rX  !  s-    : 
tU	+B	tU	+B%R9==rY   	conditionc                 |   d}|rxt        j                         }t        |j                        }t        |j                  j                               }t        |j                  |        t        |j                  |       t        t        t        | d      j                  t        j                  |      fg      ||      S )a  Works like a cascading if-then-else statement.
    A series of conditions are evaluated in sequence.
    When a condition evaluates to TRUE, the evaluation stops and the associated
    result (after THEN) is returned. If none of the conditions evaluate to TRUE,
    then the result after the optional OTHERWISE is returned, if present;
    otherwise NULL is returned.

    Args:
        condition: A :class:`Column` expression or SQL text representing the specified condition.
        value: A :class:`Column` expression or a literal value, which will be returned
            if ``condition`` is true.

    Example::

        >>> df = session.create_dataframe([1, None, 2, 3, None, 5, 6], schema=["a"])
        >>> df.collect()
        [Row(A=1), Row(A=None), Row(A=2), Row(A=3), Row(A=None), Row(A=5), Row(A=6)]
        >>> df.select(when(col("a") % 2 == 0, lit("even")).as_("ans")).collect()
        [Row(ANS=None), Row(ANS=None), Row(ANS='even'), Row(ANS=None), Row(ANS=None), Row(ANS=None), Row(ANS='even')]

    Multiple when statements can be changed and `otherwise`/`else_` used to create expressions similar to ``CASE WHEN ... ELSE ... END`` in SQL.

    Example::

        >>> df.select(when(col("a") % 2 == 0, lit("even")).when(col("a") % 2 == 1, lit("odd")).as_("ans")).collect()
        [Row(ANS='odd'), Row(ANS=None), Row(ANS='even'), Row(ANS='odd'), Row(ANS=None), Row(ANS='odd'), Row(ANS='even')]
        >>> df.select(when(col("a") % 2 == 0, lit("even")).when(col("a") % 2 == 1, lit("odd")).otherwise(lit("unknown")).as_("ans")).collect()
        [Row(ANS='odd'), Row(ANS='unknown'), Row(ANS='even'), Row(ANS='odd'), Row(ANS='unknown'), Row(ANS='odd'), Row(ANS='even')]
    Nr  ry   )ro   rp   r$   column_case_exprcasesaddr#   r1  r"   r'  r5   r   r8   r   r6   r  )r1  r'  rQ   rn   r   	case_exprs         rV   r  r  !  s    F Cjjl !5!56%djjnn&67	293F3F	R5ioouM (	6:FFOOE*	
  rY   expr1expr2c                 ^    |rt        d| ||g      nd}t        dt        | d      ||||      S )a  
    Returns one of two specified expressions, depending on a condition.
    This is equivalent to an ``if-then-else`` expression.

    Args:
        condition: A :class:`Column` expression or SQL text representing the specified condition.
        expr1: A :class:`Column` expression or a literal value, which will be returned
            if ``condition`` is true.
        expr2: A :class:`Column` expression or a literal value, which will be returned
            if ``condition`` is false.

    Examples::

        >>> df = session.create_dataframe([True, False, None], schema=["a"])
        >>> df.select(iff(df["a"], lit("true"), lit("false")).alias("iff")).collect()
        [Row(IFF='true'), Row(IFF='false'), Row(IFF='false')]
    r   Nry   )r%   r   r8   )r1  r7  r8  rQ   rn   s        rV   r   r   "  sE    0 DM
ei%>
?RVCIu- rY   valszsnowflake.snowpark.DataFramec                   d}|rt        j                         }t        |j                        }| D ](  }|j                  j                         }t        ||       * g }|D ]s  }	t        j                         }
t        |	t        j                  j                  j                        r|	j                  |
       nt        |
|	       |j                  |
       u t        j                         }t        |d|g|  t        | }| D cg c]  }t!        |d       }}t#        t%        |D cg c]  }|j&                   c}      d      j)                  |d      }||_        |S c c}w c c}w )a  Returns a conditional expression that you can pass to the filter or where methods to
    perform the equivalent of a WHERE ... IN query that matches rows containing a sequence of
    values.

    The expression evaluates to true if the values in a row matches the values in one of
    the specified sequences.

    The following code returns a DataFrame that contains the rows in which
    the columns `c1` and `c2` contain the values:
    - `1` and `"a"`, or
    - `2` and `"b"`
    This is equivalent to ``SELECT * FROM table WHERE (c1, c2) IN ((1, 'a'), (2, 'b'))``.

    Example::

        >>> df = session.create_dataframe([[1, "a"], [2, "b"], [3, "c"]], schema=["col1", "col2"])
        >>> df.filter(in_([col("col1"), col("col2")], [[1, "a"], [2, "b"]])).show()
        -------------------
        |"COL1"  |"COL2"  |
        -------------------
        |1       |a       |
        |2       |b       |
        -------------------
        <BLANKLINE>

    The following code returns a DataFrame that contains the rows where
    the values of the columns `c1` and `c2` in `df2` match the values of the columns
    `a` and `b` in `df1`. This is equivalent to
    ``SELECT * FROM table2 WHERE (c1, c2) IN (SELECT a, b FROM table1)``.

    Example::

        >>> df1 = session.sql("select 1, 'a'")
        >>> df.filter(in_([col("col1"), col("col2")], df1)).show()
        -------------------
        |"COL1"  |"COL2"  |
        -------------------
        |1       |a       |
        -------------------
        <BLANKLINE>

    Args::
        cols: A list of the columns to compare for the IN operation.
        vals: A list containing the values or columns, or a Snowpark DataFrame to compare for the IN operation.
    Nin_Fr}   )ro   rp   r$   list_valvsr5  r"   r   r  r  	dataframe	DataFrame_set_ast_refr  r    r.   r9   r6   r   r   r<  rz   )r   rQ   r:  rn   list_arglist_astrW   col_astvalues_argsvalval_astr   r.  r   s                 rV   r<  r<  8"  sD   v C ::<$X%6%67 	HCkkoo'G9'3G	H  	(CjjlG#y11;;EEF  )=gsKw'	( jjlsE8BkB($/D156A~a'6G6
7;aAMM;<	c$%c   CHJ 7;s   E &E%c                     t        d|       S )a  
    Finds the cumulative distribution of a value with regard to other values
    within the same window partition.

    Example:

        >>> from snowflake.snowpark.window import Window
        >>> from snowflake.snowpark.types import DecimalType
        >>> df = session.create_dataframe([[1, 2], [1, 2], [1,3], [4, 5], [2, 3], [3, 4], [4, 7], [3,7], [4,5]], schema=["a", "b"])
        >>> df.select(cume_dist().over(Window.order_by("a")).cast(DecimalType(scale=3)).alias("result")).show()
        ------------
        |"RESULT"  |
        ------------
        |0.333     |
        |0.333     |
        |0.333     |
        |0.444     |
        |0.667     |
        |0.667     |
        |1.000     |
        |1.000     |
        |1.000     |
        ------------
        <BLANKLINE>
    	cume_distr}   r~   r}   s    rV   rI  rI  "  s    6 +;;rY   c                     t        d|       S )a.  
    Returns the rank of a value within an ordered group of values.
    The rank value starts at 1 and continues up.

    Example::
        >>> from snowflake.snowpark.window import Window
        >>> df = session.create_dataframe(
        ...     [
        ...         [1, 2, 1],
        ...         [1, 2, 3],
        ...         [2, 1, 10],
        ...         [2, 2, 1],
        ...         [2, 2, 3],
        ...     ],
        ...     schema=["x", "y", "z"]
        ... )
        >>> df.select(rank().over(Window.partition_by(col("X")).order_by(col("Y"))).alias("result")).sort("result").show()
        ------------
        |"RESULT"  |
        ------------
        |1         |
        |1         |
        |1         |
        |2         |
        |2         |
        ------------
        <BLANKLINE>
    rankr}   r~   r}   s    rV   rK  rK  "  s    < &I66rY   c                     t        d|       S )aA  
    Returns the relative rank of a value within a group of values, specified as a percentage
    ranging from 0.0 to 1.0.

    Example::
        >>> from snowflake.snowpark.window import Window
        >>> df = session.create_dataframe(
        ...     [
        ...         [1, 2, 1],
        ...         [1, 2, 3],
        ...         [2, 1, 10],
        ...         [2, 2, 1],
        ...         [2, 2, 3],
        ...     ],
        ...     schema=["x", "y", "z"]
        ... )
        >>> df.select(percent_rank().over(Window.partition_by("x").order_by(col("y"), col("z"))).alias("result")).sort("result").show()
        ------------
        |"RESULT"  |
        ------------
        |0.0       |
        |0.0       |
        |0.5       |
        |1.0       |
        |1.0       |
        ------------
        <BLANKLINE>
    percent_rankr}   r~   r}   s    rV   rM  rM  "  s    < .I>>rY   c                     t        d|       S )aZ  
    Returns the rank of a value within a group of values, without gaps in the ranks.
    The rank value starts at 1 and continues up sequentially.
    If two values are the same, they will have the same rank.

    Example::

        >>> from snowflake.snowpark.window import Window
        >>> window = Window.order_by("key")
        >>> df = session.create_dataframe([(1, "1"), (2, "2"), (1, "3"), (2, "4")], schema=["key", "value"])
        >>> df.select(dense_rank().over(window).as_("dense_rank")).collect()
        [Row(DENSE_RANK=1), Row(DENSE_RANK=1), Row(DENSE_RANK=2), Row(DENSE_RANK=2)]
    
dense_rankr}   r~   r}   s    rV   rO  rO  "  s     ,)<<rY   c                     t        d|       S )a  
    Returns a unique row number for each row within a window partition.
    The row number starts at 1 and continues up sequentially.

    Example::

        >>> from snowflake.snowpark.window import Window
        >>> df = session.create_dataframe(
        ...     [
        ...         [1, 2, 1],
        ...         [1, 2, 3],
        ...         [2, 1, 10],
        ...         [2, 2, 1],
        ...         [2, 2, 3],
        ...     ],
        ...     schema=["x", "y", "z"]
        ... )
        >>> df.select(col("X"), row_number().over(Window.partition_by(col("X")).order_by(col("Y"))).alias("result")).sort("X", "result").show()
        ------------------
        |"X"  |"RESULT"  |
        ------------------
        |1    |1         |
        |1    |2         |
        |2    |1         |
        |2    |2         |
        |2    |3         |
        ------------------
        <BLANKLINE>
    
row_numberr}   r~   r}   s    rV   rQ  rQ  #  s    > ,)<<rY   offsetdefault_valueignore_nullsc           	          |rt        d| |||g      nd}t        | d      }t        t        |j                  |t        j
                  |      |      d      }||_        |S )a  
    Accesses data in a previous row in the same result set without having to
    join the table to itself.

    Example::

        >>> from snowflake.snowpark.window import Window
        >>> df = session.create_dataframe(
        ...     [
        ...         [1, 2, 1],
        ...         [1, 2, 3],
        ...         [2, 1, 10],
        ...         [2, 2, 1],
        ...         [2, 2, 3],
        ...     ],
        ...     schema=["x", "y", "z"]
        ... )
        >>> df.select(lag("Z").over(Window.partition_by(col("X")).order_by(col("Y"))).alias("result")).sort("result").collect()
        [Row(RESULT=None), Row(RESULT=None), Row(RESULT=1), Row(RESULT=1), Row(RESULT=10)]
    lagNFr}   )r%   r9   r6   r   r   r  rz   r   rR  rS  rT  rQ   rn   r   r   s           rV   rV  rV  &#  sh    >  	EAv}l#KL  	q% A
AMM66??=#A<PC CHJrY   c           	          |rt        d| |||g      nd}t        | d      }t        t        |j                  |t        j
                  |      |      d      }||_        |S )a  
    Accesses data in a subsequent row in the same result set without having to
    join the table to itself.

    Example::

        >>> from snowflake.snowpark.window import Window
        >>> df = session.create_dataframe(
        ...     [
        ...         [1, 2, 1],
        ...         [1, 2, 3],
        ...         [2, 1, 10],
        ...         [2, 2, 1],
        ...         [2, 2, 3],
        ...     ],
        ...     schema=["x", "y", "z"]
        ... )
        >>> df.select(lead("Z").over(Window.partition_by(col("X")).order_by(col("Y"))).alias("result")).sort("result").collect()
        [Row(RESULT=None), Row(RESULT=None), Row(RESULT=1), Row(RESULT=3), Row(RESULT=3)]
    leadNFr}   )r%   r9   r6   r   r   r  rz   rW  s           rV   rY  rY  S#  sh    >  	FQ|$LM  	q&!A
Q]]FFOOM$BLQC CHJrY   c                     |rt        d| |g      nd}t        | d      }t        t        |j                  dd|      d      }||_        |S )az  
    Returns the last value within an ordered group of values.

    Example::

        >>> from snowflake.snowpark.window import Window
        >>> window = Window.partition_by("column1").order_by("column2")
        >>> df = session.create_dataframe([[1, 10], [1, 11], [2, 20], [2, 21]], schema=["column1", "column2"])
        >>> df.select(df["column1"], df["column2"], last_value(df["column2"]).over(window).as_("column2_last")).collect()
        [Row(COLUMN1=1, COLUMN2=10, COLUMN2_LAST=11), Row(COLUMN1=1, COLUMN2=11, COLUMN2_LAST=11), Row(COLUMN1=2, COLUMN2=20, COLUMN2_LAST=21), Row(COLUMN1=2, COLUMN2=21, COLUMN2_LAST=21)]
    
last_valueNFr}   )r%   r9   r6   r   r   rz   r   rT  rQ   rn   r   r   s         rV   r[  r[  #  sP      CL
lQ,=
>QUCq,'A
1==$lCu
UCCHJrY   c                     |rt        d| |g      nd}t        | d      }t        t        |j                  dd|      d      }||_        |S )a  
    Returns the first value within an ordered group of values.

    Example::

        >>> from snowflake.snowpark.window import Window
        >>> window = Window.partition_by("column1").order_by("column2")
        >>> df = session.create_dataframe([[1, 10], [1, 11], [2, 20], [2, 21]], schema=["column1", "column2"])
        >>> df.select(df["column1"], df["column2"], first_value(df["column2"]).over(window).as_("column2_first")).collect()
        [Row(COLUMN1=1, COLUMN2=10, COLUMN2_FIRST=10), Row(COLUMN1=1, COLUMN2=11, COLUMN2_FIRST=10), Row(COLUMN1=2, COLUMN2=20, COLUMN2_FIRST=20), Row(COLUMN1=2, COLUMN2=21, COLUMN2_FIRST=20)]
    first_valueNFr}   )r%   r9   r6   r   r   rz   r\  s         rV   r^  r^  #  sQ      DM
ma->
?RVCq-(A
AMM4|DPU
VCCHJrY   c                     |rt        d| ||g      nd}t        | d      }t        t        |j                  |d|      d      }||_        |S )av  
    Returns the nth value within an ordered group of values.

    Example::

        >>> from snowflake.snowpark.window import Window
        >>> window = Window.partition_by("column1").order_by("column2")
        >>> df = session.create_dataframe([[1, 10], [1, 11], [2, 20], [2, 21]], schema=["column1", "column2"])
        >>> df.select(df["column1"], df["column2"], nth_value(df["column2"], 2).over(window).as_("column2_2nd")).collect()
        [Row(COLUMN1=1, COLUMN2=10, COLUMN2_2ND=11), Row(COLUMN1=1, COLUMN2=11, COLUMN2_2ND=11), Row(COLUMN1=2, COLUMN2=20, COLUMN2_2ND=21), Row(COLUMN1=2, COLUMN2=21, COLUMN2_2ND=21)]
    	nth_valueNFr}   )r%   r9   r6   r   r   rz   )r   r   rT  rQ   rn   r   r   s          rV   r`  r`  #  sR      EN
kAq,+?
@SWCq+&A
!--D,?5
QCCHJrY   c                 6    t        | d      }t        d||      S )aj  
    Divides an ordered data set equally into the number of buckets specified by n.
    Buckets are sequentially numbered 1 through n.

    Args:
        e: The desired number of buckets; must be a positive integer value.

    Example::

        >>> from snowflake.snowpark.window import Window
        >>> df = session.create_dataframe(
        ...     [["C", "SPY", 3], ["C", "AAPL", 10], ["N", "SPY", 5], ["N", "AAPL", 7], ["Q", "MSFT", 3]],
        ...     schema=["exchange", "symbol", "shares"]
        ... )
        >>> df.select(col("exchange"), col("symbol"), ntile(3).over(Window.partition_by("exchange").order_by("shares")).alias("ntile_3")).order_by(["exchange","symbol"]).show()
        -------------------------------------
        |"EXCHANGE"  |"SYMBOL"  |"NTILE_3"  |
        -------------------------------------
        |C           |AAPL      |2          |
        |C           |SPY       |1          |
        |N           |AAPL      |2          |
        |N           |SPY       |1          |
        |Q           |MSFT      |1          |
        -------------------------------------
        <BLANKLINE>
    ntiler}   r0  r   s      rV   rb  rb  #  s    8 	a)A'1	::rY   c                     t        d| |      S )aG  
    Return a percentile value based on a continuous distribution of the
    input column. If no input row lies exactly at the desired percentile,
    the result is calculated using linear interpolation of the two nearest
    input values. NULL values are ignored in the calculation.

    Args:
        percentile: the percentile of the value that you want to find.
            The percentile must be a constant between 0.0 and 1.0. For example,
            if you want to find the value at the 90th percentile, specify 0.9.

    Example:

        >>> df = session.create_dataframe([
        ...     (0, 0), (0, 10), (0, 20), (0, 30), (0, 40),
        ...     (1, 10), (1, 20), (2, 10), (2, 20), (2, 25),
        ...     (2, 30), (3, 60), (4, None)
        ... ], schema=["k", "v"])
        >>> df.group_by("k").agg(percentile_cont(0.25).within_group("v").as_("percentile")).sort("k").collect()
        [Row(K=0, PERCENTILE=Decimal('10.000')), Row(K=1, PERCENTILE=Decimal('12.500')), Row(K=2, PERCENTILE=Decimal('17.500')), Row(K=3, PERCENTILE=Decimal('60.000')), Row(K=4, PERCENTILE=None)]
    percentile_contr}   r~   )r	  rQ   s     rV   rd  rd  #  s    6 +Z9MMrY   r.  c                 \    |D cg c]  }t        |d       }}t        dg|d| iS c c}w )a  
    Returns the largest value from a list of expressions.
    If any of the argument values is NULL, the result is NULL.
    GREATEST supports all data types, including VARIANT.

    Examples::

        >>> df = session.create_dataframe([[1, 2, 3], [2, 4, -1], [3, 6, None]], schema=["a", "b", "c"])
        >>> df.select(greatest(df["a"], df["b"], df["c"]).alias("greatest")).collect()
        [Row(GREATEST=3), Row(GREATEST=4), Row(GREATEST=None)]
    greatestrQ   r   rQ   r.  r2  r   s       rV   rf  rf  	$  s8     3::BJ	':A:*>q>I>> 	;r/  c                 \    |D cg c]  }t        |d       }}t        dg|d| iS c c}w )a  
    Returns the smallest value from a list of expressions.
    If any of the argument values is NULL, the result is NULL.
    LEAST supports all data types, including VARIANT.

    Example::

        >>> df = session.create_dataframe([[1, 2, 3], [2, 4, -1], [3, 6, None]], schema=["a", "b", "c"])
        >>> df.select(least(df["a"], df["b"], df["c"]).alias("least")).collect()
        [Row(LEAST=1), Row(LEAST=-1), Row(LEAST=None)]
    leastrQ   r   rg  s       rV   ri  ri  $  s8     077G	$7A7';A;;; 	8r/  c                     |rt        d| ||g      nd}t        | d      }t        t        |j                  ||      d      }||_        |S )a~  
    Returns the concatenated input values, separated by `delimiter` string.
    See `LISTAGG <https://docs.snowflake.com/en/sql-reference/functions/listagg.html>`_ for details.

    Args:
        e: A :class:`Column` object or column name that determines the values
            to be put into the list.
        delimiter: A string delimiter.
        is_distinct: Whether the input expression is distinct.

    Examples::

        >>> df = session.create_dataframe([1, 2, 3, 2, 4, 5], schema=["col"])
        >>> df.select(listagg("col", ",").within_group(df["col"].asc()).as_("result")).collect()
        [Row(RESULT='1,2,2,3,4,5')]
    listaggNFr}   )r%   r9   r6   r   r   rz   )r   r  r   rQ   rn   r   r   s          rV   rk  rk  +$  sU    4  	I9k'BC  	q)$A
	;?5
QCCHJrY   z*snowflake.snowpark.table.WhenMatchedClausec                 X    t         j                  j                  j                  | |      S )a  
    Specifies a matched clause for the :meth:`Table.merge <snowflake.snowpark.Table.merge>` action.
    See :class:`~snowflake.snowpark.table.WhenMatchedClause` for details.

    Convenience function to create a new WhenMatchedClause instance which is required together with an action when merging
    a Snowpark table with a Snowpark DataFrame (see snowflake.snowpark.Table.merge for more details).

    Example::

        >>> target_df = session.create_dataframe([(10, "old"), (10, "too_old"), (11, "old")], schema=["key", "value"])
        >>> target_df.write.save_as_table("my_table", mode="overwrite", table_type="temporary")
        >>> target = session.table("my_table")
        >>> source = session.create_dataframe([(10, "new"), (12, "new"), (13, "old")], schema=["key", "value"])
        >>> target.merge(source, (target["key"] == source["key"]) & (target["value"] == "too_old"),
        ...              [when_matched().update({"value": source["value"]})])
        MergeResult(rows_inserted=0, rows_updated=1, rows_deleted=0)
        >>> target.collect()
        [Row(KEY=10, VALUE='old'), Row(KEY=10, VALUE='new'), Row(KEY=11, VALUE='old')]

    r}   )r  r  tableWhenMatchedClauser1  rQ   s     rV   when_matchedrp  P$  s&    0 ##55i95UUrY   z-snowflake.snowpark.table.WhenNotMatchedClausec                 X    t         j                  j                  j                  | |      S )a  
    Specifies a not-matched clause for the :meth:`Table.merge <snowflake.snowpark.Table.merge>` action.
    See :class:`~snowflake.snowpark.table.WhenNotMatchedClause` for details.

    Convenience function to create a new WhenNotMatchedClause instance which is required together with an action when merging
    a Snowpark table with a Snowpark DataFrame (see snowflake.snowpark.Table.merge for more details).

    Example::

        >>> from snowflake.snowpark.types import IntegerType, StringType, StructField, StructType
        >>> schema = StructType([StructField("key", IntegerType()), StructField("value", StringType())])
        >>> target_df = session.create_dataframe([(10, "old"), (10, "too_old"), (11, "old")], schema=schema)
        >>> target_df.write.save_as_table("my_table", mode="overwrite", table_type="temporary")
        >>> target = session.table("my_table")
        >>> source = session.create_dataframe([(10, "new"), (12, "new"), (13, "old")], schema=schema)
        >>> target.merge(source, (target["key"] == source["key"]) & (target["value"] == "too_old"),
        ...              [when_not_matched().insert({"key": source["key"]})])
        MergeResult(rows_inserted=2, rows_updated=0, rows_deleted=0)
        >>> target.sort(col("key"), col("value")).collect()
        [Row(KEY=10, VALUE='old'), Row(KEY=10, VALUE='too_old'), Row(KEY=11, VALUE='old'), Row(KEY=12, VALUE=None), Row(KEY=13, VALUE=None)]
    r}   )r  r  rm  WhenNotMatchedClausero  s     rV   when_not_matchedrs  k$  s&    2 ##88i8XXrY      )return_typeinput_typesr  is_permanentstage_locationimportspackagesr6  if_not_existssessionparallelmax_batch_sizestatement_paramssource_code_displaystrictsecureexternal_access_integrationssecrets	immutablecommentartifact_repositoryresource_constraintrQ   funcru  rv  r  rw  rx  ry  rz  r6  r{  r|  z"snowflake.snowpark.session.Sessionr}  r~  r  r  r  r  r  r  r  r  r  r  c                4   t        di | t        j                  j                  j	                  |
      }
|
t        |
      j                  }n|
j                  j                  }| i|j                  d      Xt        j                  |fi d|d|d|d|d|d|d	|d
|d|	d|d|d|d|d|d|d|d|d|d|d|d|d||S  || fi d|d|d|d|d|d|d	|d
|d|	d|d|d|d|d|d|d|d|d|d|d|d|d||S )a(  Registers a Python function as a Snowflake Python UDF and returns the UDF.

    It can be used as either a function call or a decorator. In most cases you work with a single session.
    This function uses that session to register the UDF. If you have multiple sessions, you need to
    explicitly specify the ``session`` parameter of this function. If you have a function and would
    like to register it to multiple databases, use ``session.udf.register`` instead. See examples
    in :class:`~snowflake.snowpark.udf.UDFRegistration`.

    Args:
        func: A Python function used for creating the UDF.
        return_type: A :class:`~snowflake.snowpark.types.DataType` representing the return data
            type of the UDF. Optional if type hints are provided.
        input_types: A list of :class:`~snowflake.snowpark.types.DataType`
            representing the input data types of the UDF. Optional if
            type hints are provided.
        name: A string or list of strings that specify the name or fully-qualified
            object identifier (database name, schema name, and function name) for
            the UDF in Snowflake, which allows you to call this UDF in a SQL
            command or via :func:`call_udf()`. If it is not provided, a name will
            be automatically generated for the UDF. A name must be specified when
            ``is_permanent`` is ``True``.
        is_permanent: Whether to create a permanent UDF. The default is ``False``.
            If it is ``True``, a valid ``stage_location`` must be provided.
        stage_location: The stage location where the Python file for the UDF
            and its dependencies should be uploaded. The stage location must be specified
            when ``is_permanent`` is ``True``, and it will be ignored when
            ``is_permanent`` is ``False``. It can be any stage other than temporary
            stages and external stages.
        imports: A list of imports that only apply to this UDF. You can use a string to
            represent a file path (similar to the ``path`` argument in
            :meth:`~snowflake.snowpark.Session.add_import`) in this list, or a tuple of two
            strings to represent a file path and an import path (similar to the ``import_path``
            argument in :meth:`~snowflake.snowpark.Session.add_import`). These UDF-level imports
            will override the session-level imports added by
            :meth:`~snowflake.snowpark.Session.add_import`. Note that an empty list means
            no import for this UDF, and ``None`` or not specifying this parameter means using
            session-level imports.
        packages: A list of packages that only apply to this UDF. These UDF-level packages
            will override the session-level packages added by
            :meth:`~snowflake.snowpark.Session.add_packages` and
            :meth:`~snowflake.snowpark.Session.add_requirements`. Note that an empty list means
            no package for this UDF, and ``None`` or not specifying this parameter means using
            session-level packages. To use Python packages that are not available in Snowflake,
            refer to :meth:`~snowflake.snowpark.Session.custom_package_usage_config`.
        replace: Whether to replace a UDF that already was registered. The default is ``False``.
            If it is ``False``, attempting to register a UDF with a name that already exists
            results in a ``SnowparkSQLException`` exception being thrown. If it is ``True``,
            an existing UDF with the same name is overwritten.
        if_not_exists: Whether to skip creation of a UDF when one with the same signature already exists.
            The default is ``False``. ``if_not_exists`` and ``replace`` are mutually exclusive
            and a ``ValueError`` is raised when both are set. If it is ``True`` and a UDF with
            the same signature exists, the UDF creation is skipped.
        session: Use this session to register the UDF. If it's not specified, the session that you created before calling this function will be used.
            You need to specify this parameter if you have created multiple sessions before calling this method.
        parallel: The number of threads to use for uploading UDF files with the
            `PUT <https://docs.snowflake.com/en/sql-reference/sql/put.html#put>`_
            command. The default value is 4 and supported values are from 1 to 99.
            Increasing the number of threads can improve performance when uploading
            large UDF files.
        max_batch_size: The maximum number of rows per input pandas DataFrame or pandas Series
            inside a vectorized UDF. Because a vectorized UDF will be executed within a time limit,
            which is `60` seconds, this optional argument can be used to reduce the running time of
            every batch by setting a smaller batch size. Note that setting a larger value does not
            guarantee that Snowflake will encode batches with the specified number of rows. It will
            be ignored when registering a non-vectorized UDF.
        statement_params: Dictionary of statement level parameters to be set while executing this action.
        source_code_display: Display the source code of the UDF `func` as comments in the generated script.
            The source code is dynamically generated therefore it may not be identical to how the
            `func` is originally defined. The default is ``True``.
            If it is ``False``, source code will not be generated or displayed.
        strict: Whether the created UDF is strict. A strict UDF will not invoke the UDF if any input is
            null. Instead, a null value will always be returned for that row. Note that the UDF might
            still return null for non-null inputs.
        secure: Whether the created UDF is secure. For more information about secure functions,
            see `Secure UDFs <https://docs.snowflake.com/en/sql-reference/udf-secure.html>`_.
        external_access_integrations: The names of one or more external access integrations. Each
            integration you specify allows access to the external network locations and secrets
            the integration specifies.
        secrets: The key-value pairs of string types of secrets used to authenticate the external network location.
            The secrets can be accessed from handler code. The secrets specified as values must
            also be specified in the external access integration and the keys are strings used to
            retrieve the secrets using secret API.
        immutable: Whether the UDF result is deterministic or not for the same input.
        comment: Adds a comment for the created object. See
            `COMMENT <https://docs.snowflake.com/en/sql-reference/sql/comment>`_
        artifact_repository: The name of an artifact_repository that packages are found in. If unspecified, packages are
            pulled from Anaconda.
        resource_constraint: A dictionary containing a resource properties of a warehouse and then
            constraints needed to run this function. Eg ``{"architecture": "x86"}`` requires an x86
            warehouse be used for execution.

    Returns:
        A UDF function that can be called with :class:`~snowflake.snowpark.Column` expressions.

    Note:
        1. When type hints are provided and are complete for a function,
        ``return_type`` and ``input_types`` are optional and will be ignored.
        See details of supported data types for UDFs in
        :class:`~snowflake.snowpark.udf.UDFRegistration`.

            - You can use use :attr:`~snowflake.snowpark.types.Variant` to
              annotate a variant, and use :attr:`~snowflake.snowpark.types.Geography`
              or :attr:`~snowflake.snowpark.types.Geometry` to annotate geospatial
              types when defining a UDF.

            - You can use use :attr:`~snowflake.snowpark.types.PandasSeries` to annotate
              a pandas Series, and use :attr:`~snowflake.snowpark.types.PandasDataFrame`
              to annotate a pandas DataFrame when defining a vectorized UDF.
              Note that they are generic types so you can specify the element type in a
              pandas Series and DataFrame.

            - :class:`typing.Union` is not a valid type annotation for UDFs,
              but :class:`typing.Optional` can be used to indicate the optional type.

            - Type hints are not supported on functions decorated with decorators.

        2. A temporary UDF (when ``is_permanent`` is ``False``) is scoped to this ``session``
        and all UDF related files will be uploaded to a temporary session stage
        (:func:`session.get_session_stage() <snowflake.snowpark.Session.get_session_stage>`).
        For a permanent UDF, these files will be uploaded to the stage that you provide.

        3. By default, UDF registration fails if a function with the same name is already
        registered. Invoking :func:`udf` with ``replace`` set to ``True`` will overwrite the
        previously registered function.

        4. When registering a vectorized UDF, ``pandas`` library will be added as a package
        automatically, with the latest version on the Snowflake server. If you don't want to
        use this version, you can overwrite it by adding `pandas` with specific version
        requirement using ``package`` argument or :meth:`~snowflake.snowpark.Session.add_packages`.

    See Also:
        :class:`~snowflake.snowpark.udf.UDFRegistration`

    UDFs can be created as anonymous UDFs

    Example::

        >>> from snowflake.snowpark.types import IntegerType
        >>> add_one = udf(lambda x: x+1, return_type=IntegerType(), input_types=[IntegerType()])
        >>> df = session.create_dataframe([1, 2, 3], schema=["a"])
        >>> df.select(add_one(col("a")).as_("ans")).collect()
        [Row(ANS=2), Row(ANS=3), Row(ANS=4)]

    or as named UDFs that are accessible in the same session. Instead of calling `udf` as function, it can be also used
    as a decorator:

    Example::

        >>> @udf(name="minus_one", replace=True)
        ... def minus_one(x: int) -> int:
        ...     return x - 1
        >>> df.select(minus_one(col("a")).as_("ans")).collect()
        [Row(ANS=0), Row(ANS=1), Row(ANS=2)]
        >>> session.sql("SELECT minus_one(10)").collect()
        [Row(MINUS_ONE(10)=9)]

    r|  _registered_object_nameru  rv  r  rw  rx  ry  rz  r6  r{  r}  r~  r  r  r  r  r  r  r  r  r  r  rQ   rT   )r,   r  r  r|  '_get_sandbox_conditional_active_sessionrG   registerudfrX  	functoolspartial)r  ru  rv  r  rw  rx  ry  rz  r6  r{  r|  r}  r~  r  r  r  r  r  r  r  r  r  r  rQ   rR  udf_registration_methods                             rV   r  r  $  sO   x "6"  ((PPG "1'"B"K"K")++"6"6|

#<=E  #
#
 $
 	

 &
 *
 
 
 
 (
 
 *
 .
 !4
 
  !
" *F#
$ %
&  '
( )
* !4+
, !4-
.  1
 	
6 '
#
 $
 	

 &
 *
 
 
 
 (
 
 *
 .
 !4
 
  !
" *F#
$ %
&  '
( )
* !4+
, !4-
.  1
 	
rY   )rv  r  rw  rx  ry  rz  r6  r{  r|  r}  r  r  r  r  r  r  r  r  r  rQ   handleroutput_schemar@   c                   t        di | t        j                  j                  j	                  |
      }
|
t        |
      j                  }n|
j                  j                  }| c|j                  d      Rt        j                  |fi d|d|d|d|d|d|d	|d
|d|	d|d|d|d|d|d|d|d|d|d|d||S  || fi d|d|d|d|d|d|d	|d
|d|	d|d|d|d|d|d|d|d|d|d|d||S )a&  Registers a Python class as a Snowflake Python UDTF and returns the UDTF.

    It can be used as either a function call or a decorator. In most cases you work with a single session.
    This function uses that session to register the UDTF. If you have multiple sessions, you need to
    explicitly specify the ``session`` parameter of this function. If you have a function and would
    like to register it to multiple databases, use ``session.udtf.register`` instead. See examples
    in :class:`~snowflake.snowpark.udtf.UDTFRegistration`.

    Args:
        handler: A Python class used for creating the UDTF.
        output_schema: A list of column names, or a :class:`~snowflake.snowpark.types.StructType` instance that represents the table function's columns, or a ``PandasDataFrameType`` instance for vectorized UDTF.
         If a list of column names is provided, the ``process`` method of the handler class must have return type hints to indicate the output schema data types.
        input_types: A list of :class:`~snowflake.snowpark.types.DataType`
            representing the input data types of the UDTF. Optional if
            type hints are provided.
        name: A string or list of strings that specify the name or fully-qualified
            object identifier (database name, schema name, and function name) for
            the UDTF in Snowflake, which allows you to call this UDTF in a SQL
            command or via :func:`call_udtf()`. If it is not provided, a name will
            be automatically generated for the UDTF. A name must be specified when
            ``is_permanent`` is ``True``.
        is_permanent: Whether to create a permanent UDTF. The default is ``False``.
            If it is ``True``, a valid ``stage_location`` must be provided.
        stage_location: The stage location where the Python file for the UDTF
            and its dependencies should be uploaded. The stage location must be specified
            when ``is_permanent`` is ``True``, and it will be ignored when
            ``is_permanent`` is ``False``. It can be any stage other than temporary
            stages and external stages.
        imports: A list of imports that only apply to this UDTF. You can use a string to
            represent a file path (similar to the ``path`` argument in
            :meth:`~snowflake.snowpark.Session.add_import`) in this list, or a tuple of two
            strings to represent a file path and an import path (similar to the ``import_path``
            argument in :meth:`~snowflake.snowpark.Session.add_import`). These UDTF-level imports
            will override the session-level imports added by
            :meth:`~snowflake.snowpark.Session.add_import`.
        packages: A list of packages that only apply to this UDTF. These UDTF-level packages
            will override the session-level packages added by
            :meth:`~snowflake.snowpark.Session.add_packages` and
            :meth:`~snowflake.snowpark.Session.add_requirements`. To use Python packages that are not available
            in Snowflake, refer to :meth:`~snowflake.snowpark.Session.custom_package_usage_config`.
        replace: Whether to replace a UDTF that already was registered. The default is ``False``.
            If it is ``False``, attempting to register a UDTF with a name that already exists
            results in a ``SnowparkSQLException`` exception being thrown. If it is ``True``,
            an existing UDTF with the same name is overwritten.
        if_not_exists: Whether to skip creation of a UDTF when one with the same signature already exists.
            The default is ``False``. ``if_not_exists`` and ``replace`` are mutually exclusive
            and a ``ValueError`` is raised when both are set. If it is ``True`` and a UDTF with
            the same signature exists, the UDTF creation is skipped.
        session: Use this session to register the UDTF. If it's not specified, the session that you created before calling this function will be used.
            You need to specify this parameter if you have created multiple sessions before calling this method.
        parallel: The number of threads to use for uploading UDTF files with the
            `PUT <https://docs.snowflake.com/en/sql-reference/sql/put.html#put>`_
            command. The default value is 4 and supported values are from 1 to 99.
            Increasing the number of threads can improve performance when uploading
            large UDTF files.
        statement_params: Dictionary of statement level parameters to be set while executing this action.
        strict: Whether the created UDTF is strict. A strict UDTF will not invoke the UDTF if any input is
            null. Instead, a null value will always be returned for that row. Note that the UDTF might
            still return null for non-null inputs.
        secure: Whether the created UDTF is secure. For more information about secure functions,
            see `Secure UDFs <https://docs.snowflake.com/en/sql-reference/udf-secure.html>`_.
        external_access_integrations: The names of one or more external access integrations. Each
            integration you specify allows access to the external network locations and secrets
            the integration specifies.
        secrets: The key-value pairs of string types of secrets used to authenticate the external network location.
            The secrets can be accessed from handler code. The secrets specified as values must
            also be specified in the external access integration and the keys are strings used to
            retrieve the secrets using secret API.
        immutable: Whether the UDTF result is deterministic or not for the same input.
        comment: Adds a comment for the created object. See
            `COMMENT <https://docs.snowflake.com/en/sql-reference/sql/comment>`_
        artifact_repository: The name of an artifact_repository that packages are found in. If unspecified, packages are
            pulled from Anaconda.
        resource_constraint: A dictionary containing a resource properties of a warehouse and then
            constraints needed to run this function. Eg ``{"architecture": "x86"}`` requires an x86
            warehouse be used for execution.

    Returns:
        A UDTF function that can be called with :class:`~snowflake.snowpark.Column` expressions.

    Note:
        1. When type hints are provided and are complete for a function,
        ``return_type`` and ``input_types`` are optional and will be ignored.
        See details of supported data types for UDTFs in
        :class:`~snowflake.snowpark.udtf.UDTFRegistration`.

            - You can use use :attr:`~snowflake.snowpark.types.Variant` to
              annotate a variant, and use :attr:`~snowflake.snowpark.types.Geography`
              or :attr:`~snowflake.snowpark.types.Geometry` to annotate geospatial
              types when defining a UDTF.

            - :class:`typing.Union` is not a valid type annotation for UDTFs,
              but :class:`typing.Optional` can be used to indicate the optional type.

            - Type hints are not supported on functions decorated with decorators.

        2. A temporary UDTF (when ``is_permanent`` is ``False``) is scoped to this ``session``
        and all UDTF related files will be uploaded to a temporary session stage
        (:func:`session.get_session_stage() <snowflake.snowpark.Session.get_session_stage>`).
        For a permanent UDTF, these files will be uploaded to the stage that you specify.

        3. By default, UDTF registration fails if a function with the same name is already
        registered. Invoking :func:`udtf` with ``replace`` set to ``True`` will overwrite the
        previously registered function.

    See Also:
        :class:`~snowflake.snowpark.udtf.UDTFRegistration`


    Example::

        >>> from snowflake.snowpark.types import IntegerType, StructField, StructType
        >>> class PrimeSieve:
        ...     def process(self, n):
        ...         is_prime = [True] * (n + 1)
        ...         is_prime[0] = False
        ...         is_prime[1] = False
        ...         p = 2
        ...         while p * p <= n:
        ...             if is_prime[p]:
        ...                 # set all multiples of p to False
        ...                 for i in range(p * p, n + 1, p):
        ...                     is_prime[i] = False
        ...             p += 1
        ...         # yield all prime numbers
        ...         for p in range(2, n + 1):
        ...             if is_prime[p]:
        ...                 yield (p,)
        >>> prime_udtf = udtf(PrimeSieve, output_schema=StructType([StructField("number", IntegerType())]), input_types=[IntegerType()])
        >>> session.table_function(prime_udtf(lit(20))).collect()
        [Row(NUMBER=2), Row(NUMBER=3), Row(NUMBER=5), Row(NUMBER=7), Row(NUMBER=11), Row(NUMBER=13), Row(NUMBER=17), Row(NUMBER=19)]

        Instead of calling `udtf` it is also possible to use udtf as a decorator.

    Example::

        >>> @udtf(name="alt_int",replace=True, output_schema=StructType([StructField("number", IntegerType())]), input_types=[IntegerType()])
        ... class Alternator:
        ...     def __init__(self):
        ...         self._positive = True
        ...
        ...     def process(self, n):
        ...         for i in range(n):
        ...             if self._positive:
        ...                 yield (1,)
        ...             else:
        ...                 yield (-1,)
        ...             self._positive = not self._positive
        >>> session.table_function("alt_int", lit(3)).collect()
        [Row(NUMBER=1), Row(NUMBER=-1), Row(NUMBER=1)]
        >>> session.table_function("alt_int", lit(2)).collect()
        [Row(NUMBER=1), Row(NUMBER=-1)]
        >>> session.table_function("alt_int", lit(1)).collect()
        [Row(NUMBER=1)]
    r  r  r  rv  r  rw  rx  ry  rz  r6  r{  r}  r  r  r  r  r  r  r  r  r  rQ   rT   )r,   r  r  r|  r  rI   r  udtfrX  r  r  )r  r  rv  r  rw  rx  ry  rz  r6  r{  r|  r}  r  r  r  r  r  r  r  r  r  rQ   rR  udtf_registration_methods                           rV   r  r  %  s'   p "6"  ((PPG #3G#D#M#M #*<<#8#8 6::&?@H  $
'
 $
 	

 &
 *
 
 
 
 (
 
 .
 
 
 *F
  !
"  #
$ %
& !4'
( !4)
*  -
 	
2 (
'
 $
 	

 &
 *
 
 
 
 (
 
 .
 
 
 *F
  !
"  #
$ %
& !4'
( !4)
*  -
 	
rY   )ru  rv  r  rw  rx  ry  rz  r6  r{  r|  r}  r  r  r  r  r  r  r  rQ   c                   t        di | t        j                  j                  j	                  |
      }
|
t        |
      j                  }n|
j                  j                  }| ]|j                  d      Lt        j                  |fi d|d|d|d|d|d|d	|d
|d|	d|d|d|d|d|d|d|d|d||S  || fi d|d|d|d|d|d|d	|d
|d|	d|d|d|d|d|d|d|d|d||S )a$  Registers a Python class as a Snowflake Python UDAF and returns the UDAF.

    It can be used as either a function call or a decorator. In most cases you work with a single session.
    This function uses that session to register the UDAF. If you have multiple sessions, you need to
    explicitly specify the ``session`` parameter of this function. If you have a function and would
    like to register it to multiple databases, use ``session.udaf.register`` instead. See examples
    in :class:`~snowflake.snowpark.udaf.UDAFRegistration`.

    Args:
        handler: A Python class used for creating the UDAF.
        return_type: A :class:`~snowflake.snowpark.types.DataType` representing the return data
            type of the UDAF. Optional if type hints are provided.
        input_types: A list of :class:`~snowflake.snowpark.types.DataType`
            representing the input data types of the UDAF. Optional if
            type hints are provided.
        name: A string or list of strings that specify the name or fully-qualified
            object identifier (database name, schema name, and function name) for
            the UDAF in Snowflake, which allows you to call this UDAF in a SQL
            command or via :func:`DataFrame.agg`. If it is not provided, a name will
            be automatically generated for the UDAF. A name must be specified when
            ``is_permanent`` is ``True``.
        is_permanent: Whether to create a permanent UDAF. The default is ``False``.
            If it is ``True``, a valid ``stage_location`` must be provided.
        stage_location: The stage location where the Python file for the UDAF
            and its dependencies should be uploaded. The stage location must be specified
            when ``is_permanent`` is ``True``, and it will be ignored when
            ``is_permanent`` is ``False``. It can be any stage other than temporary
            stages and external stages.
        imports: A list of imports that only apply to this UDAF. You can use a string to
            represent a file path (similar to the ``path`` argument in
            :meth:`~snowflake.snowpark.Session.add_import`) in this list, or a tuple of two
            strings to represent a file path and an import path (similar to the ``import_path``
            argument in :meth:`~snowflake.snowpark.Session.add_import`). These UDAF-level imports
            will override the session-level imports added by
            :meth:`~snowflake.snowpark.Session.add_import`. Note that an empty list means
            no import for this UDAF, and ``None`` or not specifying this parameter means using
            session-level imports.
        packages: A list of packages that only apply to this UDAF. These UDAF-level packages
            will override the session-level packages added by
            :meth:`~snowflake.snowpark.Session.add_packages` and
            :meth:`~snowflake.snowpark.Session.add_requirements`. Note that an empty list means
            no package for this UDAF, and ``None`` or not specifying this parameter means using
            session-level packages. To use Python packages that are not available in Snowflake,
            refer to :meth:`~snowflake.snowpark.Session.custom_package_usage_config`.
        replace: Whether to replace a UDAF that already was registered. The default is ``False``.
            If it is ``False``, attempting to register a UDAF with a name that already exists
            results in a ``SnowparkSQLException`` exception being thrown. If it is ``True``,
            an existing UDAF with the same name is overwritten.
        if_not_exists: Whether to skip creation of a UDAF when one with the same signature already exists.
            The default is ``False``. ``if_not_exists`` and ``replace`` are mutually exclusive
            and a ``ValueError`` is raised when both are set. If it is ``True`` and a UDAF with
            the same signature exists, the UDAF creation is skipped.
        session: Use this session to register the UDAF. If it's not specified, the session that you created before
            calling this function will be used. You need to specify this parameter if you have created multiple
            sessions before calling this method.
        parallel: The number of threads to use for uploading UDAF files with the
            `PUT <https://docs.snowflake.com/en/sql-reference/sql/put.html#put>`_
            command. The default value is 4 and supported values are from 1 to 99.
            Increasing the number of threads can improve performance when uploading
            large UDAF files.
        statement_params: Dictionary of statement level parameters to be set while executing this action.
        immutable: Whether the UDAF result is deterministic or not for the same input.
        external_access_integrations: The names of one or more external access integrations. Each
            integration you specify allows access to the external network locations and secrets
            the integration specifies.
        secrets: The key-value pairs of string types of secrets used to authenticate the external network location.
            The secrets can be accessed from handler code. The secrets specified as values must
            also be specified in the external access integration and the keys are strings used to
            retrieve the secrets using secret API.
        comment: Adds a comment for the created object. See
            `COMMENT <https://docs.snowflake.com/en/sql-reference/sql/comment>`_
        artifact_repository: The name of an artifact_repository that packages are found in. If unspecified, packages are
            pulled from Anaconda.
        resource_constraint: A dictionary containing a resource properties of a warehouse and then
            constraints needed to run this function. Eg ``{"architecture": "x86"}`` requires an x86
            warehouse be used for execution.

    Returns:
        A UDAF function that can be called with :class:`~snowflake.snowpark.Column` expressions.

    Note:
        1. When type hints are provided and are complete for a function,
        ``return_type`` and ``input_types`` are optional and will be ignored.
        See details of supported data types for UDAFs in
        :class:`~snowflake.snowpark.udaf.UDAFRegistration`.

            - You can use use :attr:`~snowflake.snowpark.types.Variant` to
              annotate a variant, and use :attr:`~snowflake.snowpark.types.Geography`
              to annotate a geography when defining a UDAF.

            - :class:`typing.Union` is not a valid type annotation for UDAFs,
              but :class:`typing.Optional` can be used to indicate the optional type.

            - Type hints are not supported on functions decorated with decorators.

        2. A temporary UDAF (when ``is_permanent`` is ``False``) is scoped to this ``session``
        and all UDAF related files will be uploaded to a temporary session stage
        (:func:`session.get_session_stage() <snowflake.snowpark.Session.get_session_stage>`).
        For a permanent UDAF, these files will be uploaded to the stage that you provide.

        3. By default, UDAF registration fails if a function with the same name is already
        registered. Invoking :func:`udaf` with ``replace`` set to ``True`` will overwrite the
        previously registered function.

    See Also:
        :class:`~snowflake.snowpark.udaf.UDAFRegistration`


    Example::
        >>> from snowflake.snowpark.types import IntegerType
        >>> class PythonSumUDAF:
        ...     def __init__(self) -> None:
        ...         self._sum = 0
        ...
        ...     @property
        ...     def aggregate_state(self):
        ...         return self._sum
        ...
        ...     def accumulate(self, input_value):
        ...         self._sum += input_value
        ...
        ...     def merge(self, other_sum):
        ...         self._sum += other_sum
        ...
        ...     def finish(self):
        ...         return self._sum
        >>> sum_udaf = udaf(
        ...     PythonSumUDAF,
        ...     name="sum_int",
        ...     replace=True,
        ...     return_type=IntegerType(),
        ...     input_types=[IntegerType()],
        ... )
        >>> df = session.create_dataframe([[1, 3], [1, 4], [2, 5], [2, 6]]).to_df("a", "b")
        >>> df.agg(sum_udaf("a")).collect()
        [Row(SUM_INT("A")=6)]

        Instead of calling `udaf` it is also possible to use udaf as a decorator.

    Example::

        >>> @udaf(name="sum_int", replace=True, return_type=IntegerType(), input_types=[IntegerType()])
        ... class PythonSumUDAF:
        ...     def __init__(self) -> None:
        ...         self._sum = 0
        ...
        ...     @property
        ...     def aggregate_state(self):
        ...         return self._sum
        ...
        ...     def accumulate(self, input_value):
        ...         self._sum += input_value
        ...
        ...     def merge(self, other_sum):
        ...         self._sum += other_sum
        ...
        ...     def finish(self):
        ...         return self._sum

        >>> df = session.create_dataframe([[1, 3], [1, 4], [2, 5], [2, 6]]).to_df("a", "b")
        >>> df.agg(PythonSumUDAF("a")).collect()
        [Row(SUM_INT("A")=6)]
    r  r  ru  rv  r  rw  rx  ry  rz  r6  r{  r}  r  r  r  r  r  r  r  rQ   rT   )r,   r  r  r|  r  rE   r  udafrX  r  r  )r  ru  rv  r  rw  rx  ry  rz  r6  r{  r|  r}  r  r  r  r  r  r  r  rQ   rR  udaf_registration_methods                         rV   r  r  |&  s   | "6"  ((PPG #3G#D#M#M #*<<#8#8 6::&?@H  $
#
 $
 	

 &
 *
 
 
 
 (
 
 .
  
 *F
 
  !
" !4#
$ !4%
&  )
 	
. (
#
 $
 	

 &
 *
 
 
 
 (
 
 .
  
 *F
 
  !
" !4#
$ !4%
&  )
 	
rY   )ru  rv  r  rw  rx  ry  rz  r6  r{  r|  r}  r~  r  r  r  r  r  r  r  r  rQ   c                    t        | fi d|d|d|d|d|d|d|d|d	|	d
|
d|d|d|d|d|d|d|d|d|d|ddd||S )a  
    Registers a Python function as a vectorized UDF and returns the UDF.
    The arguments, return value and usage of this function are exactly the same as
    :func:`udf`, but this function can only be used for registering vectorized UDFs.
    See examples in :class:`~snowflake.snowpark.udf.UDFRegistration`.

    See Also:
        - :func:`udf`
        - :meth:`UDFRegistration.register() <snowflake.snowpark.udf.UDFRegistration.register>`

    Example::

        >>> from snowflake.snowpark.types import PandasSeriesType, PandasDataFrameType, IntegerType
        >>> add_one_df_pandas_udf = pandas_udf(
        ...     lambda df: df[0] + df[1] + 1,
        ...     return_type=PandasSeriesType(IntegerType()),
        ...     input_types=[PandasDataFrameType([IntegerType(), IntegerType()])]
        ... )
        >>> df = session.create_dataframe([[1, 2], [3, 4]], schema=["a", "b"])
        >>> df.select(add_one_df_pandas_udf("a", "b").alias("result")).order_by("result").show()
        ------------
        |"RESULT"  |
        ------------
        |4         |
        |8         |
        ------------
        <BLANKLINE>

    or as named pandas UDFs that are accesible in the same session. Instead of calling `pandas_udf` as function,
    it can be also used as a decorator:

    Example::

        >>> from snowflake.snowpark.types import PandasSeriesType, PandasDataFrameType, IntegerType
        >>> @pandas_udf(
        ...     return_type=PandasSeriesType(IntegerType()),
        ...     input_types=[PandasDataFrameType([IntegerType(), IntegerType()])],
        ... )
        ... def add_one_df_pandas_udf(df):
        ...     return df[0] + df[1] + 1
        >>> df = session.create_dataframe([[1, 2], [3, 4]], schema=["a", "b"])
        >>> df.select(add_one_df_pandas_udf("a", "b").alias("result")).order_by("result").show()
        ------------
        |"RESULT"  |
        ------------
        |4         |
        |8         |
        ------------
        <BLANKLINE>
    ru  rv  r  rw  rx  ry  rz  r6  r{  r|  r}  r~  r  r  r  r  r  r  r  r  _from_pandas_udf_functionTrQ   )r  )r  ru  rv  r  rw  rx  ry  rz  r6  r{  r|  r}  r~  r  r  r  r  r  r  r  r  rQ   rR  s                          rV   
pandas_udfr  t'  s    ^    	
 " &    $   & * 0  !" #$ &B%& '( )* +, #'-. 
1 rY   r)  c                       fd}|S )a  Marks a function or UDTF method as vectorized for pandas input.
    This decorator is a no-op for local invocation.
    When combined with :func:`udf`, this will make the function behave as a vectorized UDF
    using :func:`pandas_udf`.

    Args:
        input: The type of the input to the function. Must be either ``pandas.Series`` or ``pandas.DataFrame``.
        max_batch_size: The maximum batch size to use for the function. If not provided, the default batch size will be used.

    Returns:
        A decorator that marks the function as vectorized.

    Example::

        >>> import pandas as pd
        >>> from snowflake.snowpark.functions import udf, vectorized
        >>> from snowflake.snowpark.types import IntegerType
        >>> @udf(return_type=IntegerType(), input_types=[IntegerType(), IntegerType()])
        ... @vectorized(input=pd.DataFrame)
        ... def add_one_to_inputs(df):
        ...     return df[0] + df[1] + 1
        >>> df = session.create_dataframe([[1, 2], [3, 4]], schema=["a", "b"])
        >>> df.select(add_one_to_inputs("a", "b").alias("result")).collect()
        [Row(RESULT=4), Row(RESULT=8)]

    See Also:
        - :func:`udf`
        - :func:`pandas_udf`
    c                 v      _         t               _        t        j                          fd       }|S )Nc                       | i |S rN  rT   )rJ  rR  r  s     rV   _innerz.vectorized.<locals>._decorator.<locals>._inner(  s    d%f%%rY   )_sf_vectorized_inputrG  _sf_max_batch_sizer  wraps)r  r  r)  r~  s   ` rV   
_decoratorzvectorized.<locals>._decorator'  sB    !&%#&~#6A  
		& 
	& rY   rT   )r)  r~  r  s   `` rV   
vectorizedr  '  s    > rY   )rv  input_namesr  rw  rx  ry  rz  r6  r{  r|  r}  r  r  r  r  r  r  r~  r  rQ   r  c                    t        | fi d|d|d|d|d|d|d|d|d	|	d
|
d|d|d|d|d|d|d|d|d|d|d||S )aq  Registers a Python class as a vectorized Python UDTF and returns the UDTF.

    The arguments, return value and usage of this function are exactly the same as
    :func:`udtf`, but this function can only be used for registering vectorized UDTFs.
    See examples in :class:`~snowflake.snowpark.udtf.UDTFRegistration`.

    See Also:
        - :func:`udtf`
        - :meth:`UDTFRegistration.register() <snowflake.snowpark.udf.UDTFRegistration.register>`

    Compared to the default row-by-row processing pattern of a normal UDTF, which sometimes is
    inefficient, vectorized Python UDTFs (user-defined table functions) enable seamless partition-by-partition processing
    by operating on partitions as
    `pandas DataFrames <https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.html>`_
    and returning results as
    `pandas DataFrames <https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.html>`_
    or lists of `pandas arrays <https://pandas.pydata.org/docs/reference/api/pandas.array.html>`_
    or `pandas Series <https://pandas.pydata.org/docs/reference/series.html>`_.

    In addition, vectorized Python UDTFs allow for easy integration with libraries that operate on pandas DataFrames or pandas arrays.

    A vectorized UDTF handler class:
    - defines an :code:`end_partition` method that takes in a DataFrame argument and returns a :code:`pandas.DataFrame` or a tuple of :code:`pandas.Series` or :code:`pandas.arrays` where each array is a column.
    - does NOT define a :code:`process` method.
    - optionally defines a handler class with an :code:`__init__` method which will be invoked before processing each partition.

    You can use :func:`~snowflake.snowpark.functions.udtf`, :meth:`register` or
    :func:`~snowflake.snowpark.functions.pandas_udtf` to create a vectorized UDTF by providing
    appropriate return and input types. If you would like to use :meth:`register_from_file` to
    create a vectorized UDTF, you need to explicitly mark the handler method as vectorized using
    either the decorator `@vectorized(input=pandas.DataFrame)` or setting `<class>.end_partition._sf_vectorized_input = pandas.DataFrame`

    Note: A vectorized UDTF must be called with `~snowflake.snowpark.Window.partition_by` to build the partitions.

    Example::
        >>> from snowflake.snowpark.types import PandasSeriesType, PandasDataFrameType, IntegerType
        >>> class multiply:
        ...     def __init__(self):
        ...         self.multiplier = 10
        ...     def end_partition(self, df):
        ...         df.col1 = df.col1*self.multiplier
        ...         df.col2 = df.col2*self.multiplier
        ...         yield df
        >>> multiply_udtf = pandas_udtf(
        ...     multiply,
        ...     output_schema=PandasDataFrameType([StringType(), IntegerType(), FloatType()], ["id_", "col1_", "col2_"]),
        ...     input_types=[PandasDataFrameType([StringType(), IntegerType(), FloatType()])],
        ...     input_names=['"id"', '"col1"', '"col2"']
        ... )
        >>> df = session.create_dataframe([['x', 3, 35.9],['x', 9, 20.5]], schema=["id", "col1", "col2"])
        >>> df.select(multiply_udtf("id", "col1", "col2").over(partition_by=["id"])).sort("col1_").show()
        -----------------------------
        |"ID_"  |"COL1_"  |"COL2_"  |
        -----------------------------
        |x      |30       |359.0    |
        |x      |90       |205.0    |
        -----------------------------
        <BLANKLINE>

    Example::

        >>> @pandas_udtf(
        ... output_schema=PandasDataFrameType([StringType(), IntegerType(), FloatType()], ["id_", "col1_", "col2_"]),
        ... input_types=[PandasDataFrameType([StringType(), IntegerType(), FloatType()])],
        ... input_names=['"id"', '"col1"', '"col2"']
        ... )
        ... class _multiply:
        ...     def __init__(self):
        ...         self.multiplier = 10
        ...     def end_partition(self, df):
        ...         df.col1 = df.col1*self.multiplier
        ...         df.col2 = df.col2*self.multiplier
        ...         yield df
        >>> df.select(multiply_udtf("id", "col1", "col2").over(partition_by=["id"])).sort("col1_").show()
        -----------------------------
        |"ID_"  |"COL1_"  |"COL2_"  |
        -----------------------------
        |x      |30       |359.0    |
        |x      |90       |205.0    |
        -----------------------------
        <BLANKLINE>
    r  rv  r  r  rw  rx  ry  rz  r6  r{  r|  r}  r  r  r  r  r  r  r~  r  rQ   )r  )r  r  rv  r  r  rw  rx  ry  rz  r6  r{  r|  r}  r  r  r  r  r  r  r~  r  rQ   rR  s                          rV   pandas_udtfr  (  s    ^ #    	
  " &    $   *   !" &B#$ %& '( &)* +, 
/ rY   udf_namec                `    t        |        |rt        d| g|      nd}t        | g|d||dS )a}  Calls a user-defined function (UDF) by name.

    Args:
        udf_name: The name of UDF in Snowflake.
        args: Arguments can be in two types:

            - :class:`~snowflake.snowpark.Column`, or
            - Basic Python types, which are converted to Snowpark literals.

    Example::
        >>> from snowflake.snowpark.types import IntegerType
        >>> udf_def = session.udf.register(lambda x, y: x + y, name="add_columns", input_types=[IntegerType(), IntegerType()], return_type=IntegerType(), replace=True)
        >>> df = session.create_dataframe([[1, 2]], schema=["a", "b"])
        >>> df.select(call_udf("add_columns", col("a"), col("b"))).show()
        -------------------------------
        |"ADD_COLUMNS(""A"", ""B"")"  |
        -------------------------------
        |3                            |
        -------------------------------
        <BLANKLINE>
    call_udfNzfunctions.call_udf)api_call_sourcerz   rQ   )r0   r%   r   )r  rQ   rJ  rn   s       rV   r  r  (  sM    . "@I
j8*;d*;
<tC	 - rY   function_namec                    d}|r$t        j                         }t        || g|i | t        j                  j
                  j                  | g|||d|}|S )ab  Invokes a Snowflake table function, including system-defined table functions and user-defined table functions.

    It returns a :meth:`~snowflake.snowpark.table_function.TableFunctionCall` so you can specify the partition clause.

    Args:
        function_name: The name of the table function.
        args: The positional arguments of the table function.
        **kwargs: The named arguments of the table function. Some table functions (e.g., ``flatten``) have named arguments instead of positional ones.

    Example::
        >>> from snowflake.snowpark.functions import lit
        >>> session.table_function(call_table_function("split_to_table", lit("split words to table"), lit(" ")).over()).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')]
    Nry   )ro   rp   r!   r  r  r  r*  )r  rQ   rJ  rR  rn   r  s         rV   call_table_functionr  (  sl    , Cjjl']LTLVL""11CC#&)?EI rY   c                 B      fd}|rt        d g      nd}||_        |S )a  Create a function object to invoke a Snowflake table function.

    Args:
        function_name: The name of the table function.

    Example::
        >>> from snowflake.snowpark.functions import lit
        >>> split_to_table = table_function("split_to_table")
        >>> session.table_function(split_to_table(lit("split words to table"), lit(" ")).over()).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')]
    c                  "    t        g| i |S rN  )r  )rJ  rR  r  s     rV   <lambda>z table_function.<locals>.<lambda>(  s     !4"" &" rY   r  N)r%   rz   )r  rQ   fnrn   s   `   rV   r  r  (  s/    
B
 EN
.
@SWCBGIrY   c                4    t        j                  | g|d|iS )a  Invokes a Snowflake `system-defined function <https://docs.snowflake.com/en/sql-reference-functions.html>`_ (built-in function) with the specified name
    and arguments.

    Args:
        function_name: The name of built-in function in Snowflake
        args: Arguments can be in two types:

            - :class:`~snowflake.snowpark.Column`, or
            - Basic Python types, which are converted to Snowpark literals.

    Example::
        >>> df = session.create_dataframe([1, 2, 3, 4], schema=["a"])  # a single column with 4 rows
        >>> df.select(call_function("avg", col("a"))).show()
        ----------------
        |"AVG(""A"")"  |
        ----------------
        |2.500000      |
        ----------------
        <BLANKLINE>

    rQ   )r   call_function)r  rQ   rJ  s      rV   r  r  (  s    6 **=U4U9UUrY   c                 0    t        j                  | |      S )a  
    Function object to invoke a Snowflake `system-defined function <https://docs.snowflake.com/en/sql-reference-functions.html>`_ (built-in function). Use this to invoke
    any built-in functions not explicitly listed in this object.

    Args:
        function_name: The name of built-in function in Snowflake.

    Returns:
        A :class:`Callable` object for calling a Snowflake system-defined function.

    Example::
        >>> df = session.create_dataframe([1, 2, 3, 4], schema=["a"])  # a single column with 4 rows
        >>> df.select(call_function("avg", col("a"))).show()
        ----------------
        |"AVG(""A"")"  |
        ----------------
        |2.500000      |
        ----------------
        <BLANKLINE>
        >>> my_avg = function('avg')
        >>> df.select(my_avg(col("a"))).show()
        ----------------
        |"AVG(""A"")"  |
        ----------------
        |2.500000      |
        ----------------
        <BLANKLINE>
    r}   )r   function)r  rQ   s     rV   r  r  )  s    < %%myIIrY   r  rz   c                     |r|t        | |      }t        t        | |j                         D ci c]  \  }}|t        j                  |       c}}|      ||      S c c}}w )N)r  ry   )r%   r6   r   itemsr  )r  rR  r  rz   rQ   r  r  s          rV   _call_named_arguments_functionr  5)  se     T\"40/5||~>tq!Q"">+	

   ?s    A owner)ru  rv  r  rw  rx  ry  rz  r6  r{  r|  r}  r  
execute_asr  r  r  r  r  rQ   r  r  zsnowflake.snowpark.Sessionr  )callerr  zrestricted callerc                   t        di | t        j                  j                  j	                  |
      }
|
t        |
      j                  }n|
j                  j                  }| c|j                  d      Rt        j                  |fi d|d|d|d|d|d|d	|d
|d|	d|d|d|d|d|d|d|d|d|d|d||S  || fi d|d|d|d|d|d|d	|d
|d|	d|d|d|d|d|d|d|d|d|d|d||S )a&  Registers a Python function as a Snowflake Python stored procedure and returns the stored procedure.

    It can be used as either a function call or a decorator. In most cases you work with a single session.
    This function uses that session to register the stored procedure. If you have multiple sessions, you need to
    explicitly specify the ``session`` parameter of this function. If you have a function and would
    like to register it to multiple databases, use ``session.sproc.register`` instead. See examples
    in :class:`~snowflake.snowpark.stored_procedure.StoredProcedureRegistration`.

    Note that the first parameter of your function should be a snowpark Session. Also, you need to add
    `snowflake-snowpark-python` package (version >= 0.4.0) to your session before trying to create a
    stored procedure.

    Args:
        func: A Python function used for creating the stored procedure.
        return_type: A :class:`~snowflake.snowpark.types.DataType` representing the return data
            type of the stored procedure. Optional if type hints are provided.
        input_types: A list of :class:`~snowflake.snowpark.types.DataType`
            representing the input data types of the stored procedure. Optional if
            type hints are provided.
        name: A string or list of strings that specify the name or fully-qualified
            object identifier (database name, schema name, and function name) for
            the stored procedure in Snowflake, which allows you to call this stored procedure in a SQL
            command or via :func:`session.call()`. If it is not provided, a name will
            be automatically generated for the stored procedure. A name must be specified when
            ``is_permanent`` is ``True``.
        is_permanent: Whether to create a permanent stored procedure. The default is ``False``.
            If it is ``True``, a valid ``stage_location`` must be provided.
        stage_location: The stage location where the Python file for the stored procedure
            and its dependencies should be uploaded. The stage location must be specified
            when ``is_permanent`` is ``True``, and it will be ignored when
            ``is_permanent`` is ``False``. It can be any stage other than temporary
            stages and external stages.
        imports: A list of imports that only apply to this stored procedure. You can use a string to
            represent a file path (similar to the ``path`` argument in
            :meth:`~snowflake.snowpark.Session.add_import`) in this list, or a tuple of two
            strings to represent a file path and an import path (similar to the ``import_path``
            argument in :meth:`~snowflake.snowpark.Session.add_import`). These stored-proc-level imports
            will override the session-level imports added by
            :meth:`~snowflake.snowpark.Session.add_import`.
        packages: A list of packages that only apply to this stored procedure. These stored-proc-level packages
            will override the session-level packages added by
            :meth:`~snowflake.snowpark.Session.add_packages` and
            :meth:`~snowflake.snowpark.Session.add_requirements`. To use Python packages that are not available in
            Snowflake, refer to :meth:`~snowflake.snowpark.Session.custom_package_usage_config`.
        replace: Whether to replace a stored procedure that already was registered. The default is ``False``.
            If it is ``False``, attempting to register a stored procedure with a name that already exists
            results in a ``SnowparkSQLException`` exception being thrown. If it is ``True``,
            an existing stored procedure with the same name is overwritten.
        if_not_exists: Whether to skip creation of a stored procedure the same procedure is already registered.
            The default is ``False``. ``if_not_exists`` and ``replace`` are mutually exclusive and a ``ValueError``
            is raised when both are set. If it is ``True`` and a stored procedure is already registered, the registration is skipped.
        session: Use this session to register the stored procedure. If it's not specified, the session that you created before calling this function will be used.
            You need to specify this parameter if you have created multiple sessions before calling this method.
        parallel: The number of threads to use for uploading stored procedure files with the
            `PUT <https://docs.snowflake.com/en/sql-reference/sql/put.html#put>`_
            command. The default value is 4 and supported values are from 1 to 99.
            Increasing the number of threads can improve performance when uploading
            large stored procedure files.
        execute_as: What permissions should the procedure have while executing. This
            supports caller, or owner for now. See `owner and caller rights <https://docs.snowflake.com/en/sql-reference/stored-procedures-rights.html>`_
            for more information.
        statement_params: Dictionary of statement level parameters to be set while executing this action.
        strict: Whether the created stored procedure is strict. A strict stored procedure will not invoke
            the stored procedure if any input is null. Instead, a null value will always be returned. Note
            that the stored procedure might still return null for non-null inputs.
        source_code_display: Display the source code of the stored procedure `func` as comments in the generated script.
            The source code is dynamically generated therefore it may not be identical to how the
            `func` is originally defined. The default is ``True``.
            If it is ``False``, source code will not be generated or displayed.
        external_access_integrations: The names of one or more external access integrations. Each
            integration you specify allows access to the external network locations and secrets
            the integration specifies.
        secrets: The key-value pairs of string types of secrets used to authenticate the external network location.
            The secrets can be accessed from handler code. The secrets specified as values must
            also be specified in the external access integration and the keys are strings used to
            retrieve the secrets using secret API.
        comment: Adds a comment for the created object. See
            `COMMENT <https://docs.snowflake.com/en/sql-reference/sql/comment>`_
        artifact_repository: The name of an artifact_repository that packages are found in. If unspecified, packages are
            pulled from Anaconda.
        resource_constraint: A dictionary containing a resource properties of a warehouse and then
            constraints needed to run this function. Eg ``{"architecture": "x86"}`` requires an x86
            warehouse be used for execution.

    Returns:
        A stored procedure function that can be called with python value.

    Note:
        1. When type hints are provided and are complete for a function,
        ``return_type`` and ``input_types`` are optional and will be ignored.
        See details of supported data types for stored procedure in
        :class:`~snowflake.snowpark.stored_procedure.StoredProcedureRegistration`.

            - You can use :attr:`~snowflake.snowpark.types.Variant` to
              annotate a variant, and use :attr:`~snowflake.snowpark.types.Geography`
              or :attr:`~snowflake.snowpark.types.Geometry` to annotate geospatial
              types when defining a stored procedure.

            - :class:`typing.Union` is not a valid type annotation for stored procedures,
              but :class:`typing.Optional` can be used to indicate the optional type.

        2. A temporary stored procedure (when ``is_permanent`` is ``False``) is scoped to this ``session``
        and all stored procedure related files will be uploaded to a temporary session stage
        (:func:`session.get_session_stage() <snowflake.snowpark.Session.get_session_stage>`).
        For a permanent stored procedure, these files will be uploaded to the stage that you provide.

        3. By default, stored procedure registration fails if a function with the same name is already
        registered. Invoking :func:`sproc` with ``replace`` set to ``True`` will overwrite the
        previously registered function.

        4. To describe the return type for a stored procedure that `returns tabular data
        <https://docs.snowflake.com/en/sql-reference/stored-procedures-python#returning-tabular-data>`_,
        use one of the following ways:

            - (Recommended) Describe the return type using :attr:`~snowflake.snowpark.types.StructType`
              and :attr:`~snowflake.snowpark.types.StructField`. Set ``return_type =
              StructType([StructField("a", DataTypeA()), ...])`` to describe the case
              ``RETURNS TABLE(A DataTypeA, ...)``.

            - Set ``return_type = StructType()`` to describe the case ``RETURNS TABLE()``.

            - When using type hints, the return type of function can be set as
              :class:`~snowflake.snowpark.dataframe.DataFrame`. This registers a
              table stored procedure with return type defined using ``RETURNS TABLE()``.
              Check **See also** below for more examples.

    See Also:
        :class:`~snowflake.snowpark.stored_procedure.StoredProcedureRegistration`

    Example::
        >>> from snowflake.snowpark.types import IntegerType
        >>> @sproc(return_type=IntegerType(), input_types=[IntegerType(), IntegerType()], packages=["snowflake-snowpark-python"])
        ... def add_sp(session_, x, y):
        ...     return session_.sql(f"SELECT {x} + {y}").collect()[0][0]
        ...
        >>> add_sp(1, 1)
        2
    r  r  ru  rv  r  rw  rx  ry  rz  r6  r{  r}  r  r  r  r  r  r  r  r  r  rQ   rT   )r,   r  r  r|  r  r<   r  sprocrX  r  r  )r  ru  rv  r  rw  rx  ry  rz  r6  r{  r|  r}  r  r  r  r  r  r  r  rQ   r  r  rR  sproc_registration_methods                           rV   r  r  K)  s-   N "6"  ((PPG $?%

( 	" %,MM$:$:!|

#<=E  %
#
 $
 	

 &
 *
 
 
 
 (
 
 .
 "
 
 !4
  *F!
" #
$ %
& !4'
( !4)
*  -
 	
2 )
#
 $
 	

 &
 *
 
 
 
 (
 
 .
 "
 
 !4
  *F!
" #
$ %
& !4'
( !4)
*  -
 	
rY   
model_nameversion_or_alias_namemethod_namec                    |rt        d| ||g|      }nd }t        | }|D cg c]  }t        j                  |       }}t        t	        | |||      ||      S c c}w )Nmodelry   )r%   r.   r6   r  r   )	r  r  r  rQ   rJ  rz   	args_listr  expressionss	            rV   _call_modelr  2*  s~     "j"7LtL
 -t4I3<=C6??3'=K=!		
 	 	 >s   Aservice_namec                    |rt        d| |g|      }nd }t        | }|D cg c]  }t        j                  |       }}t        t	        | ||      ||      S c c}w )Nservicery   )r%   r.   r6   r  r   )r  r  rQ   rJ  rz   r  r  r  s           rV   _call_servicer  N*  ss     "9|[.P4.PQ-t4I3<=C6??3'=K=	

   >s   Ac                       fdS )a  
    Creates a model function that can be used to call a model method.

    Args:
        model_name: The name of the model to call.
        version_or_alias_name: The version or alias name of the model to call.

    Example::

        >>> df = session.table("TESTSCHEMA_SNOWPARK_PYTHON.DIAMONDS_TEST")
        >>> model_instance = model("TESTSCHEMA_SNOWPARK_PYTHON.DIAMONDS_PRICE_PREDICTION", "v1")
        >>> result_df = df.select(model_instance("predict")(
        ...     col("CUT_OE"), col("COLOR_OE"), col("CLARITY_OE"), col("CARAT"),
        ...     col("DEPTH"), col("TABLE_PCT"), col("X"), col("Y"), col("Z")
        ... )["output_feature_0"])
        >>> result_df.count()
        5412
    c                       fdS )Nc                  &    t        g| diS NrQ   )r  )rJ  rQ   r  r  r  s    rV   r  z)model.<locals>.<lambda>.<locals>.<lambda>~*  s$    [);.9=.IR. rY   rT   )r  rQ   r  r  s   `rV   r  zmodel.<locals>.<lambda>~*  s
       rY   rT   )r  r  rQ   s   ```rV   r  r  f*  s    0 rY   c                       fdS )a  
    Creates a service function that can be used to call a service method.

    Args:
        service_name: The name of the service to call.

    Example::

        >>> service_instance = service("TESTSCHEMA_SNOWPARK_PYTHON.FORECAST_MODEL_SERVICE")
        >>> # Prepare a DataFrame with the ten expected features
        >>> df = session.create_dataframe(
        ...     [
        ...         (0.038076, 0.050680, 0.061696, 0.021872, -0.044223, -0.034821, -0.043401, -0.002592, 0.019907, -0.017646),
        ...     ],
        ...     schema=["age", "sex", "bmi", "bp", "s1", "s2", "s3", "s4", "s5", "s6"],
        ... )
        >>> # Invoke the model's predict method exposed by the service
        >>> result_df = df.select(
        ...     service_instance("predict")(col("age"), col("sex"), col("bmi"), col("bp"), col("s1"), col("s2"), col("s3"), col("s4"), col("s5"), col("s6"))["output_feature_0"]
        ... )
        >>> result_df.show()
        ------------------------------------------------------
        |"TESTSCHEMA_SNOWPARK_PYTHON.FORECAST_MODEL_SERV...  |
        ------------------------------------------------------
        |220.2223358154297                                   |
        ------------------------------------------------------
        <BLANKLINE>
    c                       fdS )Nc                  $    t        g| diS r  )r  )rJ  rQ   r  r  s    rV   r  z+service.<locals>.<lambda>.<locals>.<lambda>*  s!    ]k.$(.4=. rY   rT   )r  rQ   r  s   `rV   r  zservice.<locals>.<lambda>*  s
       rY   rT   )r  rQ   s   ``rV   r  r  *  s    B rY   c                 v    |rt        d|| |gn| g      nd}t        dt        | |d      d      }||_        |S )a  
    Converts a timestamp or a timestamp string to Unix time stamp (in seconds).

    Example::

        >>> import datetime
        >>> df = session.create_dataframe([["2013-05-08T23:39:20.123-07:00"]], schema=["ts_col"])
        >>> df.select(unix_timestamp(col("ts_col")).alias("unix_time")).show()
        ---------------
        |"UNIX_TIME"  |
        ---------------
        |1368056360   |
        ---------------
        <BLANKLINE>
    unix_timestampNepoch_secondFr}   )r%   r  rz  rz   )r   re  rQ   rn   r   s        rV   r  r  *  sW    2 	 	QHaS	

   Qu=C CHJrY   	start_posc                     |rt        d| ||g      nd}t        |       }t        |d      }t        d||t        |      ||      S )a  
    Searches for the first occurrence of the first argument in the second argument.
    If successful, returns the position (1-based) of the first argument in the second argument.
    Otherwise, return 0.

    Note::

        If the first argument is empty, this function always returns 1.

    Example::

        >>> df = session.create_dataframe([["find a needle in a haystack"],["nothing but hay in a haystack"]], schema=["expr"])
        >>> df.select(locate("needle", col("expr")).alias("1-pos")).show()
        -----------
        |"1-pos"  |
        -----------
        |8        |
        |0        |
        -----------
        <BLANKLINE>
    locateNr:  ry   )r%   rj   r9   r   )r7  r8  r  rQ   rn   _substr_strs          rV   r  r  *  sW    4 ENHueY&?@SW  %jG%*DWdC	N	 rY   yearsquartersmonthsweeksdayshoursminutessecondsmillisecondsmicrosecondsminssecsc                 (   d}|rTt        j                         }| |||||||||	|
||dj                         D ci c]
  \  }}||| }}}t        |dfi | |xs |}|xs |}t	        t        | |||||||||	|
      d      }||_        |S c c}}w )ug  
    Creates an interval column with the specified years, quarters, months, weeks, days, hours,
    minutes, seconds, milliseconds, microseconds, and nanoseconds. You can find more details in
    `Interval constants <https://docs.snowflake.com/en/sql-reference/data-types-datetime#interval-constants>`_.

    INTERVAL is not a data type (that is, you can’t define a table column to be of data type INTERVAL).
    Intervals can only be used in date, time, and timestamp arithmetic. For example,
    ``df.select(make_interval(days=0))`` is not valid.

    Example::

        >>> import datetime
        >>> from snowflake.snowpark.functions import to_date
        >>>
        >>> df = session.create_dataframe([datetime.datetime(2023, 8, 8, 1, 2, 3)], schema=["ts"])
        >>> df.select(to_date(col("ts") + make_interval(days=10)).alias("next_day")).show()
        --------------
        |"NEXT_DAY"  |
        --------------
        |2023-08-18  |
        --------------
        <BLANKLINE>

    You can also find some examples to use interval constants with :meth:`~snowflake.snowpark.Window.range_between`
    method.
    N)r  r  r  r  r  r  r  r  r  r  rV  r  r  r   Fr}   )ro   rp   r  r    r6   r   rz   )r  r  r  r  r  r  r  r  r  r  rV  r  r  rQ   rn   r  r  rR  rY  s                      rV   r   r   +  s    V Cjjl $ "" , ,* eg!
1 }! qD
 
& 	sO>v> oGoG 	
 C" CHJY
s   Bz1.38.0zType YearMonthIntervalType is currently in private preview and needs to be enabled by setting parameter `FEATURE_INTERVAL_TYPES` to `ENABLED`)versionextra_doc_string_alias_column_namec           
         d}|rJg }|j                  | | n
t        d             |j                  ||n
t        d             t        d|      }| t        d      nt        | d      }|t        d      nt        |d      }|t        d      z  |z   }t	        t	        t        t        |      t        d      z        d      d      }	t	        t	        t        t        |      t        d      z        d      d      }
t        |t        d      k  t        d      t        d            }t        ||	t        d      |
      }t	        |d	      }|r)d
 }d ||       d ||       d}|j                  |      }||_
        |S )a  
    Creates a year-month interval expression using with specified years and months.

    This YearMonthInterval is not to be confused with the interval created by make_interval.
    You can define a table column to be of data type YearMonthIntervalType.

    Args:
        years: The number of years, positive or negative
        months: The number of months, positive or negative
        _alias_column_name: If true, alias the column name to a cleaner value

    Returns:
        A Column representing a year-month interval

    Example::

        >>> from snowflake.snowpark.functions import interval_year_month_from_parts
        >>>
        >>> _ = session.sql("ALTER SESSION SET FEATURE_INTERVAL_TYPES=ENABLED;").collect()
        >>> df = session.create_dataframe([[1, 2]], ["years", "months"])
        >>> df.select(interval_year_month_from_parts(col("years"), col("months")).alias("interval")).show()
        --------------
        |"INTERVAL"  |
        --------------
        |+1-02       |
        --------------
        <BLANKLINE>

    Nr   interval_year_month_from_parts   rG  r  -r-  zINTERVAL YEAR TO MONTHc                     t        | j                  t              rt        | j                  j                        S | j
                  j                  S rN  )r   _expr1r   r  r'  r   r  rM  s    rV   get_col_namez4interval_year_month_from_parts.<locals>.get_col_name+  s5    #**g.3::++,,+++rY   zinterval_year_month_from_parts(, rP  )r  rj   r%   r9   rI  r  rw  r   rC  aliasrz   )r  r  r  rQ   rn   rJ  	years_col
months_coltotal_monthsnormalized_yearsnormalized_monthssign_prefixinterval_stringrY  r  
alias_names                   rV   r  r  b+  s   P CU.ECF;f0Fc!f=!"BDI = 	AE#CD  > 	AF$DE  s2w&3LDs<'83r7'B!CUKUST%L(9CG(C"DeLeTs1vCBK
 [*:CHFWXO
 8
9C	, 7|I7N6OrR^_iRjQkklm
ii
#CHJrY   zType DayTimeIntervalType is currently in private preview and needs to be enabled by setting parameter `FEATURE_INTERVAL_TYPES` to `ENABLED`.c                    d}|rg }|j                  | | n
t        d             |j                  ||n
t        d             |j                  ||n
t        d             |j                  ||n
t        d             t        d|      }| t        d      nt        | d      }|t        d      nt        |d      }	|t        d      nt        |d      }
|t        d      nt        |d      }|t        d      z  |	t        d      z  z   |
t        d      z  z   |z   }|t        d      k  }t	        |      }t        t        |t        d      z        d      }|t        d      z  }t        t        |t        d      z        d      }|t        d      z  }t        t        |t        d      z        d      }|t        d      z  }t        |t        d      k  t        t        d	      t        |d
            t        |d
            }t        |t        d      k  t        t        d	      t        |d
            t        |d
            }t        t        |      d      }t        |t        d      k  t        t        d	      t        |d
            t        |d
            }t	        |t        |d      z
        dkD  }|t        |d      z
  }t        |t        t        d      t        t        t        |t        d      z  d      d
      dt        d	                  t        d            }t        ||      }t        |t        d      t        d            }t        |t        |d
      t        d      |t        d      |t        d      |      }t        |d      }|r;d } d | |       d | |	       d | |
       d | |       d	}!|j                  |!      }||_        |S )a  
    Creates a day-time interval expression using with specified days, hours, mins and seconds.

    This DayTime is not to be confused with the interval created by make_interval.
    You can define a table column to be of data type DayTimeIntervalType.

    Args:
        days: The number of days, positive or negative
        hours: The number of hours, positive or negative
        mins: The number of minutes, positive or negative
        secs: The number of seconds, positive or negative
        _alias_column_name: If true, alias the column name to a cleaner value

    Returns:
        A Column representing a day-time interval

    Example::

        >>> from snowflake.snowpark.functions import interval_day_time_from_parts
        >>>
        >>> _ = session.sql("ALTER SESSION SET FEATURE_INTERVAL_TYPES=ENABLED;").collect()
        >>> df = session.create_dataframe([[1, 12, 30, 01.001001]], ['day', 'hour', 'min', 'sec'])
        >>> df.select(interval_day_time_from_parts(col("day"), col("hour"), col("min"), col("sec")).alias("interval")).show()
        --------------------------
        |"INTERVAL"              |
        --------------------------
        |1 day, 12:30:01.001001  |
        --------------------------
        <BLANKLINE>

    Nr   interval_day_time_from_partsiQ i  <   rG  r  0r  decimalgV瞯<.i@B rL  r-  r   :zINTERVAL DAY TO SECONDc                     t        | j                  t              rt        | j                  j                        S t        | j                        S rN  )r   r  r   r  r'  rM  s    rV   r  z2interval_day_time_from_parts.<locals>.get_col_nameH,  s3    #**g.3::++,,3::&rY   zinterval_day_time_from_parts(r  rP  )r  rj   r%   r9   rw  rI  r  r   rC  r  r  r  rz   )"r  r  r  r  r  rQ   rn   rJ  days_col	hours_colmins_colsecs_coltotal_secondsis_negativeabs_total_seconds	days_partremaining_after_days
hours_partremaining_after_hours	mins_part	secs_part	hours_strmins_strsecs_intsecs_strhas_fractionfractional_partfraction_strsecs_formattedr  interval_valuerY  r  r  s"                                     rV   r  r  +  s   Z C D,D#a&9U.ECF;D,D#a&9D,D#a&9!"@$G ,AN49W$X 
 = 	AE#AB  ,AN49W$X  ,AN49W$X 
 	3u:	CI 553r78JJXU   #a&(KM*U,s5z9:EBI,s5z9e03t9<=uEJ03t9<U03r7:;UCI%B/ISWs3xj%01ZI CGs3xi/0YH E)$e,H3r7s3xh./XuH y4)#<<=EL$x";;OHU?S\91=uEC	
 	BL Hl3Nk3s8SW5KYCCC	N ~7
8C	' 5\(5K4LB|\eOfNggijvw  kA  jB  BD  EQ  RZ  E[  D\  \]  ^
ii
#CHJrY   z1.28.0z^Please consider installing snowflake-ml-python and using `snowflake.cortex.summarize` instead.z/Use :meth:`snowflake.cortex.summarize` instead.)r  extra_warning_textr  c                 ^    |rt        d| g      nd}d}t        | |      }t        ||||      S )z
    Summarizes the given English-language input text.
    Args:
        text: A string containing the English text from which a summary should be generated.
    Returns:
        A string containing a summary of the original text.
    snowflake_cortex_summarizeNzsnowflake.cortex.summarizery   r%   r7   r   r  rQ   rn   r#  text_cols        rV   r  r  V,  sB    " FO84&ATX  1MdM2H-yQQrY   z^Please consider installing snowflake-ml-python and using `snowflake.cortex.sentiment` instead.z/Use :meth:`snowflake.cortex.sentiment` instead.c                 ^    |rt        d| g      nd}d}t        | |      }t        ||||      S )a}  
    A string containing the text for which a sentiment score should be calculated.
    Args:
        text: A string containing the English text from which a summary should be generated.
    Returns:
        A floating-point number from -1 to 1 (inclusive) indicating the level of negative or positive sentiment in the
        text. Values around 0 indicate neutral sentiment.
    snowflake_cortex_sentimentNzsnowflake.cortex.sentimentry   r   r!  s        rV   r$  r$  o,  sB    $ FO84&ATX  1MdM2H-yQQrY   c                 6    t        | d      }t        d||      S )a   
    Returns the inverse(arc) hyperbolic cosine of the input value.

    Example::

        >>> df = session.create_dataframe([2.352409615], schema=["a"])
        >>> df.select(acosh("a").as_("acosh")).collect()
        [Row(ACOSH=1.4999999998857607)]
    acoshr}   r   r   s      rV   r&  r&  ,  r  rY   c                 6    t        | d      }t        d||      S )a  
    Returns the inverse(arc) hyperbolic sine of the input value.

    Example::

        >>> df = session.create_dataframe([2.129279455], schema=["a"])
        >>> df.select(asinh(df["a"]).alias("asinh")).collect()
        [Row(ASINH=1.4999999999596934)]
    asinhr}   r   r   s      rV   r(  r(  ,  r  rY   c                 6    t        | d      }t        d||      S )a
  
    Returns the inverse(arc) hyperbolic tangent of the input value.

    Example::

        >>> df = session.create_dataframe([0.9051482536], schema=["a"])
        >>> df.select(atanh(df["a"]).alias("result")).collect()
        [Row(RESULT=1.4999999997517164)]
    atanhr}   r   r   s      rV   r*  r*  ,  r  rY   c                 6    t        | d      }t        d||      S )u  
    Returns the length of a string or binary value in bits.

    Example::

        >>> df = session.create_dataframe([['abc'], ['Δ']], schema=["v"])
        >>> df = df.withColumn("b", lit("A1B2").cast("binary"))
        >>> df.select(bit_length(col("v")).alias("BIT_LENGTH_V"), bit_length(col("b")).alias("BIT_LENGTH_B")).collect()
        [Row(BIT_LENGTH_V=24, BIT_LENGTH_B=16), Row(BIT_LENGTH_V=16, BIT_LENGTH_B=16)]
    
bit_lengthr}   r   r   s      rV   r,  r,  ,  s     	q,'A,Y??rY   numeric_exprc                 6    t        | d      }t        d||      S )a  
    Returns the position of the first set bit (i.e., the first '1' bit) in the binary representation of the input number.

    Example::

        >>> df = session.create_dataframe([1, 2, 3, 32768, 32769], schema=["a"])
        >>> df.select(bitmap_bit_position("a").alias("bit_position")).collect()
        [Row(BIT_POSITION=0), Row(BIT_POSITION=1), Row(BIT_POSITION=2), Row(BIT_POSITION=32767), Row(BIT_POSITION=0)]
    bitmap_bit_positionr}   r   )r-  rQ   r   s      rV   r/  r/  ,  s!     	|%:;A/iHHrY   c                 6    t        | d      }t        d||      S )a  
    Returns the bucket number of the input value in a bitmap index.

    The bucket number is a value between 1 and the number of buckets in the bitmap index.

    Example::

        >>> df = session.create_dataframe([1, 2, 3, 32768, 32769], schema=["a"])
        >>> df.select(bitmap_bucket_number(col("a")).alias("bucket_number")).collect()
        [Row(BUCKET_NUMBER=1), Row(BUCKET_NUMBER=1), Row(BUCKET_NUMBER=1), Row(BUCKET_NUMBER=1), Row(BUCKET_NUMBER=2)]
    bitmap_bucket_numberr}   r   r   s      rV   r1  r1  ,  s!     	q01A0!yIIrY   relative_positionc                 6    t        | d      }t        d||      S )aF  
    Returns a bitmap constructed from the relative positions of the input values.

    Example::

        >>> df = session.create_dataframe([1, 32769], schema=["a"])
        >>> df.select(bitmap_bucket_number(df["a"]).alias("bitmap_id"),bitmap_bit_position(df["a"]).alias("bit_position")).group_by("bitmap_id").agg(bitmap_construct_agg(col("bit_position")).alias("bitmap")).order_by("bitmap_id").collect()
        [Row(BITMAP_ID=1, BITMAP=bytearray(b'\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00')), Row(BITMAP_ID=2, BITMAP=bytearray(b'\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00'))]
    bitmap_construct_aggr}   r   )r2  rQ   r   s      rV   r4  r4  ,  s"     	(*@AA0!yIIrY   c                 6    t        | d      }t        d||      S )a8  
    Returns the cube root of value in a column.

    Example::

        >>> df = session.create_dataframe([0, 2, -10, None], schema=["x"])
        >>> df.select(cbrt("x").alias("cbrt_x")).collect()
        [Row(CBRT_X=0.0), Row(CBRT_X=1.2599210498948734), Row(CBRT_X=-2.1544346900318834), Row(CBRT_X=None)]
    cbrtr}   r   r   s      rV   r6  r6  ,  r  rY   e1e2c                 P    t        | d      }t        |d      }t        d|||      S )a2  
    Compares whether two expressions are equal. The function is NULL-safe, meaning it treats NULLs as
    known values for comparing equality. Note that this is different from the EQUAL comparison operator (=),
    which treats NULLs as unknown values.

    Example::

        >>> df = session.create_dataframe([[1, 1], [1, None], [None, 2], [None, None]], schema=["a", "b"])
        >>> df.select(equal_null(df["a"], df["b"]).alias("equal_null")).collect()
        [Row(EQUAL_NULL=True), Row(EQUAL_NULL=False), Row(EQUAL_NULL=False), Row(EQUAL_NULL=True)]
    
equal_nullr}   r   r7  r8  rQ   r   r   s        rV   r:  r:  -  s-     
L	)B	L	)B,B)DDrY   c                 P    t        | d      }t        |d      }t        d|||      S )ab  
    If expr1 is NULL, returns expr2, otherwise returns expr1.

    Example::

        >>> df = session.create_dataframe([("a", "b"), ("c", None), (None, "d"), (None, None)], schema=["e1", "e2"])
        >>> df.select(ifnull(df["e1"], df["e2"]).alias("result")).collect()
        [Row(RESULT='a'), Row(RESULT='c'), Row(RESULT='d'), Row(RESULT=None)]
    ifnullr}   r   r;  s        rV   r=  r=  -  s-     
H	%B	H	%B(Bi@@rY   fract_sec_precisionc                 X    |rt        d| g      nd}t        dt        | d      ||      S )a  
    Returns the current timestamp at the start of the query with the specified fractional second precision.

    Example::

        >>> df = session.create_dataframe([1], schema=["a"])
        >>> df.select(localtimestamp(3)).collect()  # doctest: +SKIP
    localtimestampNFr}   ry   )r%   r   rj   )r>  rQ   rn   s      rV   r@  r@  +-  sC      	,/B.CD 
 51	 rY   col_to_returncol_containing_maximum"maximum_number_of_values_to_returnc           	          t        | d      }t        |d      }|/|rt        d|||g      nd}t        d||t        |d      ||      S t        d|||      S )a|  
    Finds the row(s) containing the maximum value for a column and returns the value of another column in that row.

    Example::

        >>> df = session.create_dataframe([
        ...     [1001, 10, 10000],
        ...     [1020, 10, 9000],
        ...     [1030, 10, 8000],
        ...     [900, 20, 15000],
        ...     [2000, 20, None],
        ...     [2010, 20, 15000],
        ...     [2020, 20, 8000]
        ... ], schema=["employee_id", "department_id", "salary"])
        >>> df.select(max_by("employee_id", "salary", 3)).collect()
        [Row(MAX_BY("EMPLOYEE_ID", "SALARY", 3)='[\n  2010,\n  900,\n  1001\n]')]
    max_byNFr}   ry   r  )rA  rB  rC  rQ   r   r   rn   s          rV   rE  rE  B-  s    0 
x	0B	.	9B)5   2r3U*VW 	
 2eD
 	
 hB)DDrY   col_containing_minimumc           	          t        | d      }t        |d      }|/|rt        d|||g      nd}t        d||t        |d      ||      S t        d|||      S )ar  
    Finds the row(s) containing the minimum value for a column and returns the value of another column in that row.

    Example::

        >>> df = session.create_dataframe([
        ...     [1001, 10, 10000],
        ...     [1020, 10, 9000],
        ...     [1030, 10, 8000],
        ...     [900, 20, 15000],
        ...     [2000, 20, None],
        ...     [2010, 20, 15000],
        ...     [2020, 20, 8000]
        ... ], schema=["employee_id", "department_id", "salary"])
        >>> df.select(min_by("employee_id", "salary", 3).alias("min_by")).collect()
        [Row(MIN_BY='[\n  2020,\n  1030,\n  1020\n]')]

    min_byNFr}   ry   r  )rA  rF  rC  rQ   r   r   rn   s          rV   rH  rH  n-  s    2 
x	0B	.	9B)5   2r3U*VW 	
 2eD
 	
 hB)DDrY   c                 6    t        | d      }t        d||      S )u  
    Returns the length of a string or binary value in bytes.
    This will be the same as LENGTH for ASCII strings and greater than LENGTH for strings using Unicode code points.
    For binary, this is always the same as LENGTH.

    Example::

        >>> df = session.create_dataframe(['abc', 'Β', "X'A1B2'"], schema=["a"])
        >>> df.select(octet_length(col("a")).alias("octet_length")).collect()
        [Row(OCTET_LENGTH=3), Row(OCTET_LENGTH=2), Row(OCTET_LENGTH=7)]
    octet_lengthr}   r   r   s      rV   rJ  rJ  -  s     	q.)A.!yAArY   c           	          |rt        d| ||g      nd}t        | d      }t        |d      }t        d||t        |d      ||      S )a  
    Searches for the first occurrence of the first argument in the second argument and, if successful, returns
    the position (1-based) of the first argument in the second argument.

    Example::

        >>> df = session.create_dataframe([['an', 'banana'], ['nan', 'banana']], schema=["expr1", "expr2"])
        >>> df.select(position(df["expr1"], df["expr2"], 3).alias("position")).collect()
        [Row(POSITION=4), Row(POSITION=3)]
    r  NFr}   ry   rd  )r7  r8  r  rQ   rn   r   r   s          rV   r  r  -  sb    &  	Jy(AB 
 
z	*B	z	*B

I' rY   c                 P    t        | d      }t        |d      }t        d|||      S )a  
    Returns the average of the independent variable for non-null pairs in a group, where x is the
    independent variable and y is the dependent variable.

    Example::

        >>> df = session.create_dataframe([[10, 11], [20, 22], [25, None], [30, 35]], schema=["v", "v2"])
        >>> df.groupBy("v").agg(regr_avgx(df["v"], df["v2"]).alias("regr_avgx")).sort("v").collect()
        [Row(V=10, REGR_AVGX=11.0), Row(V=20, REGR_AVGX=22.0), Row(V=25, REGR_AVGX=None), Row(V=30, REGR_AVGX=35.0)]
    	regr_avgxr}   r   r  r  rQ   r   r   s        rV   rM  rM  -  s-     
;	'B	;	'B+r2CCrY   c                 P    t        | d      } t        |d      }t        d| ||      S )a  
    Returns the average of the dependent variable for non-null pairs in a group, where x is the
    independent variable and y is the dependent variable.

    Example::

        >>> df = session.create_dataframe([[10, 11], [20, 22], [25, None], [30, 35]], schema=["v", "v2"])
        >>> df = df.group_by("v").agg(regr_avgy(df["v"], df["v2"]).alias("regr_avgy")).sort("v")
        >>> df.collect()
        [Row(V=10, REGR_AVGY=10.0), Row(V=20, REGR_AVGY=20.0), Row(V=25, REGR_AVGY=None), Row(V=30, REGR_AVGY=30.0)]
    	regr_avgyr}   r   r  r  rQ   s      rV   rP  rP  -  s-     	q+&Aq+&A+q!yAArY   c                 P    t        | d      }t        |d      }t        d|||      S )ao  
    Returns the number of non-null number pairs in a group.

    Example::

        >>> df = session.create_dataframe([[1, 10, 11], [1, 20, 22], [1, 25, None], [2, 30, 35]], schema=["k", "v", "v2"])
        >>> df.group_by("k").agg(regr_count(col("v"), col("v2")).alias("regr_count")).sort("k").collect()
        [Row(K=1, REGR_COUNT=2), Row(K=2, REGR_COUNT=1)]
    
regr_countr}   r   rN  s        rV   rS  rS  -  s-     
<	(B	<	(B,B)DDrY   c                 P    t        | d      }t        |d      }t        d|||      S )a  
    Returns the intercept of the univariate linear regression line for non-null pairs in a group.
    It is computed for non-null pairs using the following formula: AVG(y)-REGR_SLOPE(y,x)*AVG(x), where x is
    the independent variable and y is the dependent variable.

    Example::

        >>> df = session.create_dataframe([[10, 11], [20, 22], [30, 35]], schema=["v", "v2"])
        >>> df.groupBy().agg(regr_intercept(df["v"], df["v2"]).alias("regr_intercept")).collect()
        [Row(REGR_INTERCEPT=1.1547344110854496)]
    regr_interceptr}   r   rN  s        rV   rU  rU  .  s0     
+	,B	+	,B*BiHHrY   c                 P    t        | d      } t        |d      }t        d| ||      S )a  
    Returns the coefficient of determination for non-null pairs in a group.
    It is computed for non-null pairs using the following formula: NULL if VAR_POP(x) = 0, else
    1 if VAR_POP(y) = 0 and VAR_POP(x) <> 0, else POWER(CORR(y,x), 2).
    Where x is the independent variable and y is the dependent variable.

    Example::

        >>> df = session.create_dataframe([[10, 11], [20, 22], [25, None], [30, 35]], schema=["v", "v2"])
        >>> df.groupBy("v").agg(regr_r2(col("v"), col("v2")).alias("regr_r2")).collect()
        [Row(V=10, REGR_R2=None), Row(V=20, REGR_R2=None), Row(V=25, REGR_R2=None), Row(V=30, REGR_R2=None)]
    regr_r2r}   r   rQ  s      rV   rW  rW  .  s-     	q)$Aq)$A)QY??rY   c                 P    t        | d      }t        |d      }t        d|||      S )af  
    Returns the slope of the linear regression line for non-null pairs in a group.
    It is computed for non-null pairs using the following formula: COVAR_POP(x,y) / VAR_POP(x), where x is the
    independent variable and y is the dependent variable.

    Example::

        >>> df = session.create_dataframe([[10, 11], [20, 22], [25, None], [30, 35]], schema=["v", "v2"])
        >>> df = df.group_by("v").agg(regr_slope(df["v2"], df["v"]).alias("regr_slope"))
        >>> df.collect()
        [Row(V=10, REGR_SLOPE=None), Row(V=20, REGR_SLOPE=None), Row(V=25, REGR_SLOPE=None), Row(V=30, REGR_SLOPE=None)]
    
regr_sloper}   r   rN  s        rV   rY  rY  &.  s-     
<	(B	<	(B,B)DDrY   c                 P    t        | d      }t        |d      }t        d|||      S )a  
    Returns REGR_COUNT(y, x) * VAR_POP(x) for non-null pairs.

    Example::

        >>> df = session.create_dataframe([[10, 11], [20, 22], [25, None], [30, 35]], schema=["v", "v2"])
        >>> df.group_by("v").agg(regr_sxx(col("v"), col("v2")).alias("regr_sxx")).sort("v").collect()
        [Row(V=10, REGR_SXX=0.0), Row(V=20, REGR_SXX=0.0), Row(V=25, REGR_SXX=None), Row(V=30, REGR_SXX=0.0)]
    regr_sxxr}   r   r  s        rV   r[  r[  9.  s-     1j)E1j)E*eUiHHrY   c                 P    t        | d      }t        |d      }t        d|||      S )a  
    Returns REGR_COUNT(expr1, expr2) * COVAR_POP(expr1, expr2) for non-null pairs.

    Example::

        >>> df = session.create_dataframe([[10, 11], [20, 22], [25, None], [30, 35]], schema=["v", "v2"])
        >>> df = df.filter(df["v2"].is_not_null())
        >>> df.group_by("v").agg(regr_sxy(df["v"], df["v2"]).alias("regr_sxy")).collect()
        [Row(V=10, REGR_SXY=0.0), Row(V=20, REGR_SXY=0.0), Row(V=30, REGR_SXY=0.0)]
    regr_sxyr}   r   r  s        rV   r]  r]  I.  s-     1j)E1j)E*eUiHHrY   c                 P    t        | d      }t        |d      }t        d|||      S )a  
    Returns REGR_COUNT(y, x) * VAR_POP(y) for non-null pairs.

    Example::

        >>> df = session.create_dataframe([[10, 11], [20, 22], [25, None], [30, 35]], schema=["v", "v2"])
        >>> df.groupBy("v").agg(regr_syy(df["v"], df["v2"]).alias("regr_syy")).collect()
        [Row(V=10, REGR_SYY=0.0), Row(V=20, REGR_SYY=0.0), Row(V=25, REGR_SYY=None), Row(V=30, REGR_SYY=0.0)]
    regr_syyr}   r   rN  s        rV   r_  r_  Z.  s-     
:	&B	:	&B*b"	BBrY   c                 X    t        | d      }|rt        d|||      S t        d||      S )a(  
    A special version of TO_BINARY that performs the same operation (i.e. converts an input expression to
    a binary value), but with error handling support (i.e. if the conversion cannot be performed,
    it returns a NULL value instead of raising an error).

    Example::

        >>> df = session.create_dataframe(["01", "A B", "Hello", None], schema=["hex_encoded_string"])
        >>> df.select(try_to_binary(df["hex_encoded_string"], 'HEX').alias("b")).collect()
        [Row(B=bytearray(b'\x01')), Row(B=None), Row(B=None), Row(B=None)]
    try_to_binaryr}   r   rx  s       rV   ra  ra  j.  s=     	q/*A  	3)D OQ)DrY   max_line_lengthalphabetc                     |rt        d| |g|g n|gz         nd}t        | d      }|g}|r|j                  t        |             |r|j                  t        |             t	        dg|||dS )a3  
    Encodes the input (string or binary) using Base64 encoding.

    Example:
        >>> df = session.create_dataframe(["Snowflake", "Data"], schema=["input"])
        >>> df.select(base64_encode(col("input")).alias("encoded")).collect()
        [Row(ENCODED='U25vd2ZsYWtl'), Row(ENCODED='RGF0YQ==')]
    base64_encodeNry   r%   r9   r  rj   r   )r   rb  rc  rQ   rn   	col_inputrJ  s          rV   re  re  .  s    * 	 	 (*:B
K	

   q/2I ;DC()CM" /PDPsiPPrY   c                     |rt        d|| gn| |g      nd}t        | d      }|g}|r|j                  t        |             t	        dg|||dS )a,  
    Decodes a Base64-encoded string to a string.

    Example:
        >>> df = session.create_dataframe(["U25vd2ZsYWtl", "SEVMTE8="], schema=["input"])
        >>> df.select(base64_decode_string(col("input")).alias("decoded")).collect()
        [Row(DECODED='Snowflake'), Row(DECODED='HELLO')]
    base64_decode_stringNry   rf  )r   rc  rQ   rn   rg  rJ  s         rV   ri  ri  .  sr    "  	"8+;QC!X	
   q"89I ;DCM" 0W4WcYWWrY   casec                 p    |rt        d| |g      nd}t        | d      }t        d|t        |      ||      S )uX  
    Encodes the input using hexadecimal (also ‘hex’ or ‘base16’) encoding.

    Example:
        >>> df = session.create_dataframe(["Snowflake", "Hello"], schema=["input"])
        >>> df.select(hex_encode(col("input")).alias("hex_encoded")).collect()
        [Row(HEX_ENCODED='536E6F77666C616B65'), Row(HEX_ENCODED='48656C6C6F')]
    
hex_encodeNry   rd  )r   rj  rQ   rn   rg  s        rV   rl  rl  .  sB     ;D
lQI
6Cq,/IiT	 rY   max_distancec                    |rt        d|| |gn| ||g      nd}t        | d      }t        |d      }||g}|:t        |t              rt	        |d      nt        |d      }|j                  |       t        dg|||dS )a  Computes the Levenshtein distance between two input strings.

    Optionally, a maximum distance can be specified. If the distance exceeds this value,
    the computation halts and returns the maximum distance.

    Example::

        >>> df = session.create_dataframe(
        ...     [["abc", "def"], ["abcdef", "abc"], ["snow", "flake"]],
        ...     schema=["s1", "s2"]
        ... )
        >>> df.select(
        ...     editdistance(col("s1"), col("s2")).alias("distance"),
        ...     editdistance(col("s1"), col("s2"), 2).alias("max_2_distance")
        ... ).collect()
        [Row(DISTANCE=3, MAX_2_DISTANCE=2), Row(DISTANCE=3, MAX_2_DISTANCE=2), Row(DISTANCE=5, MAX_2_DISTANCE=2)]
    editdistanceNFr}   ry   )r%   r9   r   rG  rj   r  r   )	r7  r8  rm  rQ   rn   s1s2rJ  max_dists	            rV   ro  ro  .  s    : 	 	$,RH2r<2H	

   
N	+B	N	+B8D ,, .n= 	
 	H.O4OcYOOrY   substrc                     t        | d      }t        t        |d      |d      }|rt        d| |g      |_        |S d|_        |S )au  
    Locate the position of the first occurrence of substr column in the given string. Returns null if either of the arguments are null.

    Example::
        >>> df = session.create_dataframe([["hello world"], ["world hello"]], schema=["text"])
        >>> df.select(instr(col("text"), "world").alias("position")).collect()
        [Row(POSITION=7), Row(POSITION=1)]
    instrFr}   N)r9   r  rj   r%   rz   )r  rs  rQ   rp  r   s        rV   ru  ru  /  sO     
W	%B
3v/u
EC>G"7S&M:CHJ NRCHJrY   r   r   c                 <   |rt        d| ||g      nd}t        | t        t        f      rt	        | d      n| } t        |t        t        f      rt	        |d      n|}t        |t        t        f      rt	        |d      nt        |d      }t        d| ||||      S )a~  
    Generates a normally-distributed pseudo-random floating point number with specified mean and stddev (standard deviation).

    Example::
        >>> df = session.create_dataframe([1,2,3], schema=["a"])
        >>> df.select(normal(0, 1, "a").alias("normal")).collect()
        [Row(NORMAL=-1.143416214223267), Row(NORMAL=-0.78469958830255), Row(NORMAL=-0.365971322006404)]
    normalNFr}   ry   rN  )r   r   rC  rQ   rn   s        rV   rw  rw  !/  s    & AJ
hvs(;
<tC)3D3,)G3tu%TD(26C<(HFe$f 
 cC<( 	C5!C* 
 (D&#C9UUrY   c                     |rt        d| g n| g      nd}| t        d      } t        t        dd      t        dd      | d      }||_        |S )a  
    Generates a column with independent and identically distributed (i.i.d.) samples from the standard normal distribution.

    Example::
        >>> df = session.create_dataframe([1,2,3], schema=["seed"])
        >>> df.select(randn("seed").alias("randn")).collect()
        [Row(RANDN=-1.143416214223267), Row(RANDN=-0.78469958830255), Row(RANDN=-0.365971322006404)]
        >>> df.select(randn().alias("randn")).collect()  # doctest: +SKIP
    randnNFr}   r   r   )r%   r?  rw  rj   rz   )r=  rQ   rn   r   s       rV   ry  ry  A/  sf      	G4<RdVD 
 |&
AA	C CHJrY   c                     t         j                  j                  j                         }t	        | d      }|j                  d      }|rt        d|t        |d      g      nd} ||t        |      d      }||_        |S )ah  
    Extracts values from an XML column using an XPath expression.

    Returns an array of strings containing all matches in document order.
    Returns an empty array if no matches are found.

    Args:
        col: Column containing XML data (string or parsed XML)
        path: XPath expression string

    Example::

        >>> df = session.create_dataframe([['<root><a>1</a><a>2</a></root>']], schema=['xml'])
        >>> result = df.select(xpath('xml', '//a/text()').alias('result')).collect()
        >>> json.loads(result[0].RESULT)
        ['1', '2']

        >>> # With attributes
        >>> df2 = session.create_dataframe([['<root><item id="1">A</item><item id="2">B</item></root>']], schema=['xml'])
        >>> result = df2.select(xpath('xml', '//item[@id="2"]/text()').alias('result')).collect()
        >>> json.loads(result[0].RESULT)
        ['B']
    xpathr%  Fr}   N	r  r  r|  _get_active_sessionr9   _get_or_register_xpath_udfr%   rj   rz   rW   r!  rQ   r|  xml_col	xpath_udfrn   r   s           rV   r{  r{  _/  s    2   ((<<>GS'*G227;I  	Ggs45/I%JK 
 GSY%
8CCHJrY   c                     t         j                  j                  j                         }t	        | d      }|j                  d      }|rt        d|t        |d      g      nd} ||t        |      d      }||_        |S )a  
    Extracts the first value from an XML column using an XPath expression as a string.

    Returns NULL if no matches are found.

    Args:
        col: Column containing XML data
        path: XPath expression string

    Example::

        >>> df = session.create_dataframe([['<root><a>1</a><a>2</a></root>']], schema=['xml'])
        >>> df.select(xpath_string('xml', '//a/text()').alias('result')).collect()
        [Row(RESULT='1')]
    xpath_stringr`  Fr}   Nr|  r  s           rV   r  r  /  s    "   ((<<>GS.1G228<I  	NWc$%6P,QR 
 GSY%
8CCHJrY   c                     t         j                  j                  j                         }t	        | d      }|j                  d      }|rt        d|t        |d      g      nd} ||t        |      d      }||_        |S )a  
    Evaluates an XPath expression and returns the result as a boolean.

    Returns FALSE if no matches are found. Follows XPath boolean coercion rules.

    Args:
        col: Column containing XML data
        path: XPath expression string

    Example::

        >>> df = session.create_dataframe([['<root><a>1</a></root>']], schema=['xml'])
        >>> df.select(xpath_boolean('xml', 'count(//a) > 0').alias('has_a')).collect()
        [Row(HAS_A=True)]
    xpath_booleanbooleanFr}   Nr|  r  s           rV   r  r  /  s    "   ((<<>GS/2G229=I  	Ogs457Q-RS 
 GSY%
8CCHJrY   c                     t         j                  j                  j                         }t	        | d      }|j                  d      }|rt        d|t        |d      g      nd} ||t        |      d      }||_        |S )a  
    Extracts a numeric value from an XML column using an XPath expression.

    Returns NULL if no matches are found or value cannot be converted to float.

    Args:
        col: Column containing XML data
        path: XPath expression string

    Example::

        >>> df = session.create_dataframe([['<root><price>19.99</price></root>']], schema=['xml'])
        >>> df.select(xpath_number('xml', '//price/text()').alias('price')).collect()
        [Row(PRICE=19.99)]
    xpath_numberrH  Fr}   Nr|  r  s           rV   r  r  /  s    "   ((<<>GS.1G227;I  	NWc$%6P,QR 
 GSY%
8CCHJrY   c                     t         j                  j                  j                         }t	        | d      }|j                  d      }|rt        d|t        |d      g      nd} ||t        |      d      }||_        |S )a  
    Extracts an integer value from an XML column using an XPath expression.

    Returns NULL if no matches are found or value cannot be converted to integer.
    Floats are truncated to integers (e.g., 1.9 becomes 1).

    Args:
        col: Column containing XML data
        path: XPath expression string

    Example::

        >>> df = session.create_dataframe([['<root><count>42</count></root>']], schema=['xml'])
        >>> df.select(xpath_int('xml', '//count/text()').alias('count')).collect()
        [Row(COUNT=42)]
    	xpath_intrG  Fr}   Nr|  r  s           rV   r  r  /  s    $   ((<<>GS+.G2259I  	K'3tu3M)NO 
 GSY%
8CCHJrY   
stage_namerelative_file_pathc                      t        d| ||      S )aT  
    Generates a Snowflake file URL to a staged file using the stage name and relative file path as inputs.
    A file URL permits prolonged access to a specified file. That is, the file URL does not expire.
    The file URL is in the following format:

    ``https://<account_identifier>/api/files/<db_name>/<schema_name>/<stage_name>/<relative_path>``

    See more details `here <https://docs.snowflake.com/en/sql-reference/functions/build_stage_file_url#returns>`_.

    Args:
        stage_name: Name of the internal or external stage where the file is stored.
            If the stage name includes spaces or special characters, it must be enclosed in single quotes
            (e.g. '@"my stage"' for a stage named "my stage"). It has to be a constant instead of a column expression.
        relative_file_path: Path and filename of the file relative to its location in the stage.
            It has to be a constant instead of a column expression.

    Example::

        >>> df.select(build_stage_file_url("@images_stage", "/us/yosemite/half_dome.jpg").alias("url")).collect()  # doctest: +SKIP
    build_stage_file_urlr}   r~   )r  r  rQ   s      rV   r  r  0  s    0 
,>) rY   stage_file_uric                 Z    |rt        d| g      nd}t        | d      }t        d|||      S )a  
    Converts a stage file URI to a FILE value or NULL (if input is NULL), with the
    `metadata <https://docs.snowflake.com/LIMITEDACCESS/sql-reference/data-types-unstructured#file-data-type>`_
    related to the file.

    Args:
        stage_file_uri: The stage file URI to convert to a FILE value, e.g., ``@mystage/myfile.txt``.
            It has to be a constant instead of a column expression.

    Example::

        >>> import json
        >>> # Create a temp stage.
        >>> _ = session.sql("create or replace temp stage mystage").collect()
        >>> # Upload a file to a stage.
        >>> r = session.file.put("tests/resources/testCSV.csv", "@mystage", auto_compress=False, overwrite=True)
        >>> df = session.range(1).select(to_file("@mystage/testCSV.csv").alias("file"))
        >>> result = json.loads(df.collect()[0][0])
        >>> result["RELATIVE_PATH"]
        'testCSV.csv'
        >>> result["CONTENT_TYPE"]
        'text/csv'
    to_fileNry   r   )r  rQ   rn   r   s       rV   r  r   0  s6    2 ?H
i.)9
:TC~y1A)QSIFFrY   c                 :    d}t        | |      }t        |||      S )a  
    Returns the content type (also known as mime type) of a FILE.

    Example::

        >>> import json
        >>> # Create a temp stage.
        >>> _ = session.sql("create or replace temp stage mystage").collect()
        >>> # Upload a file to a stage.
        >>> r = session.file.put("tests/resources/testCSV.csv", "@mystage", auto_compress=False, overwrite=True)
        >>> df = session.range(1).select(fl_get_content_type(to_file("@mystage/testCSV.csv")).alias("file"))
        >>> df.collect()[0][0]
        'text/csv'
    fl_get_content_typer}   r   r   rQ   r  rg  s       rV   r  r  >0  s$      *Mq-0I-iHHrY   c                 :    d}t        | |      }t        |||      S )a  
    Returns the hash content (ETAG) of a FILE.

    Example::

        >>> import json
        >>> # Create a temp stage.
        >>> _ = session.sql("create or replace temp stage mystage").collect()
        >>> # Upload a file to a stage.
        >>> r = session.file.put("tests/resources/testCSV.csv", "@mystage", auto_compress=False, overwrite=True)
        >>> df = session.range(1).select(fl_get_etag(to_file("@mystage/testCSV.csv")).alias("file"))
        >>> len(df.collect()[0][0])  # doctest: +SKIP
    fl_get_etagr}   r   r  s       rV   r  r  S0  s$     "Mq-0I-iHHrY   c                 :    d}t        | |      }t        |||      S )a  
    Returns the file type (modality) of a FILE. One of following values are returned:

        - document

        - video

        - audio

        - image

        - compressed

        - unknown

    Example::

        >>> import json
        >>> # Create a temp stage.
        >>> _ = session.sql("create or replace temp stage mystage").collect()
        >>> # Upload a file to a stage.
        >>> r = session.file.put("tests/resources/testCSV.csv", "@mystage", auto_compress=False, overwrite=True)
        >>> df = session.range(1).select(fl_get_file_type(to_file("@mystage/testCSV.csv")).alias("file"))
        >>> df.collect()[0][0]
        'document'
    fl_get_file_typer}   r   r  s       rV   r  r  g0  s$    8 'Mq-0I-iHHrY   c                 :    d}t        | |      }t        |||      S )a  
    Returns the last modified date of a FILE.

    Example::

        >>> import json
        >>> # Create a temp stage.
        >>> _ = session.sql("create or replace temp stage mystage").collect()
        >>> # Upload a file to a stage.
        >>> r = session.file.put("tests/resources/testCSV.csv", "@mystage", auto_compress=False, overwrite=True)
        >>> df = session.range(1).select(fl_get_last_modified(to_file("@mystage/testCSV.csv")).alias("file"))
        >>> type(df.collect()[0][0])
        <class 'datetime.datetime'>
    fl_get_last_modifiedr}   r   r  s       rV   r  r  0  $      +Mq-0I-iHHrY   c                 :    d}t        | |      }t        |||      S )a  
    Returns the relative path of a FILE.

    Example::

        >>> import json
        >>> # Create a temp stage.
        >>> _ = session.sql("create or replace temp stage mystage").collect()
        >>> # Upload a file to a stage.
        >>> r = session.file.put("tests/resources/testCSV.csv", "@mystage", auto_compress=False, overwrite=True)
        >>> df = session.range(1).select(fl_get_relative_path(to_file("@mystage/testCSV.csv")).alias("file"))
        >>> df.collect()[0][0]
        'testCSV.csv'
    fl_get_relative_pathr}   r   r  s       rV   r  r  0  r  rY   c                 :    d}t        | |      }t        |||      S )a  
    Returns the scoped URL of a FILE.

    Example::

        >>> import json
        >>> # Create a temp stage.
        >>> _ = session.sql("create or replace temp stage mystage").collect()
        >>> # Upload a file to a stage.
        >>> r = session.file.put("tests/resources/testCSV.csv", "@mystage", auto_compress=False, overwrite=True)
        >>> df = session.range(1).select(fl_get_scoped_file_url(to_file("@mystage/testCSV.csv")).alias("file"))
        >>> df.collect()[0][0]
    fl_get_scoped_file_urlr}   r   r  s       rV   r  r  0  s$     -Mq-0I-iHHrY   c                 :    d}t        | |      }t        |||      S )a  
    Returns the size, in bytes, of a FILE.

    Example::

        >>> import json
        >>> # Create a temp stage.
        >>> _ = session.sql("create or replace temp stage mystage").collect()
        >>> # Upload a file to a stage.
        >>> r = session.file.put("tests/resources/testCSV.csv", "@mystage", auto_compress=False, overwrite=True)
        >>> df = session.range(1).select(fl_get_size(to_file("@mystage/testCSV.csv")).alias("file"))
        >>> df.collect()[0][0]
        32
    fl_get_sizer}   r   r  s       rV   r  r  0  $      "Mq-0I-iHHrY   c                 :    d}t        | |      }t        |||      S )a  
    Returns the stage name of a FILE.

    Example::

        >>> import json
        >>> # Create a temp stage.
        >>> _ = session.sql("create or replace temp stage mystage").collect()
        >>> # Upload a file to a stage.
        >>> r = session.file.put("tests/resources/testCSV.csv", "@mystage", auto_compress=False, overwrite=True)
        >>> df = session.range(1).select(fl_get_stage(to_file("@mystage/testCSV.csv")).alias("file"))
        >>> df.collect()[0][0].split(".")[-1]
        'MYSTAGE'
    fl_get_stager}   r   r  s       rV   r  r  0  s$      #Mq-0I-iHHrY   c                 :    d}t        | |      }t        |||      S )a  
    Returns the stage URL of a FILE.

    Example::

        >>> import json
        >>> # Create a temp stage.
        >>> _ = session.sql("create or replace temp stage mystage").collect()
        >>> # Upload a file to a stage.
        >>> r = session.file.put("tests/resources/testCSV.csv", "@mystage", auto_compress=False, overwrite=True)
        >>> df = session.range(1).select(fl_get_stage_file_url(to_file("@mystage/testCSV.csv")).alias("file"))
        >>> df.collect()[0][0]  # doctest: +SKIP
        'https://'
    fl_get_stage_file_urlr}   r   r  s       rV   r  r  0  s$      ,Mq-0I-iHHrY   c                 :    d}t        | |      }t        |||      S )a  
    Checks if the input is an audio FILE.

    Example::

        >>> import json
        >>> # Create a temp stage.
        >>> _ = session.sql("create or replace temp stage mystage").collect()
        >>> # Upload a file to a stage.
        >>> r = session.file.put("tests/resources/testCSV.csv", "@mystage", auto_compress=False, overwrite=True)
        >>> df = session.range(1).select(fl_is_audio(to_file("@mystage/testCSV.csv")).alias("file"))
        >>> df.collect()[0][0]
        False
    fl_is_audior}   r   r  s       rV   r  r  1  r  rY   c                 :    d}t        | |      }t        |||      S )a  
    Checks if the input is a video FILE.

    Example::

        >>> import json
        >>> # Create a temp stage.
        >>> _ = session.sql("create or replace temp stage mystage").collect()
        >>> # Upload a file to a stage.
        >>> r = session.file.put("tests/resources/testCSV.csv", "@mystage", auto_compress=False, overwrite=True)
        >>> df = session.range(1).select(fl_is_video(to_file("@mystage/testCSV.csv")).alias("file"))
        >>> df.collect()[0][0]
        False
    fl_is_videor}   r   r  s       rV   r  r  1  r  rY   c                 :    d}t        | |      }t        |||      S )a  
    Checks if the input is a document FILE.

    Example::

        >>> import json
        >>> # Create a temp stage.
        >>> _ = session.sql("create or replace temp stage mystage").collect()
        >>> # Upload a file to a stage.
        >>> r = session.file.put("tests/resources/testCSV.csv", "@mystage", auto_compress=False, overwrite=True)
        >>> df = session.range(1).select(fl_is_document(to_file("@mystage/testCSV.csv")).alias("file"))
        >>> df.collect()[0][0]
        True
    fl_is_documentr}   r   r  s       rV   r  r  /1  s$      %Mq-0I-iHHrY   c                 :    d}t        | |      }t        |||      S )a  
    Checks if the input is a compressed FILE.

    Example::

        >>> import json
        >>> # Create a temp stage.
        >>> _ = session.sql("create or replace temp stage mystage").collect()
        >>> # Upload a file to a stage.
        >>> r = session.file.put("tests/resources/testCSV.csv", "@mystage", auto_compress=False, overwrite=True)
        >>> df = session.range(1).select(fl_is_compressed(to_file("@mystage/testCSV.csv")).alias("file"))
        >>> df.collect()[0][0]
        False
    fl_is_compressedr}   r   r  s       rV   r  r  D1  s$      'Mq-0I-iHHrY   c                 :    d}t        | |      }t        |||      S )a  
    Checks if the input is an image FILE.

    Example::

        >>> import json
        >>> # Create a temp stage.
        >>> _ = session.sql("create or replace temp stage mystage").collect()
        >>> # Upload a file to a stage.
        >>> r = session.file.put("tests/resources/testCSV.csv", "@mystage", auto_compress=False, overwrite=True)
        >>> df = session.range(1).select(fl_is_image(to_file("@mystage/testCSV.csv")).alias("file"))
        >>> df.collect()[0][0]
        False
    fl_is_imager}   r   r  s       rV   r  r  Y1  r  rY   template_stringexprsc                    d}|rt        || g|D cg c]  }| c}z         nd}|D cg c]  }t        ||       }}t        |t        |       g|||dS c c}w c c}w )a
  
    Constructs a structured OBJECT containing a template string and a list of arguments.
    This object is useful for dynamically formatting messages, constructing structured prompts,
    or storing formatted data for further processing, such as by Cortex AI functions.

    Args:
        template_string: A string containing numbered placeholders like {0}
            where the number is at least 0 and less than the number of expressions specified.
            The first expression is substituted for {0}, the second for {1}, and so on.
        *exprs: Expressions whose values will eventually be substituted into the template string
            in place of the numbered placeholders. These can be column names or other expressions.
            Values can be of any type coercible to a string (for example, VARCHAR, NUMBER, etc.), or FILE.

    Returns:
        A SQL OBJECT with the following structure:
        ``{ 'template': '<template_string>', 'args': ARRAY(<value_1>, <value_2>, ...) }``

        The args array contains the value of the expressions specified in the PROMPT function call.

    Note:

        - This function does not perform any string formatting itself.
          It is intended to construct an object to be consumed by Cortex AI functions.

        - It is an error to use a placeholder in the template string that does not have a corresponding expression,
          but it is not an error to have expressions that are not used in the template string.

    Examples::

        >>> df = session.create_dataframe([["Alice", "Monday"], ["Bob", "Tuesday"]], schema=["name", "day"])
        >>> df.select(prompt("Hello, {0}. Today is {1}", col("name"), col("day")).alias("greeting")).show()
        --------------------------------------------
        |"GREETING"                                |
        --------------------------------------------
        |{                                         |
        |  "args": [                               |
        |    "Alice",                              |
        |    "Monday"                              |
        |  ],                                      |
        |  "template": "Hello, {0}. Today is {1}"  |
        |}                                         |
        |{                                         |
        |  "args": [                               |
        |    "Bob",                                |
        |    "Tuesday"                             |
        |  ],                                      |
        |  "template": "Hello, {0}. Today is {1}"  |
        |}                                         |
        --------------------------------------------
        <BLANKLINE>
    promptNry   rd  )r  rQ   r  r  r   rn   s         rV   r  r  n1  s    r M  	MO+<QV?W?W+WX 
 >CCT^D-0CECs?+.3:=  @X Ds
   	AAresponse_formatc                     d}t        | t              rt        |       }n| }t        t	        j
                  |      j                  dd            }|rt        || |g      nd}t        |||||      S )a  
    Extracts information from an input string or file based on the specified response format.

    Args:
        input: Either:
            - A string or Column containing text to extract information from
            - A FILE type Column representing a document to extract from

        response_format: Information to be extracted in one of the following formats:

            - Simple object schema (dict) mapping feature names to extraction prompts:
              ``{'name': 'What is the last name of the employee?', 'address': 'What is the address of the employee?'}``
            - Array of strings containing the information to be extracted:
              ``['What is the last name of the employee?', 'What is the address of the employee?']``
            - Array of arrays containing two strings (feature name and extraction prompt):
              ``[['name', 'What is the last name of the employee?'], ['address', 'What is the address of the employee?']]``
            - Array of strings with colon-separated feature names and extraction prompts:
              ``['name: What is the last name of the employee?', 'address: What is the address of the employee?']``

    Returns:
        A Column containing a JSON object with the extracted information.

    Note:
        - You can either ask questions in natural language or describe information to be extracted
          (e.g., 'City, street, ZIP' instead of 'What is the address?')
        - To extract a list, add 'List:' at the beginning of each question
        - Maximum of 100 features can be extracted
        - Documents must be no more than 125 pages long
        - Maximum output length is 512 tokens per question

        Supported file formats: PDF, PNG, PPTX, EML, DOC, DOCX, JPEG, JPG, HTM, HTML, TEXT, TXT, TIF, TIFF
        Files must be less than 100 MB in size.

    Examples::

        >>> # Extract from text string
        >>> df = session.range(1).select(
        ...     ai_extract(
        ...         'John Smith lives in San Francisco and works for Snowflake',
        ...         {'name': 'What is the first name of the employee?', 'city': 'What is the address of the employee?'}
        ...     ).alias("extracted")
        ... )
        >>> df.show()
        --------------------------------
        |"EXTRACTED"                   |
        --------------------------------
        |{                             |
        |  "error": null,              |
        |  "response": {               |
        |    "city": "San Francisco",  |
        |    "name": "John"            |
        |  }                           |
        |}                             |
        --------------------------------
        <BLANKLINE>

        >>> # Extract using array format
        >>> df = session.create_dataframe(
        ...     ["Alice Johnson works in Seattle", "Bob Williams works in Portland"],
        ...     schema=["text"]
        ... )
        >>> extracted_df = df.select(
        ...     col("text"),
        ...     ai_extract(col("text"), [['name', 'What is the first name?'], ['city', 'What city do they work in?']]).alias("info")
        ... )
        >>> extracted_df.show()
        ------------------------------------------------------------
        |"TEXT"                          |"INFO"                   |
        ------------------------------------------------------------
        |Alice Johnson works in Seattle  |{                        |
        |                                |  "error": null,         |
        |                                |  "response": {          |
        |                                |    "city": "Seattle",   |
        |                                |    "name": "Alice"      |
        |                                |  }                      |
        |                                |}                        |
        |Bob Williams works in Portland  |{                        |
        |                                |  "error": null,         |
        |                                |  "response": {          |
        |                                |    "city": "Portland",  |
        |                                |    "name": "Bob"        |
        |                                |  }                      |
        |                                |}                        |
        ------------------------------------------------------------
        <BLANKLINE>

        >>> # Extract lists using List: prefix
        >>> df = session.range(1).select(
        ...     ai_extract(
        ...         'Python, Java, and JavaScript are popular programming languages',
        ...         [['languages', 'List: What programming languages are mentioned?']]
        ...     ).alias("extracted")
        ... )
        >>> df.show()
        ----------------------
        |"EXTRACTED"         |
        ----------------------
        |{                   |
        |  "error": null,    |
        |  "response": {     |
        |    "languages": [  |
        |      "Python",     |
        |      "Java",       |
        |      "JavaScript"  |
        |    ]               |
        |  }                 |
        |}                   |
        ----------------------
        <BLANKLINE>


        >>> # Extract from file
        >>> _ = session.sql("CREATE OR REPLACE TEMP STAGE mystage ENCRYPTION = (TYPE = 'SNOWFLAKE_SSE')").collect()
        >>> _ = session.file.put("tests/resources/invoice.pdf", "@mystage", auto_compress=False)
        >>> df = session.range(1).select(
        ...     ai_extract(
        ...         to_file('@mystage/invoice.pdf'),
        ...         [['date', 'What is the date of the invoice?'], ['amount', 'What is the amount of the invoice?']]
        ...     ).alias("extracted")
        ... )
        >>> df.show()
        --------------------------------
        |"EXTRACTED"                   |
        --------------------------------
        |{                             |
        |  "error": null,              |
        |  "response": {               |
        |    "amount": "USD $950.00",  |
        |    "date": "Nov 26, 2016"    |
        |  }                           |
        |}                             |
        --------------------------------
        <BLANKLINE>
    
ai_extractr  'Nry   )	r   r  rj   rm   jsondumpsr6  r%   r   )r)  r  rQ   r#  	input_colresponse_format_colrn   s          rV   r  r  1  s    X !M %J		 #4::o#>#F#FsC#PQ
  	ME?+CD   rY   	predicatefilec                     d}t        | |      }| |rt        || g      nd}t        ||||      S |rt        || |g      nd}t        |||||      S )a	  
    Classifies free-form prompt inputs into a boolean. Currently supports both text and image filtering.

    Args:
        predicate: If you're specifying an input string, it is string containing the text to be classified;
            If you're filtering on one file, it is a string containing the instructions to
            classify the file input as either TRUE or FALSE.
        file: The FILE type column that the file is classified by based on the instructions specified in ``predicate``.
            You can use IMAGE FILE as an input to the AI_FILTER function.

    Note:
        For more complicated prompts, especially with multiple file columns, you can use the :func:`prompt()`
        function to help with creating an input, which supports formatting across both strings and FILE datatypes.

    Examples::

        >>> # for text
        >>> session.range(1).select(ai_filter('Is Canada in North America?').alias("answer")).show()
        ------------
        |"ANSWER"  |
        ------------
        |True      |
        ------------
        <BLANKLINE>
        >>> # use prompt function
        >>> df = session.create_dataframe(["Switzerland", "Korea"], schema=["country"])
        >>> df.select(
        ...     ai_filter(prompt("Is {0} in Asia?", col("country"))).as_("asia"),
        ...     ai_filter(prompt("Is {0} in Europe?", col("country"))).as_("europe"),
        ...     ai_filter(prompt("Is {0} in North America?", col("country"))).as_("north_america"),
        ...     ai_filter(prompt("Is {0} in Central America?", col("country"))).as_("central_america"),
        ... ).show()
        -----------------------------------------------------------
        |"ASIA"  |"EUROPE"  |"NORTH_AMERICA"  |"CENTRAL_AMERICA"  |
        -----------------------------------------------------------
        |False   |True      |False            |False              |
        |True    |False     |False            |False              |
        -----------------------------------------------------------
        <BLANKLINE>
        >>> # for image
        >>> _ = session.sql("CREATE OR REPLACE TEMP STAGE mystage ENCRYPTION = (TYPE = 'SNOWFLAKE_SSE')").collect()
        >>> _ = session.file.put("tests/resources/dog.jpg", "@mystage", auto_compress=False)
        >>> df = session.range(1).select(ai_filter("is it a dog picture?", to_file("@mystage/dog.jpg")).alias("is_dog"))
        >>> df.show()
        ------------
        |"IS_DOG"  |
        ------------
        |True      |
        ------------
        <BLANKLINE>
    	ai_filterNry   )r7   r%   r   )r  r  rQ   r#  predicate_colrn   s         rV   r  r  \2  s}    r  M"9m<M|AJ!-)=PT=si
 	

 FO	4/@ATX 	 =$SI
 	
rY   list_of_categoriesc                    d}t        |      }|rt        || ||g      nd}t        | |      }t        |t              r2t        d |D              r t        |t        t                     d      }n!t        |t              r|}nt        d|       |r?t        t        j                  |      j                  dd            }	t        ||||	||	      S t        |||||	      S )
a
  
    Classifies text or images into categories that you specify.

    Args:
        expr: The string, image, or a SQL object from :func:`prompt()` that you're classifying.
            If you're classifying text, the input string is case sensitive.
            You might get different results if you use different capitalization.
        list_of_categories: An array of strings that represents the different categories.
            Categories are case-sensitive. The array must contain at least 2 and no more than 100 categories.
            If the requirements aren't met, the function returns an error.
        **kwargs: Configuration settings specified as key/value pairs. Supported keys:

            - task_description: A explanation of the classification task that is 50 words or fewer.
                This can help the model understand the context of the classification task and improve accuracy.

            - output_mode: Set to ``multi`` for multi-label classification. Defaults to `single` for single-label classification.

            - examples: A list of example objects for few-shot learning. Each example must include:

                - input: Example text to classify.

                - labels: List of correct categories for the input.

                - explanation: Explanation of why the input maps to those categories.

    Returns:
        A serialized object. The object's ``label`` field is a string that specifies the category to
        which the input belongs. If you specify invalid values for the arguments, an error is returned.

    Examples::

        >>> # for text
        >>> session.range(1).select(ai_classify('One day I will see the world', ['travel', 'cooking']).alias("answer")).show()
        -----------------
        |"ANSWER"       |
        -----------------
        |{              |
        |  "labels": [  |
        |    "travel"   |
        |  ]            |
        |}              |
        -----------------
        <BLANKLINE>
        >>> df = session.create_dataframe([
        ...     ['France', ['North America', 'Europe', 'Asia']],
        ...     ['Singapore', ['North America', 'Europe', 'Asia']],
        ...     ['one day I will see the world', ['travel', 'cooking', 'dancing']],
        ...     ['my lobster bisque is second to none', ['travel', 'cooking', 'dancing']]
        ... ], schema=["data", "category"])
        >>> df.select("data", ai_classify(col("data"), col("category"))["labels"][0].alias("class")).sort("data").show()
        ---------------------------------------------------
        |"DATA"                               |"CLASS"    |
        ---------------------------------------------------
        |France                               |"Europe"   |
        |Singapore                            |"Asia"     |
        |my lobster bisque is second to none  |"cooking"  |
        |one day I will see the world         |"travel"   |
        ---------------------------------------------------
        <BLANKLINE>

        >>> # using kwargs for advanced configuration
        >>> session.range(1).select(
        ...     ai_classify(
        ...         'One day I will see the world and learn to cook my favorite dishes',
        ...         ['travel', 'cooking', 'reading', 'driving'],
        ...         task_description='Determine topics related to the given text',
        ...         output_mode='multi',
        ...         examples=[{
        ...             'input': 'i love traveling with a good book',
        ...             'labels': ['travel', 'reading'],
        ...             'explanation': 'the text mentions traveling and a good book which relates to reading'
        ...         }]
        ...     ).alias("answer")
        ... ).show()
        ------------------
        |"ANSWER"        |
        ------------------
        |{               |
        |  "labels": [   |
        |    "cooking",  |
        |    "travel"    |
        |  ]             |
        |}               |
        ------------------
        <BLANKLINE>

        >>> # for image
        >>> _ = session.sql("CREATE OR REPLACE TEMP STAGE mystage ENCRYPTION = (TYPE = 'SNOWFLAKE_SSE')").collect()
        >>> _ = session.file.put("tests/resources/dog.jpg", "@mystage", auto_compress=False)
        >>> df = session.range(1).select(
        ...     ai_classify(
        ...         prompt("Please help me classify the dog within this image {0}", to_file("@mystage/dog.jpg")),
        ...         ["French Bulldog", "Golden Retriever", "Bichon", "Cavapoo", "Beagle"]
        ...     ).alias("classes")
        ... )
        >>> df.show()
        -----------------
        |"CLASSES"      |
        -----------------
        |{              |
        |  "labels": [  |
        |    "Cavapoo"  |
        |  ]            |
        |}              |
        -----------------
        <BLANKLINE>
    ai_classifyNc              3   <   K   | ]  }t        |t                y wrN  r   r  rO  r  s     rV   rP  zai_classify.<locals>.<genexpr> 3  s      4 
1c4   Frh   rQ   z:list_of_categories must be a list of str or a Column, got r  r  ry   )dictr%   r7   r   r   allrj   r=   rA   r6   	TypeErrorrm   r  r  r6  r   )
r   r  rQ   rR  r#  config_dictrn   r  cat_col
config_cols
             rV   r  r  2  s    d "Mv,K  	MD2Dk+RS  dM2H$d+ 4$64 1 :<)@E
 
&	/$HI[H\]
 	
 djj5==c3GH
8Wjsi
 	
 8W3)
 	
rY   c                 ^    d}|rt        || g      nd}t        | |      }t        ||||      S )a  
    Summarizes a column of text data.

    Args:
        expr: This is an expression that contains text for summarization, such as restaurant reviews or phone transcripts.

    Example::

        >>> df = session.create_dataframe([
        ...     [1, "Excellent"],
        ...     [1, "Excellent"],
        ...     [1, "Great"],
        ...     [1, "Mediocre"],
        ...     [2, "Terrible"],
        ...     [2, "Bad"],
        ... ], schema=["product_id", "review"])
        >>> summary_df = df.select(ai_summarize_agg(col("review")))
        >>> summary_df.count()
        1
        >>> summary_df = df.group_by("product_id").agg(ai_summarize_agg(col("review")))
        >>> summary_df.count()
        2
    ai_summarize_aggNry   r   )r   rQ   r#  rn   r  s        rV   r  r  83  s9    2 'M8A
mdV
4tCdM2H-yQQrY   task_descriptionc                 z    d}|rt        || |g      nd}t        | |      }t        ||      }t        |||||      S )a  
    Aggregates a column of text data using a natural language task description.

    This function reduces a column of text by performing a natural language aggregation
    as described in the task description. For instance, it can summarize large datasets or
    extract specific insights.

    Args:
        expr: A column or literal string containing the text data on which the aggregation operation
            is to be performed.
        task_description: A plain English string that describes the aggregation task, such as
            "Summarize the product reviews for a blog post targeting consumers" or
            "Identify the most positive review and translate it into French and Polish, one word only".

    Example::

        >>> df = session.create_dataframe([
        ...     [1, "Excellent"],
        ...     [1, "Excellent"],
        ...     [1, "Great"],
        ...     [1, "Mediocre"],
        ...     [2, "Terrible"],
        ...     [2, "Bad"],
        ... ], schema=["product_id", "review"])
        >>> summary_df = df.select(ai_agg(col("review"), "Summarize the product reviews for a blog post targeting consumers"))
        >>> summary_df.count()
        1
        >>> summary_df = df.group_by("product_id").agg(ai_agg(col("review"), "Summarize the product reviews for a blog post targeting consumers"))
        >>> summary_df.count()
        2

    Note:
        For optimal performance, follow these guidelines:

            - Use plain English text for the task description.

            - Describe the text provided in the task description. For example, instead of a task description like "summarize", use "Summarize the phone call transcripts".

            - Describe the intended use case. For example, instead of "find the best review", use "Find the most positive and well-written restaurant review to highlight on the restaurant website".

            - Consider breaking the task description into multiple steps. For example, instead of "Summarize the new articles", use "You will be provided with news articles from various publishers presenting events from different points of view. Please create a concise and elaborative summary of source texts without missing any crucial information.".
    ai_aggNry   r   )r   r  rQ   r#  rn   r  task_description_cols          rV   r  r  W3  s^    ` M  	MD2B+CD 
 dM2H)*:MJx!5C9 rY   input1input2c                    d}t        |      }|rt        || ||g      nd}t        | |      }t        ||      }|r?t        t	        j
                  |      j                  dd            }	t        ||||	||      S t        |||||      S )u  
    Computes a similarity score based on the vector cosine similarity value of the inputs' embedding vectors.
    Currently supports both text and image similarity computation.

    Args:
        input1: The first input for comparison. Can be a string with text or an image (FILE data type).
        input2: The second input for comparison. Can be a string with text or an image (FILE data type).
            Must be the same type as input1 (both text or both images).
        **kwargs: Configuration settings specified as key/value pairs. Supported keys:

            - model: The embedding model used for embedding. For STRING input, defaults to 'snowflake-arctic-embed-l-v2'.
                For IMAGE input, defaults to 'voyage-multimodal-3'. Supported values include:
                'snowflake-arctic-embed-l-v2', 'nv-embed-qa-4', 'multilingual-e5-large', 'voyage-multilingual-2',
                'snowflake-arctic-embed-m-v1.5', 'snowflake-arctic-embed-m', 'e5-base-v2', 'voyage-multimodal-3' (for images).

    Returns:
        A float value of range -1 to 1 that represents the similarity score computed using vector similarity
        between two embedding vectors for the inputs.

    Note:
        AI_SIMILARITY does not support computing the similarity between text and image inputs.
        Both inputs must be of the same type:

            - They are both Python ``str``.
            - They are both :class:`Column` objects representing a FILE data type.

    Examples::

        >>> # Text similarity
        >>> df = session.range(1).select(ai_similarity('I like this dish', 'This dish is very good').alias("similarity"))
        >>> df.collect()[0][0] > 0.8
        True

        >>> # Text similarity with custom model
        >>> df = session.range(1).select(
        ...     ai_similarity(
        ...         'I love programming',
        ...         '我喜欢编程',
        ...         model='multilingual-e5-large'
        ...     ).alias("similarity")
        ... )
        >>> df.collect()[0][0] > 0.8
        True

        >>> # Using columns
        >>> df = session.create_dataframe([
        ...     ['Hello world', 'Hi there'],
        ...     ['Good morning', 'Good evening'],
        ... ], schema=["text1", "text2"])
        >>> df = df.select(ai_similarity(col("text1"), col("text2")).alias("similarity"))
        >>> result = df.collect()
        >>> result[0][0] < 0.6
        True
        >>> result[1][0] > 0.7
        True

        >>> # Image similarity
        >>> _ = session.sql("CREATE OR REPLACE TEMP STAGE mystage ENCRYPTION = (TYPE = 'SNOWFLAKE_SSE')").collect()
        >>> _ = session.file.put("tests/resources/dog.jpg", "@mystage", auto_compress=False)
        >>> _ = session.file.put("tests/resources/cat.jpeg", "@mystage", auto_compress=False)
        >>> df = session.range(1).select(
        ...     ai_similarity(
        ...         to_file("@mystage/dog.jpg"),
        ...         to_file("@mystage/cat.jpeg")
        ...     ).alias("similarity")
        ... )
        >>> df.collect()[0][0] < 0.5
        True
    ai_similarityNr  r  ry   )r  r%   r7   rm   r  r  r6  r   )
r  r  rQ   rR  r#  r  rn   
input1_col
input2_colr  s
             rV   r  r  3  s    X $Mv,K  	MFFK+HI   6J6Jdjj5==c3GH

 	
 :zy
 	
rY   c                     d}t        |      }|rP|rt        || |g      nd}t        t        j                  |      j                  dd            }t        || |||      S |rt        || g      nd}t        || ||      S )a  
    Returns the extracted content from a document as a JSON-formatted string.
    This function supports two types of extraction: Optical Character Recognition (OCR), and layout.

    Args:
        file: A FILE type column containing the document to parse. The document must be on a
            Snowflake stage that uses server-side encryption and is accessible to the user.
        **kwargs: Configuration settings specified as key/value pairs. Supported keys:

            - mode: Specifies the parsing mode. Supported modes are:
                - 'OCR': The function extracts text only. This is the default mode.
                - 'LAYOUT': The function extracts layout as well as text, including structural
                  content such as tables.

            - page_split: If set to True, the function splits the document into pages and
              processes each page separately. This feature supports only PDF, PowerPoint (.pptx),
              and Word (.docx) documents. Documents in other formats return an error.
              The default is False.
              Tip: To process long documents that exceed the token limit, set this option to True.

    Returns:
        A JSON object (as a string) that contains the extracted data and associated metadata.
        The options argument determines the structure of the returned object.

        If ``page_split`` is set, the output contains:
            - pages: An array of JSON objects, each containing text extracted from the document.
            - metadata: Contains metadata about the document, such as page count.
            - errorInformation: Contains error information if document can't be parsed (only on error).

        If ``page_split`` is False or not present, the output contains:
            - content: Plain text (in OCR mode) or Markdown-formatted text (in LAYOUT mode).
            - metadata: Contains metadata about the document, such as page count.
            - errorInformation: Contains error information if document can't be parsed (only on error).

    Examples::

        >>> import json
        >>> # Parse a PDF document with default OCR mode
        >>> _ = session.sql("CREATE OR REPLACE TEMP STAGE mystage ENCRYPTION = (TYPE = 'SNOWFLAKE_SSE')").collect()
        >>> _ = session.file.put("tests/resources/doc.pdf", "@mystage", auto_compress=False)
        >>> df = session.range(1).select(
        ...     ai_parse_document(to_file("@mystage/doc.pdf")).alias("parsed_content")
        ... )
        >>> result = json.loads(df.collect()[0][0])
        >>> "Sample PDF" in result["content"]
        True
        >>> result["metadata"]["pageCount"]
        3

        >>> # Parse with LAYOUT mode to extract tables and structure
        >>> _ = session.file.put("tests/resources/invoice.pdf", "@mystage", auto_compress=False)
        >>> df = session.range(1).select(
        ...     ai_parse_document(
        ...         to_file("@mystage/invoice.pdf"),
        ...         mode='LAYOUT'
        ...     ).alias("parsed_content")
        ... )
        >>> result = json.loads(df.collect()[0][0])
        >>> "| Customer Name |" in result["content"] and "| Country |" in result["content"]  # Markdown format
        True

        >>> # Parse with page splitting for documents
        >>> df = session.range(1).select(
        ...     ai_parse_document(
        ...         to_file("@mystage/doc.pdf"),
        ...         page_split=True
        ...     ).alias("parsed_content")
        ... )
        >>> result = json.loads(df.collect()[0][0])
        >>> len(result["pages"])
        3
        >>> 'Sample PDF' in result["pages"][0]["content"]
        True
        >>> result["pages"][0]["index"]
        0
    ai_parse_documentNr  r  ry   r  r%   rm   r  r  r6  r   )r  rQ   rR  r#  r  rn   r  s          rV   r  r  3  s    d (Mv,K   k/BC 	 djj5==c3GH
4#
 	
 =F!-$84mTyQQrY   
audio_filec                     d}t        |      }|rP|rt        || |g      nd}t        t        j                  |      j                  dd            }t        || |||      S |rt        || g      nd}t        || ||      S )a  
    Transcribes text from an audio file with optional timestamps and speaker labels.

    AI_TRANSCRIBE supports numerous languages (automatically detected), and audio can contain
    more than one language. Timestamps and speaker labels are extracted based on the specified
    timestamp granularity.

    Args:
        audio_file: A FILE type column representing an audio file. The audio file must be on a
            Snowflake stage that uses server-side encryption and is accessible to the user.
            Use the to_file() function to create a reference to your staged file.
        **kwargs: Configuration settings specified as key/value pairs. Supported keys:

            - timestamp_granularity: A string specifying the desired timestamp granularity.
              Possible values are:

              - 'word': The file is transcribed as a series of words, each with its own timestamp.
              - 'speaker': The file is transcribed as a series of conversational "turns", each with its own timestamp and speaker label.

              If this field is not specified, the entire file is transcribed as a single
              segment without timestamps by default.

    Returns:
        A string containing a JSON representation of the transcription result. The JSON object
        contains the following fields:

            - audio_duration: The total duration of the audio file in seconds.
            - text: The transcription of the complete audio file (when timestamp_granularity
              is not specified).
            - segments: An array of segments (when timestamp_granularity is set to 'word' or 'speaker').
              Each segment contains:

              - start: The start time of the segment in seconds.
              - end: The end time of the segment in seconds.
              - text: The transcription text for the segment.
              - speaker_label: The label of the speaker for the segment (only when
                timestamp_granularity is 'speaker'). Labels are of the form "SPEAKER_00",
                "SPEAKER_01", etc.

    Note:
        - Supports languages: Arabic, Bulgarian, Cantonese, Catalan, Chinese, Czech, Dutch,
          English, French, German, Greek, Hungarian, Indonesian, Italian, Japanese, Korean,
          Latvian, Polish, Portuguese, Romanian, Russian, Serbian, Slovenian, Spanish,
          Swedish, Thai, Turkish, Ukrainian.
        - Supported audio formats: FLAC, MP3, Ogg, WAV, WebM
        - Maximum file size: 700 MB
        - Maximum duration: 60 minutes with timestamps, 120 minutes without

    Examples::

        >>> import json
        >>> # Basic transcription without timestamps
        >>> _ = session.sql("CREATE OR REPLACE TEMP STAGE mystage ENCRYPTION = (TYPE = 'SNOWFLAKE_SSE')").collect()
        >>> _ = session.file.put("tests/resources/audio.ogg", "@mystage", auto_compress=False)
        >>> df = session.range(1).select(
        ...     ai_transcribe(to_file("@mystage/audio.ogg")).alias("transcript")
        ... )
        >>> result = json.loads(df.collect()[0][0])
        >>> result['audio_duration'] > 120  # more than 2 minutes
        True
        >>> "glad to see things are going well" in result['text'].lower()
        True

        >>> # Transcription with word-level timestamps
        >>> df = session.range(1).select(
        ...     ai_transcribe(
        ...         to_file("@mystage/audio.ogg"),
        ...         timestamp_granularity='word'
        ...     ).alias("transcript")
        ... )
        >>> result = json.loads(df.collect()[0][0])
        >>> len(result["segments"]) > 0
        True
        >>> result["segments"][0]["text"].lower()
        'glad'
        >>> 'start' in result["segments"][0] and 'end' in result["segments"][0]
        True

        >>> # Transcription with speaker diarization
        >>> _ = session.file.put("tests/resources/conversation.ogg", "@mystage", auto_compress=False)
        >>> df = session.range(1).select(
        ...     ai_transcribe(
        ...         to_file("@mystage/conversation.ogg"),
        ...         timestamp_granularity='speaker'
        ...     ).alias("transcript")
        ... )
        >>> result = json.loads(df.collect()[0][0])
        >>> result["audio_duration"] > 100  # more than 100 seconds
        True
        >>> len(result["segments"]) > 0
        True
        >>> result["segments"][0]["speaker_label"]
        'SPEAKER_00'
        >>> 'jenny' in result["segments"][0]["text"].lower()
        True
        >>> 'start' in result["segments"][0] and 'end' in result["segments"][0]
        True
    ai_transcribeNr  r  ry   r  )r  rQ   rR  r#  r  rn   r  s          rV   r  r  a4  s    P $Mv,K   
K/HI 	 djj5==c3GH
:zy
 	
 CL!-*>QUmZcYWWrY   r  r  model_parametersshow_detailsc                      y rN  rT   )r  r  r  r  r  rQ   s         rV   ai_completer  4  s     rY   c                      y rN  rT   )r  r  r  r  r  r  rQ   s          rV   r  r  4  s     rY   c                    d}| |g}||j                  |       ||j                  |       ||j                  |       ||j                  |       |rt        ||      nd}	t        |       }
t        ||      }d|
i}|@t	        |t
              st	        |j                  t              r||d<   ||d<   nt        d      ||d<   |3t        t        j                  |      j                  dd	            }||d
<   |3t        t        j                  |      j                  dd	            }||d<   |t        t        |            |d<   t        |||	|      S )a  
    Generates a response (completion) for a text prompt using a supported language model.

    This function supports three main usage patterns:
    1. String prompt only: AI_COMPLETE(model, prompt, ...)
    2. Prompt with file: AI_COMPLETE(model, prompt, file, ...)
    3. Prompt object: AI_COMPLETE(model, prompt_object, ...)

    Args:
        model: A string specifying the model to be used. Different input types have different supported models.
            See details in `AI_COMPLETE <https://docs.snowflake.com/en/sql-reference/functions/ai_complete>`_.
        prompt: A string prompt, or a Column object from :func:`prompt()`.
        file: The FILE type column representing an image. When provided, prompt should be a string.
        model_parameters: Optional object containing model hyperparameters:

            - temperature: A value from 0 to 1 controlling randomness (default: ``0``)
            - top_p: A value from 0 to 1 controlling diversity (default: ``0``)
            - max_tokens: Maximum number of output tokens (default: ``4096``, max: ``8192``)
            - guardrails: Enable Cortex Guard filtering (default: ``FALSE``)

        response_format: Optional JSON schema that the response should follow for structured outputs.
        show_details: Optional boolean flag to return detailed inference information (default: ``FALSE``).

    Returns:
        ``response_format`` and ``show_details`` are only supported for single string.
        When ``show_details`` is ``FALSE`` and ``response_format`` is not specified: Returns a string containing the response.
        When ``show_details`` is ``FALSE`` and ``response_format`` is specified: Returns an object following the provided format.
        When ``show_details`` is ``TRUE``: Returns a JSON object with detailed inference information including
        choices, created timestamp, model name, and token usage statistics.
        See details in `AI_COMPLETE Returns <https://docs.snowflake.com/en/sql-reference/functions/ai_complete-single-string#returns>`_.

    Examples::

        >>> # Basic completion with string prompt
        >>> df = session.range(1).select(
        ...     ai_complete('snowflake-arctic', 'What are large language models?').alias("response")
        ... )
        >>> len(df.collect()[0][0]) > 10
        True

        >>> # Using model parameters
        >>> df = session.range(1).select(
        ...     ai_complete(
        ...         model='llama3.3-70b',
        ...         prompt='How does a snowflake get its unique pattern?',
        ...         model_parameters={
        ...             'temperature': 0.7,
        ...             'max_tokens': 100
        ...         }
        ...     ).alias("response")
        ... )
        >>> result = df.collect()[0][0]
        >>> len(result) > 0
        True

        >>> # With detailed output
        >>> df = session.range(1).select(
        ...     ai_complete(
        ...         model='mistral-large',
        ...         prompt='Explain AI in one sentence.',
        ...         show_details=True
        ...     ).alias("detailed_response")
        ... )
        >>> result = df.collect()[0][0]
        >>> 'choices' in result and 'usage' in result
        True

        >>> # Prompt with image processing
        >>> _ = session.sql("CREATE OR REPLACE TEMP STAGE mystage ENCRYPTION = (TYPE = 'SNOWFLAKE_SSE')").collect()
        >>> _ = session.file.put("tests/resources/kitchen.png", "@mystage", auto_compress=False)
        >>> df = session.range(1).select(
        ...     ai_complete(
        ...         model='claude-4-sonnet',
        ...         prompt='Extract the kitchen appliances identified in this image. Respond in JSON only with the identified appliances.',
        ...         file=to_file('@mystage/kitchen.png'),
        ...     )
        ... )
        >>> result = df.collect()[0][0]
        >>> "microwave" in result and "refrigerator" in result
        True

        >>> # Structured output with response format
        >>> response_schema = {
        ...     'type': 'json',
        ...     'schema': {
        ...         'type': 'object',
        ...         'properties': {
        ...             'sentiment': {'type': 'string'},
        ...             'confidence': {'type': 'number'}
        ...         },
        ...         'required': ['sentiment', 'confidence']
        ...     }
        ... }
        >>> df = session.range(1).select(
        ...     ai_complete(
        ...         model='llama3.3-70b',
        ...         prompt='Analyze the sentiment of this text: I love this product!',
        ...         response_format=response_schema
        ...     ).alias("structured_result")
        ... )
        >>> result = df.collect()[0][0]
        >>> 'sentiment' in result and 'confidence' in result
        True

        >>> # Using prompt object from prompt() function
        >>> df = session.range(1).select(
        ...     ai_complete(
        ...         model='claude-3-7-sonnet',
        ...         prompt=prompt("Extract the kitchen appliances identified in this image. Respond in JSON only with the identified appliances? {0}", to_file('@mystage/kitchen.png')),
        ...     )
        ... )
        >>> result = df.collect()[0][0]
        >>> "microwave" in result and "refrigerator" in result
        True
    r  Nr  r  r  z+prompt must be a string or a literal columnr  r  r  r  r  r  ry   )r  r%   rj   r7   r   r  r  r   r  rm   r  r  r6  r  )r  r  r  r  r  r  rQ   r#  rJ  rn   	model_col
prompt_colcall_kwargsmodel_params_colr  s                  rV   r  r  4  sw   z "M6?DD#$%"O$L!6?
mT
2TC E
I6J 	K
 fc"j&H'1K$"&KJKK *H ##DJJ/?$@$H$Hc$RS*:&' "&tzz/'B'J'J3PS'TU)<%& &.s</@&AN#){	 rY   c                 x    d}t        |       }t        ||      }|rt        || |g      nd}t        |||||      S )a  
    Creates an embedding vector from text or an image.

    Args:
        model: A string specifying the vector embedding model to be used. Supported models:

            For text embeddings:
                - 'snowflake-arctic-embed-l-v2.0': Arctic large model (default for text)
                - 'snowflake-arctic-embed-l-v2.0-8k': Arctic large model with 8K context
                - 'nv-embed-qa-4': NVIDIA embedding model for Q&A
                - 'multilingual-e5-large': Multilingual embedding model
                - 'voyage-multilingual-2': Voyage multilingual model

            For image embeddings:
                - 'voyage-multimodal-3': Voyage multimodal model (only for images)

        input: The string or image (as a FILE object) to generate an embedding from.
            Can be a string with text or a FILE column containing an image.

    Returns:
        A VECTOR containing the embedding representation of the input.

    Examples::

        >>> # Text embedding
        >>> df = session.range(1).select(
        ...     ai_embed('snowflake-arctic-embed-l-v2.0', 'Hello, world!').alias("embedding")
        ... )
        >>> result = df.collect()[0][0]
        >>> len(result) > 0
        True

        >>> # Text embedding with multilingual model
        >>> df = session.create_dataframe([
        ...     ['Hello world'],
        ...     ['Bonjour le monde'],
        ...     ['Hola mundo']
        ... ], schema=["text"])
        >>> df = df.select(
        ...     col("text"),
        ...     ai_embed('multilingual-e5-large', col("text")).alias("embedding")
        ... )
        >>> embeddings = df.collect()
        >>> all(len(row[1]) > 0 for row in embeddings)
        True

        >>> # Image embedding
        >>> _ = session.sql("CREATE OR REPLACE TEMP STAGE mystage ENCRYPTION = (TYPE = 'SNOWFLAKE_SSE')").collect()
        >>> _ = session.file.put("tests/resources/dog.jpg", "@mystage", auto_compress=False)
        >>> df = session.range(1).select(
        ...     ai_embed('voyage-multimodal-3', to_file('@mystage/dog.jpg')).alias("image_embedding")
        ... )
        >>> result = df.collect()[0][0]
        >>> len(result) > 0
        True
    ai_embedNry   )rj   r7   r%   r   )r  r)  rQ   r#  r  r  rn   s          rV   r  r  5  sT    | M E
Ium4I AJ
meU^
<tC y)# rY   
categoriesc                 j   d}t        | |      }| |rt        || g      nd}t        ||||      S t        |t              rt        d |D              s!t        dt        |      j                         t        |t        t                     d      }|rt        || |g      nd}t        |||||      S )us$  
    Returns overall and category sentiment in the given input text.

    Args:
        text: A string containing the text in which sentiment is detected.
        categories: An array containing up to ten categories (also called entities or aspects) for which sentiment should be extracted.
            Each category is a string. For example, if extracting sentiment from a restaurant review, you might specify
            ``['cost', 'quality', 'service', 'wait time']`` as the categories. Each category may be a maximum of 30 characters long.
            If you do not provide this argument, AI_SENTIMENT returns only the overall sentiment.

    Returns:
        An OBJECT value containing a ``categories`` field. ``categories`` is an array of category records. Each category includes these fields:

        - ``name``: The name of the category. The category names match the categories specified in the ``categories`` argument.
        - ``sentiment``: The sentiment of the category. Each sentiment result is one of the following strings.

            - ``unknown``: The category was not mentioned in the text.
            - ``positive``: The category was mentioned positively in the text.
            - ``negative``: The category was mentioned negatively in the text.
            - ``neutral``: The category was mentioned in the text, but neither positively nor negatively.
            - ``mixed``: The category was mentioned both positively and negatively in the text.

        The ``overall`` category record is always included and contains the overall sentiment of the text.

    Note:
        AI_SENTIMENT can analyze sentiment in English, French, German, Hindi, Italian, Spanish, and Portuguese.
        You can specify categories in the language of the text or in English.

    Examples::

        >>> # Get overall sentiment only
        >>> session.range(1).select(
        ...     ai_sentiment("A tourist's delight, in low urban light, Recommended gem, a pizza night sight. Swift arrival, a pleasure so right, Yet, pockets felt lighter, a slight pricey bite. 💰🍕🚀").alias("sentiment")
        ... ).show()
        ------------------------------
        |"SENTIMENT"                 |
        ------------------------------
        |{                           |
        |  "categories": [           |
        |    {                       |
        |      "name": "overall",    |
        |      "sentiment": "mixed"  |
        |    }                       |
        |  ]                         |
        |}                           |
        ------------------------------
        <BLANKLINE>

        >>> # Extract sentiment for specific categories
        >>> df = session.create_dataframe([
        ...     ["The movie had amazing visual effects but the plot was terrible."],
        ...     ["The food was delicious but the service was slow."],
        ...     ["The movie was great, but the acting was terrible."]
        ... ], schema=["review"])
        >>> df.select("review", ai_sentiment(col("review"), ['plot', 'visual effects', 'acting']).alias("sentiment")).show()
        ----------------------------------------------------------------------------------------
        |"REVIEW"                                            |"SENTIMENT"                      |
        ----------------------------------------------------------------------------------------
        |The movie had amazing visual effects but the pl...  |{                                |
        |                                                    |  "categories": [                |
        |                                                    |    {                            |
        |                                                    |      "name": "overall",         |
        |                                                    |      "sentiment": "mixed"       |
        |                                                    |    },                           |
        |                                                    |    {                            |
        |                                                    |      "name": "acting",          |
        |                                                    |      "sentiment": "neutral"     |
        |                                                    |    },                           |
        |                                                    |    {                            |
        |                                                    |      "name": "plot",            |
        |                                                    |      "sentiment": "negative"    |
        |                                                    |    },                           |
        |                                                    |    {                            |
        |                                                    |      "name": "visual effects",  |
        |                                                    |      "sentiment": "positive"    |
        |                                                    |    }                            |
        |                                                    |  ]                              |
        |                                                    |}                                |
        |The food was delicious but the service was slow.    |{                                |
        |                                                    |  "categories": [                |
        |                                                    |    {                            |
        |                                                    |      "name": "overall",         |
        |                                                    |      "sentiment": "mixed"       |
        |                                                    |    },                           |
        |                                                    |    {                            |
        |                                                    |      "name": "acting",          |
        |                                                    |      "sentiment": "unknown"     |
        |                                                    |    },                           |
        |                                                    |    {                            |
        |                                                    |      "name": "plot",            |
        |                                                    |      "sentiment": "unknown"     |
        |                                                    |    },                           |
        |                                                    |    {                            |
        |                                                    |      "name": "visual effects",  |
        |                                                    |      "sentiment": "unknown"     |
        |                                                    |    }                            |
        |                                                    |  ]                              |
        |                                                    |}                                |
        |The movie was great, but the acting was terrible.   |{                                |
        |                                                    |  "categories": [                |
        |                                                    |    {                            |
        |                                                    |      "name": "overall",         |
        |                                                    |      "sentiment": "mixed"       |
        |                                                    |    },                           |
        |                                                    |    {                            |
        |                                                    |      "name": "acting",          |
        |                                                    |      "sentiment": "negative"    |
        |                                                    |    },                           |
        |                                                    |    {                            |
        |                                                    |      "name": "plot",            |
        |                                                    |      "sentiment": "positive"    |
        |                                                    |    },                           |
        |                                                    |    {                            |
        |                                                    |      "name": "visual effects",  |
        |                                                    |      "sentiment": "positive"    |
        |                                                    |    }                            |
        |                                                    |  ]                              |
        |                                                    |}                                |
        ----------------------------------------------------------------------------------------
        <BLANKLINE>

    ai_sentimentNry   c              3   <   K   | ]  }t        |t                y wrN  r  r  s     rV   rP  zai_sentiment.<locals>.<genexpr>6  s      7
#$Jq#7
r  z&categories must be a list of str, got Fr  )r7   r%   r   r   r   r  r  type__name__rj   r=   rA   )r  r  rQ   r#  r"  rn   r  s          rV   r  r  5  s    @ #M dM2H<E!-$84mXC9UU *d+3 7
(27
 4
 8j9I9R9R8ST  j9Z\+BeT   j/AB 	
 8W3)
 	
rY   source_languagetarget_languagec                     d}|rt        || ||g      nd}t        | |      }t        ||      }t        ||      }t        ||||||      S )a  
    Translates the given input text from one supported language to another.

    Args:
        text: A string or Column containing the text to be translated.
        source_language: A string or Column specifying the language code for the source language.
            Specify an empty string ``''`` to automatically detect the source language.
        target_language: A string or Column specifying the language code for the target language.

    Returns:
        A string containing a translation of the original text into the target language.

    See details in `AI_TRANSLATE <https://docs.snowflake.com/en/sql-reference/functions/ai_translate>`_.

    Examples::

        >>> # Translate literal text from English to German
        >>> df = session.range(1).select(
        ...     ai_translate('Hello world', 'en', 'de').alias('translation')
        ... )
        >>> df.collect()[0][0].lower()
        'hallo welt'

        >>> # Auto-detect source language and translate to English
        >>> df = session.range(1).select(
        ...     ai_translate('Hola mundo', '', 'en').alias('translation')
        ... )
        >>> df.collect()[0][0].lower()
        'hi world'
    ai_translateNry   r   )	r  r  r  rQ   r#  rn   r"  source_lang_coltarget_lang_cols	            rV   r  r  6  sq    J #M
  	MD/?+ST  dM2H$_mDO$_mDO  rY   )T)NT)CALLNT)r-  FFr&  T)r   T)r   )r-  r   r   )r-  T)TT)TFT)NNT)FT)r   NFT)r-  FTrN  )r   T)NNNNNNNNNNNNNT)NNTT)NNNNTT)rL   T)r   NT)NNNT)NNNNT(#  __doc__r  systypingr   r  r?  r   typesr   r   r   r   r	   r
   r   r   snowflake.snowparkr  4snowflake.snowpark._internal.proto.generated.ast_pb2r  	_internalro   	generatedast_pb2snowflake.snowpark._functionsr   /snowflake.snowpark._functions.general_functionsr   r   !snowflake.snowpark.table_function0snowflake.snowpark._internal.analyzer.expressionr   r   r   r   r   r   r   r   r   r   6snowflake.snowpark._internal.analyzer.unary_expressionr   7snowflake.snowpark._internal.analyzer.window_expressionr   r   r   r   r   &snowflake.snowpark._internal.ast.utilsr    r!   r"   r#   r$   r%   'snowflake.snowpark._internal.type_utilsr&   r'   r(   r)   r*   r+   &snowflake.snowpark._internal.udf_utilsr,   "snowflake.snowpark._internal.utilsr-   r.   r/   r0   r1   r2   r3   .snowflake.snowpark._functions.scalar_functionssnowflake.snowpark.columnr5   r6   r7   r8   r9   r:   #snowflake.snowpark.stored_procedurer;   r<   snowflake.snowpark.typesr=   r>   r?   r@   rA   rB   rC   rD   snowflake.snowpark.udafrE   rF   snowflake.snowpark.udfrG   rH   snowflake.snowpark.udtfrI   rJ   version_inforM   collections.abcr  boolrW   rc   rj   rm   rx   r|   r   r   r   r   r   r   r   r   r   r   r   rG  r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  rH  r  percentile_approxr  r  r  r  r   r(  r,  grouping_idr1  r4  r7  r9  r<  rE  rT  rY  r[  r]  r_  rc  rg  rm  rq  rr  ru  rw  ry  r|  r~  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rR  r  r  r  r"  r+  r1  r6  r:  r>  r@  rC  rE  rH  r^  rb  r  r  ri  r  r  ro  rr  rt  rw  rz  r|  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rT  r  r  r  r  r  r  r  r  r  r  r  r  r  r	  r  r  r  r  r  r  r(  r*  r-  r0  
is_varcharr3  is_date_valuer6  r8  r:  r<  r>  r@  rB  rD  rF  rH  rQ  r`  rb  rW  rl  rn  rr  rt  rv  rx  rz  r|  r~  r  r  r  r  r  r  r  r  r  r  rU  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   rI  ru  r  	as_numberr  r
  r  r  r  r  r  r  r  r  r  r  r  r"  r%  r  r+  r.  rX  
element_atr  r   r<  rI  rK  rM  rO  rQ  rV  rY  r[  r^  r`  rb  rd  rf  ri  rk  rp  rs  r  r  r  Typer  r  r  r  r  r  r  r  r  r  rp   r  r  r  r  r  r  call_builtincollect_setcollect_listbuiltincountDistinctrs  
to_varcharr   monotonically_increasing_idfrom_unixtime
sort_arraymap_from_arrayssignum
array_joinarray_union
map_concatr  r  r   r  r  r  r$  r&  r(  r*  r,  r/  r1  r4  r6  r:  r=  nvlr@  rE  rH  rJ  r  rM  rP  rS  rU  rW  rY  r[  r]  r_  ra  re  base64ri  unbase64rl  hexro  ru  rw  ry  r{  r  r  r  r  xpath_floatxpath_double
xpath_longxpath_shortr  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r  r  r  r  r  r  r  r  r  r  r  r  rT   rY   rV   <module>r5     si  Yt  
      I I I  D D D ; )   I    H   = 	 	 	 S G N
 v( 

%)IN"BF  
  

 
  % 
    
"   	
  %		C=	 	
 	 	 	 

%)IN"BF  
  

 
  % 
    
"   

  %

C=
 

 
 
 
4  $(??x ? ? 	? ?> &# &$ && & &,  &*### # c#	#
 # #L 
Bt 
Bv 
B 
B 	D 	D 	D 	D 	?D 	?F 	? 	? 	Bt 	Bv 	B 	B 	D 	D 	D 	D C C C C ?D ?F ? ? Ad Af A A Bt Bv B B Ad Af A A Bt Bv B B Jt Jv J J  R#RFCK(R R 	R R" 
? 
?$ 
?& 
? 
? 	<l 	<t 	<v 	< 	< LPE!E&+FCK&8EEIEE E LP#!#&+FCK&8#EI## #L LPF!F&+FCK&8FEIFF F DH4	4#FCK04=A44 4n  /3	D!DD l+D 	D
 D DN K\ Kd Kf K K& 9< 9D 9F 9 9$ DH??$0?=A?? ?( H\ Hd Hf H H: :> , 4 6  2 DHHH$0H=AHH H* DHII$0I=AII I*  ;tL153FFG;; ; ;| > > > > >  9< 9D 9F 9 9 L T V    <l <t <v < < 9< 9D 9F 9 9 :L :T :V : : :L :T :V : :" <l <t <v < <" A< AD AF A A$ @, @4 @6 @ @  9< 9D 9F 9 9" UL UT UV U U( > > > > >6 H H H H H> =| = = = =6 <@	#(59 : &  Rl Rt Rv R RB >B%*7; D .O\ .Od .Of .O .Ob )-?	?"&?:? ?D )-4	4"&4:4 4n  6<Z	Z
Z Z 	Z
 ..2
3Z Z ;Z Zz 48 EL ET EV E E,  15 ? ?$ ?& ? ?,  $ &  ( |    ( l t v  . L T V  . O# O$ O& O O& 
 	*
c5(
)*
c5(
)* 
|S%'	(* 	*
 * *Z s 4 6  . s 4 6  . s 4 6  . s 4 6  . 	@, 	@4 	@6 	@ 	@ CG #,/<@ 8 QU"#56JN :  L#u,-<e+,  	 @  L#u,-<e+,  	 @ 	@, 	@4 	@6 	@ 	@ :L :T :V : : 9< 9D 9F 9 9" :L :T :V : :& :L :T :V : :& :L :T :V : :& F\ Fl Ft Fv F F( :L :T :V : : 9< 9D 9F 9 9$ :L :T :V : :$ 9< 9D 9F 9 9  ? ?$ ?& ? ? ;\ ;d ;f ; ; | fck(: t  @ 
9< 
9D 
9F 
9 
9 
:L 
:T 
:V 
: 
: 9< 9D 9F 9 9 :L :T :V : : =| = = = =& =| = = = =( 9< 9D 9F 9 9 	:L 	:T 	:V 	: 	: DL DC DD DF D D$ 04 A A A A A" ;\ ;d ;f ; ; HLLL!-LAELL L> <l <t <v < <  ;\ ;d ;f ; ; SW  , 3? LP    F SW"*<"8LP : SW  , 3? LP    F SW"*<"8LP 8 l uVS[1 d f  8 ? ?$ ?& ? ?& 	=| 	= 	= 	= 	= SW  "*<"8 LP    F ;\ ;d ;f ; ; TX
#+L#9MQ : 26 5, 54 56 5 5p  H
c5(
)H\3%&H H 	H H<  \3%&  2  \3%&  $  \3%&  &&\3%&&&'\3%&''  O
c5(
)OsE)*O O 	O OB SWPP!,U":;PLPPP P> :l :t :v : :2 0>| 0>l 0>t 0>v 0> 0>f  )-	+T	+T	vs{	+T 
%$	%+T 	+T
 +T +T\ QU=
=1=:==JN== =@  $%&
 &&& FCK & !	&
 & & &R 
 	444 
4 	4
 4 4n  ')#$&'8 888 $8 FCK 	8
 vs{#8 !8 8 8 8v  ')	$W$W$W $$W 	$W
 $W $WN  .2	::: uVS[)*: 	:
 : :z Mv Ms Mt Mv M M* ? ?$ ?& ? ?" 26 C, C4 C6 C C" 59 F\ Fd Ff F F8 59[	[![.2[[ [| 
 		! " 	
  < A, A A AQW A A( CL C| C CPV C C  A, A\ Ad Af A A  !!FCK ! &#+! 	!
 ! ! !H JN$)&#+$6CG : JN$)&#+$6CG : :l :t :v : :. EI$$%c]$>B$$ $N @D33,39=33 3l QU"#56JN & GK33"8,3@D33 3l QU%%"#56%JN%% %P QU"#56JN > QU"#56JN > <@(59 D <@(59 D NR''"?3'GK'' 'T D D D D ?D ?F ? ? ?D ?F ? ? :L :T :V : :$ 9< 9D 9F 9 9$ OS$Y
$Y&|4$YHL$Y$Y $YN <l <t <v < <$ HL
%4AE 6 HL
%4AE : <l <t <v < <$ ;\ ;d ;f ; ;$ ? ?$ ?& ? ?$ =| = = = =$ :L :T :V : :$ PTUsL()U0<UIMUU U6 JNQl"#Q*6QCGQQ Q6 
:t 
:v 
: 
: @DII ,I9=II I* BL BT BV B B. A< AD AF A A. BFII".I;?II I0 !F !F !F !FH BFMM".M;?MM M:  "	LL".L L 	L
 L L^ C\ Cd Cf C C@ C\ Cd Cf C C@ 
G 
G$ 
G& 
G 
G G| G G G G2  &*"'	ddTNd $d 	d
 d dN @D)U
)U ,)U9=)U)U )UX 6: 9Dl 9Dt 9Dv 9D 9Dx  $(	44
4 <
 4 	4
 4 4n  $(	TT
T <
 T 	T
 T Tn PT$	$$),*;$<$IM$ $N PT$	$$),*;$<$IM$ $N IM!I
!I!!I)5!IBF!I!I !IH , l t v  < SW/P/P!,U":;/PLP/P/P /Pd IM+H
+H!+H)5+HBF+H+H +H\ EC EL ET EV E E6 
 	\3\3 \3 	
  6 MS M M M M M8 =| = = = =" @, @4 @6 @ @" ? ?$ ?& ? ?" ? ?$ ?& ? ?"  %) $EEE SME 	E
 E E EP >, >4 >6 > > @L @T @V @ @ ?< ?D ?F ? ? = =$ =& = = 
 = =$ =& = =   @L @T @V @ @  ?< ?D ?F ? ? = =$ =& = = @L @T @V @ @ C| C C C C ?< ?D ?F ? ? = =$ =& = =  F, F4 F6 F F( F, F4 F6 F F& E E$ E& E E& s!23
63;

 s!23
?D\SVEV?W

63;
D 
 7;1
c!
"1,#$1 ,#$1 %c 123	1
 1 1 1h 

HL(4AE  
 

 6:-1
c!
"s"# 
|S 	! c!
"	
 ,#$ ,#$ |S012 )*    
 26 "4 "V " "J  7;0
c!
"0s"#0 
|S 	!0 c!
"	0
 ,#$0 ,#$0 %c 1230 0 0 0f 

HL(4AE  
 

 6:

c!
"
s"#
 
|S 	!
 c!
"	

 ,#$
 ,#$
 |S012
 
 
  

 6: %t % % %P  7;-1CY
c!
"CYs"#CY 
|S 	!CY c!
"	CY
 ,#$CY ,#$CY %c 123CY )*CY CY CY CYL @, @4 @6 @ @$ < < < < <4 @L @T @V @ @0 ?< ?D ?F ? ?. =AO	O)O6:OO O& @, @4 @6 @ @* Dl Dt Dv D D* EI--"3=1->B-- -` ? ?$ ?& ? ?6 F, F4 F6 F F$ DH	$(=A 6 BFEE".E;?EE EB EIDODO"1DO>BDODO DON BFDD".D;?DD D> C C$ C& C C4 ;? G< GD GF G G8 CG O< OD OF O O: BFGG".G;?GG G> 
 	,H,H	,H ,H 	,H
 ,H ,H^ BFGG".G;?GG G6 BFFF".F;?FF F> @l @t @v @ @* RVGG ,G2>GKOGG GB DHHH$0H=AHH H8 F, F4 F6 F F6 SW0
0*03?0LP0 0f MO M, M4 M M> >, >4 > >. 'l 't 'v ' 'T >BC	C*C7;CC C: BF I, I4 I6 I I: 15SS*.SS S< RV L	 L) L2> LKO L L  LF 
 +/+M	+M	+M +M ,'	+M
 +M +M +M\ RV#J	#J)#J2>#JKO#J#J #JT :>QQ&Q37QQ Q* :>MM&M37MM M* :>OO&O37OO O* 8/ 8d 8f 8 8& < D F  $ |    & l t v  & L T V  &     ( |    & >l >t >v > >( ?| ? ? ? ?" =\ =d =f = =" @ @ @ @ @" =\ =d =f = =" FJ#CM2?C 8 FJ#CM2?C @   $	0K0K}0K C=0K 	0K
 0K 0Kf 	 ?| ? ? ? ?" =\ =d =f = =$ @ @ @ @ @" ?| ? ? ? ?( =\ =d =f = =" Fl Ft Fv F F" Fl Ft Fv F F" E\ Ed Ef E E" BF"3-;? 4 > > > > >& =| = = = =  ? ?$ ?& ? ? @, @4 @6 @ @. <l <t <v < <  >BJ	J*J7;JJ J$ A\ Ad Af A A@  ./	2E	2E	2E c)*2E 	2E
 2E 2Ej C, Cl Ct Cv C C  >
c!
">
c!
"> > 	> >B 
 JN55'65CG55 5p 
 	  	
  D  V
|
V&		V V V Vr < < < <: 7D 7F 7 7@ ?D ?F ? ?@ =$ =& = =" =$ =& = =B  /3))) O,) 	)
 ) ) )X  :>))) E&+"567) 	)
 ) ) )X CG#'<@ 0 CG#'<@ 0 KO+/DH 0 ;U3$% ;$ ;& ; ;> N N$ N& N N: 7; ?| ? ? ? ?  48 <L <T <V < <   	!!! ! 	!
 ! !H :>VV37V1V V4 :>YY37Y4Y Y6 #{
 '+,004$(;?7;>B$(15 $8<(,!)-483{

8
{
 (#{
 $x.)	{

 5hsm+,
-{
 {
 SM{
 d5eCHo!5678{
 tE#z/234{
 {
 {
 :;{
 {
 SM{
 tCH~.{
  !{
" #{
$ %{
& #+49"5'{
( d38n%){
* +{
, c]-{
. "#/{
0 "$sCx.11{
2 3{
6 	 1 1127{
 {
| "&r
 -104$(;?7;>B158<(,!)-48/r
hr
 T#Y0EEFr
 $x.)	r

 5hsm+,
-r
 r
 SMr
 d5eCHo!5678r
 tE#z/234r
 r
 r
 :;r
 r
 tCH~.r
 r
  !r
" #+49"5#r
$ d38n%%r
& 'r
( c])r
* "#+r
, "$sCx.1-r
. /r
2 #Y%6%6673r
 r
j %)t
 '+,004$(;?7;>B158<(,!)-48+t
fkk"t
 (#t
 $x.)	t

 5hsm+,
-t
 t
 SMt
 d5eCHo!5678t
 tE#z/234t
 t
 t
 :;t
 t
 tCH~.t
 t
  #+49"5!t
" d38n%#t
$ c]%t
& "#'t
( "$sCx.1)t
* +t
. '):)::;/t
 t
n #g '+,004$(;?7;>B$(15 $8<(,!/g
8
g (#g $x.)	g
 5hsm+,
-g g SMg d5eCHo!5678g tE#z/234g g g :;g g SMg tCH~.g  !g" #g$ %g& #+49"5'g( d38n%)g* +g, c]-g. /g2 	 1 1123g gT,d ,HSM ,X ,^ "&F -1'+04$(;?7;>B158<(,$(!/FhF T#Y0EEFF $x.)	F
 $s)$F 5hsm+,
-F F SMF d5eCHo!5678F tE#z/234F F F :;F F tCH~.F  !F" #F$ #+49"5%F& d38n%'F( )F* SM+F, c]-F. /F2 #Y%6%6673F FR FJ  s  ?  t  v    F  hsm+,  	
 ; B # $ (  .  VVV V 	V V: JC JD JH J JF &*
o%& c] **	
  , #c
 '+,004$(;?7;6:15IP $8<(,!)-48/c

8
c
 (#c
 $x.)	c

 5hsm+,
-c
 c
 SMc
 d5eCHo!5678c
 tE#z/234c
 c
 c
 23c
 c
 tCH~.c
 EFc
  !c
" #c
$ #+49"5%c
& d38n%'c
( c])c
* +c
, "#-c
. "$sCx.1/c
2 ?I---.3c
 c
V #C= 
  @ 	 	
 0  ,0#C=  	 8  """ " "L 
	
" 
"	

 GK  "8, @D    F KO#03DH D " !!"&"&!%[C=[sm[ SM[ C=	[
 3-[ C=[ c][ c][ 3-[ 3-[ #[ 3-[ 3-[ [ [ [|  e $(%))-	QL!Q\"Q !Q 	Q
 Q 	
Qh  d #'$(#'#')-S
<
 SL!S <
 S <
 	S
 !S S S 	
Sl wF 15R
R)-RR R& wF 15R
R)-RR R( ;\ ;d ;f ; ; ;\ ;d ;f ; ; ;\ ;d ;f ; ; @, @4 @6 @ @ Il It Iv I I JL JT JV J J  7;J#J04JJ J  :L :T :V : : E< E\ Ed Ef E E" A| A A$ A& A A   D F  ,  9=	(E(E((E )1(E 	(E
 (E (EV  9=	)E)E()E )1)E 	)E
 )E )EX BL BT BV B B   	  	
  B D D, D4 D6 D D  B B, B4 B6 B B" E, E< ED EF E E Il I| I IPV I I" @| @ @ @ @ @$ E, E< ED EF E E$ I I I$ I& I I I I I$ I& I I  C C C$ C& C C BF"3-;? ,  &'"	#Q#Qc]#Q sm#Q 	#Q
 #Q #QL 
 GKXX'}X@DXX X>   , c $      8<	+P+P+P 5l!234+P 	+P
 +P +P\ | S T   
 	V
U

V#u*V 
|S%'	(V 	V V> NR
5sE12
3GK : "| "3 "4 "6 " "J l # $ &  : | 3 4 6  : l # $ &  : < s t v  > * )l$ $
[ @D),9= 8 GO G G G G: I< ID IF I I( I< ID IF I I& I I I I I@ IL IT IV I I( IL IT IV I I( Il It Iv I I& I< ID IF I I( IL IT IV I I( I\ Id If I I( I< ID IF I I( I< ID IF I I( Il It Iv I I( I I I I I( I< ID IF I I(  AAA A 	A AH  e#V+,e4:&e e 	e eP  "E
!E

6
E
 E
 	E
 E
P  O

O
fd3i/0O
 O

 O
 O
d R- R$ R& R R<  9
9(9 9 	9 9x  d
d
d
 d

 d
 d
N  aR
aRaR 	aR aRH  wXwXwX 	wX wXt 

 (,&*#' tn d^	
 4.    
 


 (,&*#'			 	 tn		
 d^	 4.	 	 	  
	  "'+&*#'nnn 6
n tn	n
 d^n 4.n n n nb  III I 	I IX  '+Z

Z
c#Z
 Z
 	Z
 Z
z 
 	:
:': (: 	:
 : :rY   