@@ -443,6 +443,84 @@ INSTANTIATE_TEST_SUITE_P(
443443 .ConsumeValueOrDie ();
444444 },
445445 },
446+ {
447+ " logs_basic" ,
448+ table_store::schema::Relation{{types::TIME64NS, types::STRING, types::STRING},
449+ {" start_time" , " attribute_str" , " log_message" },
450+ {types::ST_NONE, types::ST_NONE, types::ST_NONE}},
451+ R"pb(
452+ endpoint_config {}
453+ resource {}
454+ logs {
455+ attributes {
456+ name: "service.name"
457+ column {
458+ column_type: STRING
459+ column_index: 1
460+ }
461+ }
462+ time_column_index: 0
463+ observed_time_column_index: -1
464+ severity_number: 4
465+ severity_text: "INFO"
466+ body_column_index: 2
467+ }
468+ )pb" ,
469+ [](IR* graph, OperatorIR* parent, table_store::schema::Relation* relation) {
470+ OTelData data;
471+
472+ auto & log = data.logs .emplace_back ();
473+ log.time_column = CreateTypedColumn (graph, " start_time" , relation);
474+ log.attributes .push_back (
475+ {" service.name" , CreateTypedColumn (graph, " attribute_str" , relation), " " });
476+ log.severity_number = 4 ;
477+ log.severity_text = " INFO" ;
478+ log.body_column = CreateTypedColumn (graph, " log_message" , relation);
479+
480+ return graph->CreateNode <OTelExportSinkIR>(parent->ast (), parent, data)
481+ .ConsumeValueOrDie ();
482+ },
483+ },
484+ {
485+ " logs_with_observed_time_col" ,
486+ table_store::schema::Relation{
487+ {types::TIME64NS, types::TIME64NS, types::STRING, types::STRING},
488+ {" start_time" , " observed_time" , " attribute_str" , " log_message" },
489+ {types::ST_NONE, types::ST_NONE, types::ST_NONE, types::ST_NONE}},
490+ R"pb(
491+ endpoint_config {}
492+ resource {}
493+ logs {
494+ attributes {
495+ name: "service.name"
496+ column {
497+ column_type: STRING
498+ column_index: 2
499+ }
500+ }
501+ time_column_index: 0
502+ observed_time_column_index: 1
503+ severity_number: 4
504+ severity_text: "INFO"
505+ body_column_index: 3
506+ }
507+ )pb" ,
508+ [](IR* graph, OperatorIR* parent, table_store::schema::Relation* relation) {
509+ OTelData data;
510+
511+ auto & log = data.logs .emplace_back ();
512+ log.time_column = CreateTypedColumn (graph, " start_time" , relation);
513+ log.observed_time_column = CreateTypedColumn (graph, " observed_time" , relation);
514+ log.attributes .push_back (
515+ {" service.name" , CreateTypedColumn (graph, " attribute_str" , relation), " " });
516+ log.severity_number = 4 ;
517+ log.severity_text = " INFO" ;
518+ log.body_column = CreateTypedColumn (graph, " log_message" , relation);
519+
520+ return graph->CreateNode <OTelExportSinkIR>(parent->ast (), parent, data)
521+ .ConsumeValueOrDie ();
522+ },
523+ },
446524 {
447525 " string_value_attributes" ,
448526 table_store::schema::Relation{{types::TIME64NS, types::INT64},
@@ -557,6 +635,33 @@ OTelExportSinkIR* CreateSpanWithNameString(IR* graph, OperatorIR* parent,
557635 return graph->CreateNode <OTelExportSinkIR>(parent->ast (), parent, data).ConsumeValueOrDie ();
558636}
559637
638+ OTelExportSinkIR* CreateLog (IR* graph, OperatorIR* parent,
639+ table_store::schema::Relation* relation) {
640+ OTelData data;
641+
642+ auto & log = data.logs .emplace_back ();
643+ log.time_column = CreateTypedColumn (graph, " start_time" , relation);
644+ log.body_column = CreateTypedColumn (graph, " log_message" , relation);
645+ log.severity_number = 4 ;
646+ log.severity_text = " INFO" ;
647+
648+ return graph->CreateNode <OTelExportSinkIR>(parent->ast (), parent, data).ConsumeValueOrDie ();
649+ }
650+
651+ OTelExportSinkIR* CreateLogWithObservedTime (IR* graph, OperatorIR* parent,
652+ table_store::schema::Relation* relation) {
653+ OTelData data;
654+
655+ auto & log = data.logs .emplace_back ();
656+ log.time_column = CreateTypedColumn (graph, " start_time" , relation);
657+ log.observed_time_column = CreateTypedColumn (graph, " observed_time" , relation);
658+ log.body_column = CreateTypedColumn (graph, " log_message" , relation);
659+ log.severity_number = 4 ;
660+ log.severity_text = " INFO" ;
661+
662+ return graph->CreateNode <OTelExportSinkIR>(parent->ast (), parent, data).ConsumeValueOrDie ();
663+ }
664+
560665INSTANTIATE_TEST_SUITE_P (
561666 ErrorTests, WrongColumnTypesTest,
562667 ::testing::ValuesIn (std::vector<WrongColumnTypesTestCase>{
@@ -723,6 +828,31 @@ INSTANTIATE_TEST_SUITE_P(
723828 .ConsumeValueOrDie ();
724829 },
725830 },
831+ {
832+ " log_time_column_wrong" ,
833+ table_store::schema::Relation{{types::INT64, types::STRING, types::STRING},
834+ {" start_time" , " attribute_str" , " log_message" },
835+ {types::ST_NONE, types::ST_NONE, types::ST_NONE}},
836+ " Expected time column 'start_time' to be TIME64NS, received INT64" ,
837+ &CreateLog,
838+ },
839+ {
840+ " log_body_column_wrong" ,
841+ table_store::schema::Relation{{types::TIME64NS, types::STRING, types::TIME64NS},
842+ {" start_time" , " attribute_str" , " log_message" },
843+ {types::ST_NONE, types::ST_NONE, types::ST_NONE}},
844+ " Expected body column 'log_message' to be STRING, received TIME64NS" ,
845+ &CreateLog,
846+ },
847+ {
848+ " log_observed_time_column_wrong" ,
849+ table_store::schema::Relation{
850+ {types::TIME64NS, types::INT64, types::STRING, types::STRING},
851+ {" start_time" , " observed_time" , " attribute_str" , " log_message" },
852+ {types::ST_NONE, types::ST_NONE, types::ST_NONE, types::ST_NONE}},
853+ " Expected observed_time column 'observed_time' to be TIME64NS, received INT64" ,
854+ &CreateLogWithObservedTime,
855+ },
726856 }),
727857 [](const ::testing::TestParamInfo<WrongColumnTypesTestCase>& info) { return info.param .name ; });
728858} // namespace planner
0 commit comments