Kang-Won Lee

105 papers A* 14A 5B 21C 1Journal 29Unranked 34
YearRankTypeTitle / Venue / Authors
2026 J jnl
CoRR
Seongyong Kim, Junhyeon Cho, Kang-Won Lee, Soo-Chul Lim
2024 J jnl
CoRR
Kang-Won Lee, Yuzhe Qin, Xiaolong Wang, Soo-Chul Lim
2024 J jnl
IEEE Trans. Intell. Transp. Syst.
Kang-Won Lee, Dae-Kwan Ko, Yong-Jun Kim, Jee-Hwan Ryu, Soo-Chul Lim
2024 A* conf
ICRA
Ying Yuan, Haichuan Che, Yuzhe Qin, Binghao Huang, Zhao-Heng Yin, Kang-Won Lee, Yi Wu, Soo-Chul Lim, Xiaolong Wang
2023 J jnl
CoRR
Ying Yuan, Haichuan Che, Yuzhe Qin, Binghao Huang, Zhao-Heng Yin, Kang-Won Lee, Yi Wu, Soo-Chul Lim, Xiaolong Wang
2023 J jnl
Expert Syst. Appl.
Dae-Kwan Ko, Kang-Won Lee, Dong Han Lee, Soo-Chul Lim
2021 J jnl
IEEE Robotics Autom. Lett.
Kang-Won Lee, Dae-Kwan Ko, Soo-Chul Lim
2020 J jnl
IEEE Access
Myoungwon Oh, Sujin Ha, Jin Hyuk Yoon, Kang-Won Lee, Yongseok Son, Heon Young Yeom
2018 A conf
ICDCS
Myoungwon Oh, Sejin Park, Jungyeon Yoon, Sangjae Kim, Kang-Won Lee, Sage A. Weil, Heon Y. Yeom, Myoungsoo Jung
2018 A conf
IPDPS
Myoungwon Oh, Sejin Park, Jugwan Eom, Seungmin Kim, Sangjae Kim, Kang-Won Lee, Heon Y. Yeom
2016 J jnl
IACR Cryptol. ePrint Arch.
Jung Hee Cheon, Heewon Chung, Myungsun Kim, Kang-Won Lee
2015 J jnl
SIAM J. Comput.
Nikhil Bansal, Kang-Won Lee, Viswanath Nagarajan, Murtaza Zafer
2014 A* conf
ICDE
Bo Zong, Ramya Raghavendra, Mudhakar Srivatsa, Xifeng Yan, Ambuj K. Singh, Kang-Won Lee
2014 A* conf
INFOCOM
Yeon-Sup Lim, Yung-Chih Chen, Erich M. Nahum, Don Towsley, Kang-Won Lee
2013 J jnl
Int. J. Commun. Networks Distributed Syst.
Suk-Bok Lee, Ho Yin Starsky Wong, Kang-Won Lee, Songwu Lu
2013 B conf
IM
Bong Jun Ko, Sisi Liu, Murtaza Zafer, Ho Yin Starsky Wong, Kang-Won Lee
2013 conf
IEEE CLOUD
Yuting Ji, Lang Tong, Ting He, Jian Tan, Kang-Won Lee, Li Zhang
2013 J jnl
IEEE Trans. Parallel Distributed Syst.
Uichin Lee, Seung-Hoon Lee, Kang-Won Lee, Mario Gerla
2013 B conf
SECON
Starsky H. Y. Wong, Ramya Raghavendra, Yang Song, Kang-Won Lee
2012 J jnl
IEICE Trans. Commun.
Won-Kyeong Seo, Kang-Won Lee, Jae-In Choi, You Ze Cho
2012 conf
ICN
Bong Jun Ko, Vasileios Pappas, Ramya Raghavendra, Yang Song, Raheleh B. Dilmaghani, Kang-Won Lee, Dinesh C. Verma
2012 conf
HotSDN@SIGCOMM
Ramya Raghavendra, Jorge Lobo, Kang-Won Lee
2012 conf
ACSCC
Qing Wang, Ting He, Kwang-Cheng Chen, Junsong Wang, Bongjun Ko, Yonghua Lin, Kang-Won Lee
2012 conf
IEEE CLOUD
Murtaza Zafer, Yang Song, Kang-Won Lee
2012 A* conf
INFOCOM
Yang Song, Murtaza Zafer, Kang-Won Lee
2012 conf
IEEE CLOUD
Ting He, Shiyao Chen, Hyoil Kim, Lang Tong, Kang-Won Lee
2012 A* conf
INFOCOM
Ting He, Shiyao Chen, Hyoil Kim, Lang Tong, Kang-Won Lee
2011 A* conf
INFOCOM
Vivek Shrivastava, Petros Zerfos, Kang-Won Lee, Hani Jamjoom, Yew-Huey Liu, Suman Banerjee
2011 A* conf
INFOCOM
Suk-Bok Lee, Starsky H. Y. Wong, Kang-Won Lee, Songwu Lu
2011 B conf
MobiHoc
Ting He, Ananthram Swami, Kang-Won Lee
2011 conf
POLICY
Bong Jun Ko, Starsky H. Y. Wong, Kang-Won Lee, Chi-Kin Chau
2011 B conf
MASS
Berk Birand, Murtaza Zafer, Gil Zussman, Kang-Won Lee
2011 conf
Integrated Network Management
Starsky H. Y. Wong, Chi-Kin Chau, Kang-Won Lee
2011 A* conf
PODC
Nikhil Bansal, Kang-Won Lee, Viswanath Nagarajan, Murtaza Zafer
2011 A* conf
MobiCom
Yang Song, Starsky H. Y. Wong, Kang-Won Lee
2011 J jnl
J. Comput. Sci. Eng.
Kyung Dong Ryu, Kang-Won Lee, Jihie Kim
2011 conf
IPDPS Workshops
Shiyao Chen, Ting He, Ho Yin Starsky Wong, Kang-Won Lee, Lang Tong
2011 conf
MILCOM
Liang Ma, Ting He, Ananthram Swami, Kang-Won Lee, Kin K. Leung
2010 B conf
WCNC
Chi Harold Liu, Ting He, Kang-Won Lee, Kin K. Leung, Ananthram Swami
2010 B conf
MobiHoc
Ting He, Kang-Won Lee, Ananthram Swami
2010 J jnl
Int. J. Commun. Syst.
Kang-Won Lee, Won-Kyeong Seo, You Ze Cho, Jong-Woo Kim, Jin-Soo Park, Byoung-Sub Moon
2010 B conf
MASS
Seung-Hoon Lee, Starsky H. Y. Wong, Chi-Kin Chau, Kang-Won Lee, Jon Crowcroft, Mario Gerla
2010 J jnl
Comput. J.
Dinesh C. Verma, Bong Jun Ko, Petros Zerfos, Kang-Won Lee, Ting He, Matthew Duggan, Kristian D. Stewart, Ananthram Swami, Nikoletta Sofra
2010 B conf
SECON
Ting He, Kang-Won Lee, Nikoletta Sofra, Kin K. Leung
2009 J jnl
Ad Hoc Networks
Uichin Lee, Eugenio Magistretti, Mario Gerla, Paolo Bellavista, Pietro Liò, Kang-Won Lee
2009 conf
CHANTS@MobiCom
Uichin Lee, Soon-young Oh, Kang-Won Lee, Mario Gerla
2008 B conf
SECON
Seung-Hoon Lee, Uichin Lee, Kang-Won Lee, Mario Gerla
2008 A conf
ICDCS
Kang-Won Lee, Vasileios Pappas, Asser N. Tantawi
2008 J jnl
IBM J. Res. Dev.
Sandeep Gopisetty, Sandip Agarwala, Eric Butler, Divyesh Jadav, Stefan Jaquet, Madhukar R. Korupolu, Ramani Routray, Prasenjit Sarkar, Aameek Singh, Miriam Sivan-Zimet, Chung-Hao Tan, Sandeep Uttamchandani, David Merbach, Sumant Padbidri, Andreas Dieberger, Eben M. Haber, Eser Kandogan, Cheryl A. Kieliszewski, Dakshi Agrawal, Murthy V. Devarakonda, Kang-Won Lee, Kostas Magoutis, Dinesh C. Verma, Norbert G. Vogl
2008 B conf
WiMob
Kang-Won Lee, Won-Kyeong Seo, Dong-Won Kum, You Ze Cho
2008 conf
POLICY
Chi-Kin Chau, Jon Crowcroft, Kang-Won Lee, Starsky H. Y. Wong
2008 B conf
ICNP
Uichin Lee, Soon-young Oh, Kang-Won Lee, Mario Gerla
2008 B conf
MASS
Alina Beygelzimer, Aaron Kershenbaum, Kang-Won Lee, Vasileios Pappas
2007 conf
MOBIWAC
Yang Li, Kang-Won Lee, Ju-Eun Kang, You Ze Cho
2007 conf
BIOWIRE
Uichin Lee, Eugenio Magistretti, Mario Gerla, Paolo Bellavista, Pietro Liò, Kang-Won Lee
2007 conf
ICOIN
Sung-Hyup Lee, Kang-Won Lee, You Ze Cho
2007 A conf
ICWS
Sang Jeong Lee, Kyung Dong Ryu, Kang-Won Lee, Jong-Deok Choi
2007 J jnl
Comput. Networks
Kang-Won Lee, Suresh Chari, Anees Shaikh, Sambit Sahu, Pau-Chen Cheng
2007 conf
Integrated Network Management
Dakshi Agrawal, Seraphin B. Calo, Kang-Won Lee, Jorge Lobo
2007 conf
Integrated Network Management
Dakshi Agrawal, Mandis Beigi, Chatschik Bisdikian, Kang-Won Lee
2007 conf
ICOIN
Young-Soo Choi, Kang-Won Lee, You Ze Cho
2006 B conf
GLOBECOM
Sang Jeong Lee, Kang-Won Lee, Kyung Dong Ryu, Jong-Deok Choi, Dinesh C. Verma
2006 conf
WWIC
Yoon-Young An, Kang-Won Lee, Dong-Won Kum, Sung-Hyup Lee, You Ze Cho, Byung Ho Yae, Woo Young Jung
2006 conf
ICOIN
Hee-Dong Park, Kang-Won Lee, Sung-Hyup Lee, You Ze Cho, Yoon-Young An, Do-Hyeon Kim
2006 B conf
Networking
Hee-Dong Park, Dong-Won Kum, Yong-Ha Kwon, Kang-Won Lee, You Ze Cho
2006 conf
AINA (2)
Yoon-Young An, Byung Ho Yae, Kang-Won Lee, You Ze Cho, Woo Young Jung
2006 conf
USENIX ATC, General Track
KyoungSoo Park, Vivek S. Pai, Kang-Won Lee, Seraphin B. Calo
2006 J jnl
J. Inf. Sci. Eng.
Keun-Hee Han, Il-Gon Kim, Kang-Won Lee, Jin-Young Choi, Sang-Hun Jeon
2005 conf
ICOIN
Hee-Dong Park, Jun-Woo Kim, Kang-Won Lee, You Ze Cho, Do-Hyeon Kim, Bong-Kwan Cho, Kyu-Hyung Choi
2005 J jnl
Comput. Networks
Kang-Won Lee, Bong-Jun Ko, Seraphin B. Calo
2005 J jnl
Comput. Artif. Intell.
Keun-Hee Han, Il-Gon Kim, Kang-Won Lee, Ji-Yeon Choi, Sang-Hun Jeon
2005 conf
ICCSA (1)
Han-Kyu Ryu, Do-Hyeon Kim, You Ze Cho, Kang-Won Lee, Hee-Dong Park
2005 J jnl
Comput. Networks
Kang-Won Lee, Young-Bae Ko, Thyaga Nandagopal
2005 conf
IWDC
Hee-Dong Park, Yong-Ha Kwon, Kang-Won Lee, Young-Soo Choi, Sung-Hyup Lee, You Ze Cho
2005 conf
POLICY
Dakshi Agrawal, James Giles, Kang-Won Lee, Jorge Lobo
2005 conf
Integrated Network Management
Dakshi Agrawal, Seraphin B. Calo, James Giles, Kang-Won Lee, Dinesh C. Verma
2005 J jnl
IEEE Commun. Mag.
Dakshi Agrawal, Kang-Won Lee, Jorge Lobo
2005 conf
ICC
Kang-Won Lee, Suresh Chari, Anees Shaikh, Sambit Sahu, Pau-Chen Cheng
2005 conf
MMNS
Hee-Dong Park, Yong-Ha Kwon, Kang-Won Lee, Sung-Hyup Lee, Young-Soo Choi, Yang Li, You Ze Cho
2004 B conf
NOSSDAV
Kang-Won Lee, Bong-Jun Ko, Seraphin B. Calo
2004 B conf
CCGRID
Lintao Liu, Kyung Dong Ryu, Kang-Won Lee
2004 conf
PCM (2)
Young-Soo Choi, Kang-Won Lee, You Ze Cho
2004 conf
POLICY
Dakshi Agrawal, James Giles, Kang-Won Lee, Kaladhar Voruganti, Khalid Filali-Adib
2004 J jnl
IBM Syst. J.
Karen Appleby, Seraphin B. Calo, James Giles, Kang-Won Lee
2004 J jnl
Comput. Networks
Thyagarajan Nandagopal, Kang-Won Lee, Jia-Ru Li, Vaduvur Bharghavan
2004 B conf
GLOBECOM
Lintao Liu, Kyung Dong Ryu, Kang-Won Lee
2003 B conf
GLOBECOM
Young-Bae Ko, Kang-Won Lee, Thyaga Nandagopal
2003 A conf
ICDCS
Bong-Jun Ko, Kang-Won Lee, Khalil Amiri, Seraphin B. Calo
2002 J jnl
Multim. Tools Appl.
Songwu Lu, Kang-Won Lee, Vaduvur Bharghavan
2002 A* conf
SIGMETRICS
Kang-Won Lee, Khalil Amiri, Sambit Sahu, Chitra Venkatramani
2002 B conf
NOSSDAV
Chitra Venkatramani, Olivier Verscheure, Pascal Frossard, Kang-Won Lee
2001 B conf
GLOBECOM
Kang-Won Lee, Tae-Eun Kim, Vaduvur Bharghavan
2001 J jnl
IEEE Trans. Multim.
Rohit Puri, Kang-Won Lee, Kannan Ramchandran, Vaduvur Bharghavan
2001 J jnl
Signal Process. Image Commun.
Rohit Puri, Kannan Ramchandran, Kang-Won Lee, Vaduvur Bharghavan
2000 A* conf
INFOCOM
Kang-Won Lee, Rohit Puri, Tae-Eun Kim, Kannan Ramchandran, Vaduvur Bharghavan
2000 A* conf
ACM Multimedia
Kang-Won Lee, Sungwon Ha, Jia-Ru Li, Vaduvur Bharghavan
2000
Kang-Won Lee
1999 B conf
ICCCN
Sungwon Ha, Kang-Won Lee, Vaduvur Bharghavan
1999 A* conf
SIGMETRICS
Narayanan Venkitaraman, Tae-Eun Kim, Kang-Won Lee
1999 A* conf
INFOCOM
Kang-Won Lee, Sungwon Ha, Vaduvur Bharghavan
1999 conf
Networked Group Communication
Tae-Eun Kim, Raghupathy Sivakumar, Kang-Won Lee, Vaduvur Bharghavan
1999 conf
ICC
Kang-Won Lee, Vaduvur Bharghavan
1998 C conf
ISCC
Sungwon Ha, Kang-Won Lee, Vaduvur Bharghavan
1998 J jnl
IEEE Wirel. Commun.
Vaduvur Bharghavan, Kang-Won Lee, Songwu Lu, Sungwon Ha, Jia-Ru Li, Dane Dwyer
1998 conf
ICC
Kang-Won Lee, Matthew Cheng, Li-Fung Chang
redb/extractors/database_exporters.py
← Index redb/extractors/database_exporters.py python
from abc import ABC, abstractmethod
from datetime import datetime, timezone
from dataclasses import asdict
import hashlib
import json
import inspect
from typing import Any, Dict, List, Union
from redb import settings
import traceback
from contextlib import contextmanager

