The answer is that, when you are doing sensortype=sens* , the system is doing an expansion of all the fields from the other sensortypes before eliminating those sensortypes that don't match. This leaves a bunch of NULL fields.
Of course, table * is not best practices anyway -- much better to use only the fields that you need for any given query, and to put them in an explicit fields command after the first pipe, to minimize the amount of extraction done by the system.
For an understanding of why this unexpected behavior is not a bug, you have to understand how searches and bloom filters actually work under the covers.
If you look at slide 22 of this .conf2017 presentation by MVP Martin Müller (@martin_mueller) at https://conf.splunk.com/files/2017/slides/fields-indexed-tokens-and-you.pdf
...then you will see this wording...
▶ Default assumption: Field values are whole indexed tokens
▶ exception=java.lang.NullPointerException becomes [ AND java lang NullPointerException ]
▶ Actual field extractions and post-filtering happens after loading raw events
So basically, for the event selection, sensortype=sens* initially becomes AND sens* , so the initial part of the search is going to find all events that have sens* somewhere in them. That is going to literally be every record with a sensortype= in its _raw, since sens* will pick up the token sensortype . It will also pick up any other fields that happen to have values starting with sens.
Since you are coding | table * , the system cannot optimize to the fields you are asking for and EVERY field has to be expanded. Once that all gets expanded, the ones where sensortype!=sens* get dropped, but the search still knows all the fields that were created/extracted for any of the events.
... View more