Walter Vogler

158 papers A* 8A 4B 23C 2Journal 76Unranked 41
YearRankTypeTitle / Venue / Authors
2022 J jnl
Acta Informatica
Ayleen Schinko, Walter Vogler, Johannes Gareis, N. Tri Nguyen, Gerald Lüttgen
2021 J jnl
Acta Informatica
Walter Vogler, Gerald Lüttgen
2021 J jnl
Fundam. Informaticae
Antti Valmari, Walter Vogler
2020 J jnl
Acta Informatica
Walter Vogler, Gerald Lüttgen
2019 B conf
Petri Nets
Vitali Schneider, Walter Vogler
2018 J jnl
Int. J. Softw. Tools Technol. Transf.
Antti Valmari, Walter Vogler
2018 conf
ACSD
Ayleen Schinko, Walter Vogler
2018 J jnl
Sci. Ann. Comput. Sci.
Ayleen Schinko, Walter Vogler
2018 conf
Models, Mindsets, Meta
Johannes Gareis, Gerald Lüttgen, Ayleen Schinko, Walter Vogler
2017 J jnl
Theor. Comput. Sci.
Ferenc Bujtor, Walter Vogler
2017 J jnl
Sci. Comput. Program.
Richard Müller, Christian Stahl, Walter Vogler
2017 J jnl
ACM Trans. Embed. Comput. Syst.
Ferenc Bujtor, Lev Sorokin, Walter Vogler
2016 conf
ACSD
Ferenc Bujtor, Walter Vogler
2016 conf
SPIN
Antti Valmari, Walter Vogler
2016 J jnl
Theor. Comput. Sci.
Ferenc Bujtor, Sascha Fendrich, Gerald Lüttgen, Walter Vogler
2015 J jnl
Theor. Comput. Sci.
Ferenc Bujtor, Walter Vogler
2015 J jnl
ACM Trans. Embed. Comput. Syst.
Ferenc Bujtor, Walter Vogler
2015 B conf
SOFSEM
Ferenc Bujtor, Sascha Fendrich, Gerald Lüttgen, Walter Vogler
2015 J jnl
Acta Informatica
Gerald Lüttgen, Walter Vogler, Sascha Fendrich
2015 conf
ACSD
Ferenc Bujtor, Lev Sorokin, Walter Vogler
2014 B conf
SOFSEM
Ferenc Bujtor, Walter Vogler
2014 conf
ACSD
Ferenc Bujtor, Walter Vogler
2014 J jnl
Theor. Comput. Sci.
Blai Bonet, Patrik Haslum, Victor Khomenko, Sylvie Thiébaux, Walter Vogler
2014 J jnl
Acta Informatica
Walter Vogler, Christian Stahl, Richard Müller
2014 J jnl
Inf. Process. Lett.
Richard Müller, Christian Stahl, Walter Vogler
2013 J jnl
Log. Methods Comput. Sci.
Gerald Lüttgen, Walter Vogler
2013 J jnl
Electron. Commun. Eur. Assoc. Softw. Sci. Technol.
Gerald Lüttgen, Walter Vogler
2013 conf
ACSD
Stanislavs Golubcovs, Walter Vogler, Norman Kluge
2013 conf
ESOCC Workshops
Walter Vogler, Christian Stahl, Richard Müller
2012 conf
ACSD
Walter Vogler, Christian Stahl, Richard Müller
2012 J jnl
Acta Informatica
Christian Stahl, Walter Vogler
2012 conf
IFIP TCS
Gerald Lüttgen, Walter Vogler
2011 B conf
FoSSaCS
Christian Stahl, Walter Vogler
2011 conf
GandALF
Federico Buti, Massimo Callisto De Donato, Flavio Corradini, Maria Rita Di Berardini, Walter Vogler
2011 J jnl
CoRR
Federico Buti, Massimo Callisto De Donato, Flavio Corradini, Maria Rita Di Berardini, Walter Vogler
2011 J jnl
Fundam. Informaticae
Stephen A. Edwards, Ryszard Janicki, Walter Vogler
2011 conf
EXPRESS
Flavio Corradini, Maria Rita Di Berardini, Walter Vogler
2011 conf
ACSD
Dominic Wist, Walter Vogler, Ralf Wollowski
2011 J jnl
Theor. Comput. Sci.
Gerald Lüttgen, Walter Vogler
2011 J jnl
IET Comput. Digit. Tech.
Dominic Wist, M. Schaefer, Walter Vogler, Ralf Wollowski
2010 J jnl
Inf. Comput.
Gerald Lüttgen, Walter Vogler
2010 conf
ACSD
Dominic Wist, Mark Schäfer, Walter Vogler, Ralf Wollowski
2009 J jnl
Fundam. Informaticae
Dominic Wist, Ralf Wollowski, Mark Schäfer, Walter Vogler
2009 J jnl
Acta Informatica
Flavio Corradini, Maria Rita Di Berardini, Walter Vogler
2009 conf
EXPRESS
Katrin Iltgen, Walter Vogler
2009 J jnl
Acta Informatica
Victor Khomenko, Mark Schäfer, Walter Vogler, Ralf Wollowski
2009 B conf
SOFSEM
Gerald Lüttgen, Walter Vogler
2009 B conf
SOFSEM
Flavio Corradini, Maria Rita Di Berardini, Walter Vogler
2008 J jnl
Inf. Process. Lett.
Walter Vogler
2008 conf
ACSD
Mark Schäfer, Walter Vogler, Dominic Wist, Ralf Wollowski
2008 J jnl
Fundam. Informaticae
Victor Khomenko, Mark Schäfer, Walter Vogler
2007 J jnl
Theor. Comput. Sci.
Mark Schäfer, Walter Vogler
2007 J jnl
Theor. Comput. Sci.
Gerald Lüttgen, Walter Vogler
2007 J jnl
Inf. Comput.
Arend Rensink, Walter Vogler
2007 J jnl
Fundam. Informaticae
Walter Vogler, Ben Kangsah
2007 conf
ACSD
Victor Khomenko, Mark Schäfer, Walter Vogler
2007 J jnl
J. Log. Algebraic Methods Program.
Flavio Corradini, Walter Vogler
2007 A* conf
ICALP
Gerald Lüttgen, Walter Vogler
2006 J jnl
Theor. Comput. Sci.
Gerald Lüttgen, Walter Vogler
2006 B conf
CONCUR
Flavio Corradini, Maria Rita Di Berardini, Walter Vogler
2006 B conf
FoSSaCS
Gerald Lüttgen, Walter Vogler
2006 J jnl
Acta Informatica
Flavio Corradini, Maria Rita Di Berardini, Walter Vogler
2006 J jnl
Theor. Comput. Sci.
Flavio Corradini, Maria Rita Di Berardini, Walter Vogler
2006 J jnl
Acta Informatica
Victor Khomenko, Alex Kondratyev, Maciej Koutny, Walter Vogler
2006 conf
ACSD
Mark Schäfer, Walter Vogler, Ralf Wollowski, Victor Khomenko
2006 C conf
ICTAC
Marcos E. Kurbán, Peter Niebert, Hongyang Qu, Walter Vogler
2005 B conf
FoSSaCS
Gerald Lüttgen, Walter Vogler
2005 J jnl
RAIRO Theor. Informatics Appl.
Gerald Lüttgen, Walter Vogler
2005 B conf
FoSSaCS
Mark Schäfer, Walter Vogler
2005 conf
ICATPN
Mark Schäfer, Walter Vogler, Petr Jancar
2005 conf
ACSD
Walter Vogler, Ben Kangsah
2005 J jnl
Theor. Comput. Sci.
Flavio Corradini, Walter Vogler
2005 B conf
CONCUR
Victor Khomenko, Alex Kondratyev, Maciej Koutny, Walter Vogler
2005 conf
FORMATS
Flavio Corradini, Walter Vogler
2004 B conf
FoSSaCS
Gerald Lüttgen, Walter Vogler
2004 J jnl
Inf. Comput.
Gerald Lüttgen, Walter Vogler
2004 conf
EXPRESS
Flavio Corradini, Maria Rita Di Berardini, Walter Vogler
2004 conf
SFM
Elmar Bihler, Walter Vogler
2003 J jnl
Acta Informatica
Victor Khomenko, Maciej Koutny, Walter Vogler
2003 J jnl
Inf. Comput.
Walter Vogler
2003 ed.
MTCS
Walter Vogler, Kim Larsen
2003 B conf
CONCUR
Flavio Corradini, Maria Rita Di Berardini, Walter Vogler
2002 J jnl
Formal Methods Syst. Des.
Javier Esparza, Stefan Römer, Walter Vogler
2002 A* conf
CAV
Victor Khomenko, Maciej Koutny, Walter Vogler
2002 J jnl
Acta Informatica
Flavio Corradini, Walter Vogler, Lars Jenner
2002 conf
Concurrency and Hardware Design
Walter Vogler, Ralf Wollowski
2002 conf
FSTTCS
Walter Vogler, Ralf Wollowski
2002 J jnl
Theor. Comput. Sci.
Walter Vogler
2002 J jnl
Theor. Comput. Sci.
Walter Vogler
2002 conf
MTCS
Walter Vogler, Kim Larsen
2002 ed.
MTCS
Flavio Corradini, Walter Vogler
2001 B conf
CONCUR
Gerald Lüttgen, Walter Vogler
2001 J jnl
Theor. Comput. Sci.
Lars Jenner, Walter Vogler
2001 conf
APAQS
Flavio Corradini, Maria Rita Di Berardini, Walter Vogler
2001 conf
ICATPN
Walter Vogler
2001 conf
MTCS
Flavio Corradini, Walter Vogler
2000 conf
MTCS
Walter Vogler, Lars Jenner
2000 conf
ICATPN
Walter Vogler
1999 conf
ARTS
Lars Jenner, Walter Vogler
1999 conf
ICATPN
Walter Vogler
1998 conf
ICATPN
Elmar Bihler, Walter Vogler
1998 B conf
CONCUR
Walter Vogler, Alexei L. Semenov, Alexandre Yakovlev
1997 conf
Foundations of Computer Science: Potential - Theory - Cognition
Walter Vogler
1997 A* conf
ICALP
Walter Vogler
1997 B conf
MFCS
Walter Vogler
1996 A conf
TACAS
Javier Esparza, Stefan Römer, Walter Vogler
1996 C conf
FORTE
Ed Brinksma, Arend Rensink, Walter Vogler
1996 A* conf
ICALP
Lars Jenner, Walter Vogler
1996 J jnl
Inf. Comput.
Walter Vogler
1995 B conf
CONCUR
Ed Brinksma, Arend Rensink, Walter Vogler
1995 J jnl
Inf. Process. Lett.
Walter Vogler
1995 B conf
CONCUR
Walter Vogler
1995 J jnl
Inf. Comput.
Walter Vogler
1995 conf
STRICT
Walter Vogler
1995 A* conf
ICALP
Walter Vogler
1995 J jnl
Inf. Comput.
Walter Vogler
1993 J jnl
Theor. Comput. Sci.
Walter Vogler
1993 J jnl
Discret. Appl. Math.
Walter Vogler
1993 A* conf
ICALP
Walter Vogler
1992 A* conf
ICALP
Walter Vogler
1992 book
Walter Vogler
1992 ch.
Advances in Petri Nets: The DEMON Project
Walter Vogler
1992 J jnl
Fundam. Informaticae
Robert Gold, Walter Vogler
1991 J jnl
RAIRO Theor. Informatics Appl.
Walter Vogler
1991 J jnl
Forschungsberichte, TU Munich
Walter Vogler
1991 A conf
STACS
Walter Vogler
1991 J jnl
Theor. Comput. Sci.
Annegret Habel, Hans-Jörg Kreowski, Walter Vogler
1991 A* conf
ICALP
Walter Vogler
1991 J jnl
Theor. Comput. Sci.
Walter Vogler
1991 J jnl
Distributed Comput.
Walter Vogler
1991 J jnl
Forschungsberichte, TU Munich
Walter Vogler
1991 J jnl
Forschungsberichte, TU Munich
Walter Vogler
1990 J jnl
Forschungsberichte, TU Munich
Walter Vogler
1990 J jnl
Forschungsberichte, TU Munich
Walter Vogler
1990 A conf
STACS
Walter Vogler
1990 J jnl
Forschungsberichte, TU Munich
Walter Vogler
1990 B conf
MFCS
Robert Gold, Walter Vogler
1990 J jnl
Forschungsberichte, TU Munich
Robert Gold, Walter Vogler
1990 conf
Graph-Grammars and Their Application to Computer Science
Walter Vogler
1990 J jnl
Forschungsberichte, TU Munich
Walter Vogler
1989 conf
Applications and Theory of Petri Nets
Wilfried Brauer, Robert Gold, Walter Vogler
1989 conf
TAPSOFT, Vol.1
Annegret Habel, Hans-Jörg Kreowski, Walter Vogler
1989 J jnl
Acta Informatica
Walter Vogler
1989 J jnl
Acta Informatica
Annegret Habel, Hans-Jörg Kreowski, Walter Vogler
1989 B conf
WG
Walter Vogler
1989 J jnl
Math. Syst. Theory
Volker Diekert, Walter Vogler
1989 J jnl
Acta Informatica
Dirk Taubner, Walter Vogler
1988 B conf
MFCS
Walter Vogler
1988 B conf
MFCS
Volker Diekert, Walter Vogler
1988 conf
European Workshop on Applications and Theory in Petri Nets
Walter Vogler
1987 conf
WDAG
Walter Vogler
1987 J jnl
Bull. EATCS
Annegret Habel, Hans-Jörg Kreowski, Walter Vogler
1987 A conf
STACS
Dirk Taubner, Walter Vogler
1986 B conf
WG
Walter Vogler
1986 J jnl
J. Comb. Theory B
Walter Vogler
1985 J jnl
Comb.
Reinhard Diestel, Rudolf Halin, Walter Vogler
1985 J jnl
J. Graph Theory
George Hendry, Walter Vogler
1984 J jnl
J. Graph Theory
Walter Vogler
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