class DatabaseExporter(ABC):
    @abstractmethod
    def export(self, data: Any, **kwargs) -> bool:
        """Export data to the database"""
        pass

class ElasticsearchExporter(DatabaseExporter):
    def __init__(self, logger: Any, index_prefix: str):
        self.client = settings.get_elasticsearch_client()
        self.index_prefix = index_prefix
        self.log = logger

    def export(self, data: Any, **kwargs) -> bool:
        self.log.debug(inspect.currentframe().f_code.co_name)
        if not isinstance(data, list):
            data = [data]
            
        now_t = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S")
        index = kwargs.get('index')
        tag = kwargs.get('tag')
        hashes = kwargs.get('hashes')
        
        for dataclass_ in data:
            try:
                # Convert dataclass to dict and filter out None values
                document = {k: v for k, v in asdict(dataclass_).items() if v is not None}
                
                if tag:
                    document["tag"] = tag
                document |= hashes
                document["timestamp_utc"] = now_t
                document["known_benign"] = kwargs.get('known_benign', False)
                document["known_malicious"] = kwargs.get('known_malicious', False)

                if "_id" in document:
                    tmp_id = document.pop("_id") + document["sha256"]
                    _id = hashlib.sha256(tmp_id.encode()).hexdigest()
                else:
                    _id = document["sha256"]

                doc_dump = json.dumps(document)
                self.client.index(index=index, id=_id, document=doc_dump)
                
            except Exception as e:
                self.log.error(f"Failed to export to Elasticsearch: {e}")
                return False
                
        return True

