@@ -54,6 +54,20 @@ class Emitter {
5454 case NodeType::NODE_LOCKING_CLAUSE: emit_locking (node); break ;
5555 case NodeType::NODE_INTO_CLAUSE: emit_into (node); break ;
5656
57+ // ---- INSERT statement ----
58+ case NodeType::NODE_INSERT_STMT: emit_insert_stmt (node); break ;
59+ case NodeType::NODE_INSERT_COLUMNS: emit_insert_columns (node); break ;
60+ case NodeType::NODE_VALUES_CLAUSE: emit_values_clause (node); break ;
61+ case NodeType::NODE_VALUES_ROW: emit_values_row (node); break ;
62+ case NodeType::NODE_INSERT_SET_CLAUSE: emit_insert_set_clause (node); break ;
63+ case NodeType::NODE_ON_DUPLICATE_KEY: emit_on_duplicate_key (node); break ;
64+ case NodeType::NODE_ON_CONFLICT: emit_on_conflict (node); break ;
65+ case NodeType::NODE_CONFLICT_TARGET: emit_conflict_target (node); break ;
66+ case NodeType::NODE_CONFLICT_ACTION: emit_conflict_action (node); break ;
67+ case NodeType::NODE_RETURNING_CLAUSE: emit_returning (node); break ;
68+ case NodeType::NODE_STMT_OPTIONS: emit_stmt_options (node); break ;
69+ case NodeType::NODE_UPDATE_SET_ITEM: emit_update_set_item (node); break ;
70+
5771 // ---- Table references ----
5872 case NodeType::NODE_TABLE_REF: emit_table_ref (node); break ;
5973 case NodeType::NODE_ALIAS: emit_alias (node); break ;
@@ -380,6 +394,197 @@ class Emitter {
380394 }
381395 }
382396
397+ // ---- INSERT ----
398+
399+ void emit_insert_stmt (const AstNode* node) {
400+ // Check FLAG_REPLACE
401+ if (node->flags & 0x01 ) {
402+ sb_.append (" REPLACE" );
403+ } else {
404+ sb_.append (" INSERT" );
405+ }
406+
407+ for (const AstNode* child = node->first_child ; child; child = child->next_sibling ) {
408+ switch (child->type ) {
409+ case NodeType::NODE_STMT_OPTIONS:
410+ sb_.append_char (' ' );
411+ emit_node (child);
412+ break ;
413+ case NodeType::NODE_TABLE_REF:
414+ sb_.append (" INTO " );
415+ emit_node (child);
416+ break ;
417+ case NodeType::NODE_INSERT_COLUMNS:
418+ sb_.append_char (' ' );
419+ emit_node (child);
420+ break ;
421+ case NodeType::NODE_VALUES_CLAUSE:
422+ sb_.append_char (' ' );
423+ emit_node (child);
424+ break ;
425+ case NodeType::NODE_SELECT_STMT:
426+ sb_.append_char (' ' );
427+ emit_node (child);
428+ break ;
429+ case NodeType::NODE_INSERT_SET_CLAUSE:
430+ sb_.append_char (' ' );
431+ emit_node (child);
432+ break ;
433+ case NodeType::NODE_ON_DUPLICATE_KEY:
434+ sb_.append_char (' ' );
435+ emit_node (child);
436+ break ;
437+ case NodeType::NODE_ON_CONFLICT:
438+ sb_.append_char (' ' );
439+ emit_node (child);
440+ break ;
441+ case NodeType::NODE_RETURNING_CLAUSE:
442+ sb_.append_char (' ' );
443+ emit_node (child);
444+ break ;
445+ default :
446+ sb_.append_char (' ' );
447+ emit_node (child);
448+ break ;
449+ }
450+ }
451+ }
452+
453+ void emit_stmt_options (const AstNode* node) {
454+ bool first = true ;
455+ for (const AstNode* child = node->first_child ; child; child = child->next_sibling ) {
456+ if (!first) sb_.append_char (' ' );
457+ first = false ;
458+ emit_node (child);
459+ }
460+ }
461+
462+ void emit_insert_columns (const AstNode* node) {
463+ sb_.append_char (' (' );
464+ bool first = true ;
465+ for (const AstNode* child = node->first_child ; child; child = child->next_sibling ) {
466+ if (!first) sb_.append (" , " );
467+ first = false ;
468+ emit_node (child);
469+ }
470+ sb_.append_char (' )' );
471+ }
472+
473+ void emit_values_clause (const AstNode* node) {
474+ // Check for DEFAULT VALUES (value stored in node)
475+ if (node->value_len > 0 ) {
476+ emit_value (node); // "DEFAULT VALUES"
477+ return ;
478+ }
479+ sb_.append (" VALUES " );
480+ bool first = true ;
481+ for (const AstNode* child = node->first_child ; child; child = child->next_sibling ) {
482+ if (!first) sb_.append (" , " );
483+ first = false ;
484+ emit_node (child);
485+ }
486+ }
487+
488+ void emit_values_row (const AstNode* node) {
489+ sb_.append_char (' (' );
490+ bool first = true ;
491+ for (const AstNode* child = node->first_child ; child; child = child->next_sibling ) {
492+ if (!first) sb_.append (" , " );
493+ first = false ;
494+ emit_node (child);
495+ }
496+ sb_.append_char (' )' );
497+ }
498+
499+ void emit_insert_set_clause (const AstNode* node) {
500+ sb_.append (" SET " );
501+ bool first = true ;
502+ for (const AstNode* child = node->first_child ; child; child = child->next_sibling ) {
503+ if (!first) sb_.append (" , " );
504+ first = false ;
505+ emit_node (child);
506+ }
507+ }
508+
509+ void emit_update_set_item (const AstNode* node) {
510+ const AstNode* col = node->first_child ;
511+ const AstNode* val = col ? col->next_sibling : nullptr ;
512+ if (col) emit_node (col);
513+ sb_.append (" = " );
514+ if (val) emit_node (val);
515+ }
516+
517+ void emit_on_duplicate_key (const AstNode* node) {
518+ sb_.append (" ON DUPLICATE KEY UPDATE " );
519+ bool first = true ;
520+ for (const AstNode* child = node->first_child ; child; child = child->next_sibling ) {
521+ if (!first) sb_.append (" , " );
522+ first = false ;
523+ emit_node (child);
524+ }
525+ }
526+
527+ void emit_on_conflict (const AstNode* node) {
528+ sb_.append (" ON CONFLICT" );
529+ for (const AstNode* child = node->first_child ; child; child = child->next_sibling ) {
530+ sb_.append_char (' ' );
531+ emit_node (child);
532+ }
533+ }
534+
535+ void emit_conflict_target (const AstNode* node) {
536+ if (node->value_len > 0 ) {
537+ // ON CONSTRAINT name
538+ emit_value (node); // "ON CONSTRAINT"
539+ sb_.append_char (' ' );
540+ if (node->first_child ) emit_node (node->first_child );
541+ } else {
542+ // (col1, col2, ...)
543+ sb_.append_char (' (' );
544+ bool first = true ;
545+ for (const AstNode* child = node->first_child ; child; child = child->next_sibling ) {
546+ if (!first) sb_.append (" , " );
547+ first = false ;
548+ emit_node (child);
549+ }
550+ sb_.append_char (' )' );
551+ }
552+ }
553+
554+ void emit_conflict_action (const AstNode* node) {
555+ sb_.append (" DO " );
556+ StringRef action_type{node->value_ptr , node->value_len };
557+ if (action_type.equals_ci (" NOTHING" , 7 )) {
558+ sb_.append (" NOTHING" );
559+ } else if (action_type.equals_ci (" UPDATE" , 6 )) {
560+ sb_.append (" UPDATE SET " );
561+ bool first = true ;
562+ for (const AstNode* child = node->first_child ; child; child = child->next_sibling ) {
563+ if (child->type == NodeType::NODE_WHERE_CLAUSE) {
564+ emit_node (child);
565+ } else {
566+ if (!first) sb_.append (" , " );
567+ first = false ;
568+ emit_node (child);
569+ }
570+ }
571+ }
572+ }
573+
574+ void emit_returning (const AstNode* node) {
575+ sb_.append (" RETURNING " );
576+ bool first = true ;
577+ for (const AstNode* child = node->first_child ; child; child = child->next_sibling ) {
578+ if (child->type == NodeType::NODE_ALIAS) {
579+ emit_node (child);
580+ } else {
581+ if (!first) sb_.append (" , " );
582+ first = false ;
583+ emit_node (child);
584+ }
585+ }
586+ }
587+
383588 // ---- Expressions ----
384589
385590 void emit_binary_op (const AstNode* node) {
0 commit comments