@@ -78,6 +78,22 @@ function parseCSVLine(line: string, delimiter: string): string[] {
7878 return result ;
7979}
8080
81+ // Escape a CSV field - wrap in quotes if it contains delimiter, newline, or quote
82+ function escapeCsvField ( field : string , delimiter : string ) : string {
83+ // Check if field needs escaping
84+ const needsEscaping = field . includes ( delimiter ) || field . includes ( '\n' ) || field . includes ( '\r' ) || field . includes ( '"' ) ;
85+
86+ if ( ! needsEscaping ) {
87+ return field ;
88+ }
89+
90+ // Escape quotes by doubling them
91+ const escapedField = field . replace ( / " / g, '""' ) ;
92+
93+ // Wrap in quotes
94+ return `"${ escapedField } "` ;
95+ }
96+
8197// Helper functions from csvPreprocessor.ts
8298function hexToBytes ( hex : string ) : Uint8Array {
8399 hex = hex . replace ( / ^ \\ x / i, "" ) ;
@@ -287,7 +303,7 @@ export async function preprocessAndLoadInBatches(
287303 // Extract a complete CSV line (handling quoted fields with newlines)
288304 let line = '' ;
289305 let inQuotes = false ;
290- let lineStart = position ;
306+ const lineStart = position ;
291307
292308 while ( position < content . length ) {
293309 const char = content [ position ] ;
@@ -338,7 +354,9 @@ export async function preprocessAndLoadInBatches(
338354 protoDecoder : options . protoDecoder ,
339355 } ) ;
340356
341- const rowString = processedRow . join ( delimiter ) ;
357+ // Escape each field properly before joining
358+ const escapedRow = processedRow . map ( field => escapeCsvField ( field , delimiter ) ) ;
359+ const rowString = escapedRow . join ( delimiter ) ;
342360 const rowSize = rowString . length + 1 ; // +1 for newline
343361
344362 // Check if adding this row would exceed batch limits
@@ -361,7 +379,6 @@ export async function preprocessAndLoadInBatches(
361379 const sql = generateCsvReadSql ( {
362380 fileName : batchFileName ,
363381 tableName,
364- delimiter,
365382 operation,
366383 nodeId, // Always pass nodeId for both CREATE and INSERT
367384 typeHints,
@@ -401,7 +418,6 @@ export async function preprocessAndLoadInBatches(
401418 const sql = generateCsvReadSql ( {
402419 fileName : batchFileName ,
403420 tableName,
404- delimiter,
405421 operation,
406422 nodeId, // Always pass nodeId for both CREATE and INSERT
407423 typeHints,
0 commit comments