class PrintExporter(DatabaseExporter):
    """Exporter that prints results instead of uploading to database (for dry-run mode)"""
    def __init__(self, logger: Any, index_prefix: str):
        self.index_prefix = index_prefix
        self.log = logger
        self.log.debug(f"PrintExporter initialized with index_prefix: {index_prefix}")

    def export(self, data: Any, **kwargs) -> bool:
        try:
            import json
            from dataclasses import asdict, is_dataclass

            self.log.debug(f"PrintExporter.export called with data type: {type(data)}")

            if data is None:
                self.log.debug("PrintExporter.export: data is None, returning True")
                return True

            if not isinstance(data, list):
                data = [data]

            for i, item in enumerate(data):
                if is_dataclass(item) and not isinstance(item, type):
                    # Convert dataclass instance to dict
                    try:
                        item_dict = asdict(item)
                        print(json.dumps(item_dict, indent=2, default=str))
                    except Exception as e:
                        self.log.error(f"PrintExporter.export: Error converting dataclass: {e}")
                        print(str(item))
                elif isinstance(item, dict):
                    # Already a dict, print as JSON
                    print(json.dumps(item, indent=2, default=str))
                else:
                    # Fallback for other types
                    print(json.dumps(item, indent=2, default=str) if not isinstance(item, str) else item)

            self.log.debug("PrintExporter.export: completed successfully")
            return True
        except Exception as e:
            self.log.error(f"PrintExporter.export: Failed to print data: {e}")
            return False


class ClickHouseExporter(DatabaseExporter):
    def __init__(self, logger: Any, index_prefix: str, client=None):
        self.index_prefix = index_prefix
        self.log = logger
        self.client = client

    @contextmanager
    def clickhouse_connection(self):
        client = settings.create_clickhouse_client()
        try:
            yield client
        finally:
            try:
                client.close()
            except:
                pass
    # def export(self, data: Any, **kwargs) -> bool:
    #     try:
    #         # Handle multi-table export case
    #         # if isinstance(data, dict) and 'multi_table' in data:
    #         #     for table_name, table_data in data.items():
    #         #         if table_name != 'multi_table' and isinstance(table_data, dict) and 'table' in table_data:
    #         #             self.log.debug(f"Exporting to table: {table_data['table']}")
    #         #             self.log.debug(f"Column names: {table_data['column_names']}")
    #         #             self.log.debug(f"Column types: {table_data['column_type_names']}")
    #         #             self.log.debug(f"Data sample: {table_data['data'][0] if table_data['data'] else 'No data'}")
                        
    #         #             try:
    #         #                 result = self.client.insert(
    #         #                     table_data['table'],
    #         #                     table_data['data'],
    #         #                     column_names=table_data['column_names'],
    #         #                     column_type_names=table_data['column_type_names']
    #         #                 )
    #         #                 if not result:
    #         #                     self.log.error(f"Failed to insert into table {table_data['table']}")
    #         #                     return False
    #         #             except Exception as e:
    #         #                 self.log.error(f"Error inserting into table {table_data['table']}: {e}")
    #         #                 self.log.error(f"Data that caused error: {table_data['data']}")
    #         #                 return False
    #         #     return True

    #         if isinstance(data, dict) and 'multi_table' in data:
    #             for table_name, table_data in data.items():
    #                 if table_name != 'multi_table' and isinstance(table_data, dict) and 'table' in table_data:
    #                     self.log.debug(f"Exporting to table: {table_data['table']}")
                        
    #                     # Validate each row before insert
    #                     for row in table_data['data']:
    #                         for val, col_name, col_type in zip(row, table_data['column_names'], 
    #                                                         table_data['column_type_names']):
    #                             # Check for empty strings
    #                             if isinstance(val, str) and not val:
    #                                 self.log.error(f"Empty string found for column {col_name}")
    #                                 raise ValueError(f"Empty string not allowed for column {col_name}")
                                
    #                             # Log all string values for certificate_serial_number
    #                             if col_name == 'certificate_serial_number':
    #                                 self.log.debug(f"Serial number value: '{val}', type: {type(val)}, "
    #                                             f"repr: {repr(val)}")
                        
    #                     try:
    #                         result = self.client.insert(
    #                             table_data['table'],
    #                             table_data['data'],
    #                             column_names=table_data['column_names'],
    #                             column_type_names=table_data['column_type_names']
    #                         )
    #                         if not result:
    #                             self.log.error(f"Failed to insert into table {table_data['table']}")
    #                             return False
    #                     except Exception as e:
    #                         self.log.error(f"Error inserting into table {table_data['table']}: {e}")
    #                         self.log.error(f"Data that caused error: {table_data['data']}")
    #                         return False
    #             return True

    #         # Handle single table case
    #         table = kwargs.get('table')
    #         if not table:
    #             raise ValueError("Table name must be provided for ClickHouse export")
            
    #         # Unpack the tuple returned by prepare_export_data
    #         if isinstance(data, tuple):
    #             if len(data) != 3:
    #                 raise ValueError("Data tuple must contain exactly 3 elements: (data, column_names, column_type_names)")
    #             insert_data, column_names, column_type_names = data
    #         else:
    #             # Use provided column names and types from kwargs
    #             insert_data = data
    #             column_names = kwargs.get('column_names')
    #             column_type_names = kwargs.get('column_type_names')
                
    #         if not (column_names and column_type_names):
    #             raise ValueError("column_names and column_type_names must be provided")

    #         # Ensure data is in list format for batch insert
    #         if not isinstance(insert_data, list):
    #             insert_data = [insert_data]
                
    #         self.client.insert(
    #             table,
    #             insert_data,
    #             column_names=column_names,
    #             column_type_names=column_type_names
    #         )
    #         return True
            
    #     except Exception as e:
    #         self.log.error(f"Failed to export to ClickHouse: {e}")
    #         return False

    def get_client(self):
        """Get existing client or create new one if needed"""
        if self.client:
            return self.client
        try:
            return settings.create_clickhouse_client() 
        except Exception as e:
            self.log.error(f"Failed to create ClickHouse client: {e}")
            return None
            
    # WORKING SIMPLE VERSION
    def export(self, data: Any, **kwargs) -> bool:
        try:
            # # Handle multi-table export case
            # # if isinstance(data, dict) and 'multi_table' in data:
            # #     for table_data in data.values():
            # #         if isinstance(table_data, dict) and 'table' in table_data:
            # #             result = self.client.insert(
            # #                 table_data['table'],
            # #                 table_data['data'],
            # #                 column_names=table_data['column_names'],
            # #                 column_type_names=table_data['column_type_names']
            # #             )
            # #             if not result:  # If any insert fails, return False
            # #                 return False
            # #     return True
            # if isinstance(data, dict) and 'multi_table' in data:
            #     for key, table_data in data.items():
            #         if key != 'multi_table' and isinstance(table_data, dict) and 'table' in table_data:
            #             # Add type hints
            #             typed_data = []
            #             for row in table_data['data']:
            #                 typed_row = []
            #                 for val, type_name in zip(row, table_data['column_type_names']):
            #                     if isinstance(val, str) and not val:
            #                         val = 'UNKNOWN'
            #                     if type_name == 'String' or 'LowCardinality(String)' in type_name:
            #                         val = str(val) if val is not None else 'UNKNOWN'
            #                     typed_row.append(val)
            #                 typed_data.append(typed_row)
                        
            #             table_data['data'] = typed_data
                        
            #             result = self.client.insert(
            #                 table_data['table'],
            #                 table_data['data'],
            #                 column_names=table_data['column_names'],
            #                 column_type_names=table_data['column_type_names'],
            #                 settings={'input_format_values_interpret_expressions': 0}  # Disable type inference
            #             )
            #             if not result:
            #                 return False
            #         return True

            # Get a new client connection for this export operation
            with self.clickhouse_connection() as client:
                if not client:
                    return False

                # LAST WORKING VERSION
                if isinstance(data, dict) and 'multi_table' in data:
                    for key, table_data in data.items():
                        if key != 'multi_table' and isinstance(table_data, dict) and 'table' in table_data:
                            # Debug logging
                            self.log.debug(f"Processing table: {table_data['table']}")
                            self.log.debug(f"Column names: {table_data['column_names']}")
                            self.log.debug(f"Column types: {table_data['column_type_names']}")
                            
                            typed_data = []
                            for row_idx, row in enumerate(table_data['data']):
                                typed_row = []
                                for val_idx, (val, type_name, col_name) in enumerate(
                                    zip(row, table_data['column_type_names'], table_data['column_names'])
                                ):
                                    try:
                                        # Handle different types
                                        if val is None:
                                            if 'Nullable' in type_name:
                                                val = None  # Keep None for Nullable columns
                                            elif 'Array' in type_name:
                                                val = []
                                            elif 'Int' in type_name or 'UInt' in type_name:
                                                val = 0
                                            elif 'FixedString(16)' in type_name:
                                                val = b'\x00' * 16  # Binary FixedString
                                            elif 'String' in type_name or 'LowCardinality' in type_name:
                                                val = 'UNKNOWN'
                                            elif 'DateTime' in type_name:
                                                val = datetime.now(timezone.utc)
                                            elif 'Boolean' in type_name:
                                                val = False
                                            else:
                                                self.log.error(f"Unhandled type {type_name} for null value")
                                                val = 'UNKNOWN'
                                        
                                        # Log problematic values
                                        if isinstance(val, str) and not val.strip():
                                            self.log.warning(f"Empty string found in table {table_data['table']}, "
                                                        f"column {col_name}, row {row_idx}")
                                        
                                        # Ensure array types are always lists
                                        if 'Array' in type_name and not isinstance(val, list):
                                            val = [val]
                                        
                                        typed_row.append(val)
                                    except Exception as e:
                                        self.log.error(f"Error processing value in table {table_data['table']}, "
                                                    f"column {col_name} ({type_name}), "
                                                    f"row {row_idx}, value: {repr(val)}")
                                        raise
                                        
                                typed_data.append(typed_row)
                            
                            table_data['data'] = typed_data

                            # Skip insert if there is nothing to insert
                            if not typed_data:
                                self.log.debug(f"No data to insert for table {table_data['table']}, skipping.")
                                continue

                            # Debug log the first row of data
                            self.log.debug(f"Sample row for {table_data['table']}: {typed_data[0]}")

                            result = client.insert(
                                table_data['table'],
                                table_data['data'],
                                column_names=table_data['column_names'],
                                column_type_names=table_data['column_type_names'],
                                settings={'input_format_values_interpret_expressions': 0}
                            )
                            if not result:
                                self.log.error(f"Insert failed for table {table_data['table']}")
                                return False
                    return True

                # Handle single table case
                table = kwargs.get('table')
                if not table:
                    raise ValueError("Table name must be provided for ClickHouse export")
                
                # Unpack the tuple returned by prepare_export_data
                if isinstance(data, tuple):
                    if len(data) != 3:
                        raise ValueError("Data tuple must contain exactly 3 elements: (data, column_names, column_type_names)")
                    insert_data, column_names, column_type_names = data
                else:
                    # Use provided column names and types from kwargs
                    insert_data = data
                    column_names = kwargs.get('column_names')
                    column_type_names = kwargs.get('column_type_names')
                    
                if not (column_names and column_type_names):
                    raise ValueError("column_names and column_type_names must be provided")

                # Ensure data is in list format for batch insert
                if not isinstance(insert_data, list):
                    insert_data = [insert_data]

                # Skip insert if there is nothing to insert
                if not insert_data:
                    self.log.debug(f"No data to insert for table {table}, skipping.")
                    return True

                client.insert(
                    table,
                    insert_data,
                    column_names=column_names,
                    column_type_names=column_type_names,
                    settings={'input_format_values_interpret_expressions': 0}  # Disable type inference
                )
                return True

        except TypeError as e:
            # Get the actual value causing the error from the exception traceback
            import sys
            exc_type, exc_value, exc_traceback = sys.exc_info()
            
            # Walk through the traceback to find the frame with the problematic value
            current = exc_traceback
            while current:
                if 'string.py' in current.tb_frame.f_code.co_filename and '_data_size' in current.tb_frame.f_code.co_name:
                    locals_dict = current.tb_frame.f_locals
                    problematic_value = locals_dict.get('x')
                    self.log.error(f"TypeError with value: {problematic_value} (type: {type(problematic_value)})")
                    self.log.error(f"Full locals at error: {locals_dict}")
                    break
                current = current.tb_next
            
            self.log.error(f"Failed to export to ClickHouse: {e}")
            self.log.error("Full traceback:")
            self.log.error(traceback.format_exc())
            return False
        except Exception as e:
            self.log.error(f"Failed to export to ClickHouse: {e}")
            self.log.error(traceback.format_exc())
            return False
        finally:
            # Only close if we created a new client
            if client and client != self.client:
                # Close the client connection
                try:
                    client.close()
                except:
                    pass