On Tue, Feb 11, 2025 at 5:00 PM Patrick McFadin <pmcfa...@gmail.com> wrote:
>
> You get my vote for the best subject line I've seen this week.
>

+1, I'm deeply saddened that despite this title this post does not
contain the answer to the ultimate question of life, the universe, and
everything. :-(


> On Tue, Feb 11, 2025 at 1:20 PM Benedict <bened...@apache.org> wrote:
> >
> > Perhaps we should reify this in the type system? Introduce a MAYBE EMPTY 
> > modifier for column types, or simply name them eg [int] vs int?
> >
> > I think the problem is today it’s all implicit and - as David says - 
> > inconsistent. It would be nice to move away from this as the default for a 
> > variety of reasons, but also nice to make the behaviour well defined for 
> > those use cases we think we’re supporting.
> >
> > On 11 Feb 2025, at 21:16, David Capwell <dcapw...@apple.com> wrote:
> >
> > Thanks for the reply!
> >
> > AFAIK this EMPTY stuff goes back to thrift days.
> >
> >
> > This is what I was told, but the expected semantics are not clear so my 
> > goal is to help flesh things out.
> >
> > We let people insert these zero length values back then, so we have to 
> > support those zero length values existing for ever :/.
> >
> >
> > We allow this for some types but not all.  I think where I am coming from 
> > is write != select, so if we say empty = “no value” or “null” then why does 
> > select treat it as a value?  Is this the expected behavior?
> >
> > maybe we should be converting such values into a tombstone / NULL
> >
> >
> > Tombstones can be purged, where as empty can’t, so should it?
> >
> > Everything besides SAI, including the table based 2i and ALLOW FILTERING, 
> > treat EMPTY as a distant value which can be inserted and queried on.  We 
> > have supported it in the past, so we should continue to support it into the 
> > future, even if it is painful to do.
> >
> >
> > I guess where I come from here is what semantics do we expect.
> >
> > So lets say v0 is empty bytes int
> >
> > SELECT CAST(v0 AS text)
> >
> > Is this null or empty bytes?  In our project this is null
> >
> > SELECT JSON v0
> >
> > Is this null or empty bytes?  In our project this is null
> >
> > SELECT avg(v0) …
> >
> > Is this null or empty bytes?  In our project this is null
> >
> > So in most places you touch empty bytes we treat it as null, but only in 
> > filtering do we not.
> >
> > On Feb 11, 2025, at 11:27 AM, Jeremiah Jordan <jeremiah.jor...@gmail.com> 
> > wrote:
> >
> > AFAIK this EMPTY stuff goes back to thrift days.  We let people insert 
> > these zero length values back then, so we have to support those zero length 
> > values existing for ever :/.
> >
> > How useful is such a distinction?  I don’t know.  Is anybody actually doing 
> > this?  Well Andres brought up 
> > https://issues.apache.org/jira/browse/CASSANDRA-20313 as a problem because 
> > we had an end user create an SAI index on a column which contained EMPTY 
> > values in it.  So people are inserting these into the database.  Would they 
> > expect to be able to query by EMPTY?  I do not know.
> >
> > This is the first I have heard of the “isEmptyValueMeaningless” setting.  
> > The meaning of EMPTY to me has always been the same for an Integer or a 
> > String, “this column has a value of no value” vs NULL which means "this 
> > column is not set/has no value”.  If we truly want to follow the spirit of 
> > that setting, then maybe we should be converting such values into a 
> > tombstone / NULL up front when deserializing them, rather than storing the 
> > EMPTY byte buffer in the DB?
> >
> > Anyway, I am kind of rambling here.  I am of two minds.
> > I can see that this does seem like a silly distinction to have for some 
> > types, so maybe we should just decide that in a CQL world, EMPTY means NULL 
> > for some types, and actually just make that a tombstone.  Maybe 6.0 would 
> > be a good major version change to make such a “breaking” behavior change in.
> >
> > I can also see the “don’t screw up the legacy apps” use case.  Everything 
> > besides SAI, including the table based 2i and ALLOW FILTERING, treat EMPTY 
> > as a distant value which can be inserted and queried on.  We have supported 
> > it in the past, so we should continue to support it into the future, even 
> > if it is painful to do.
> >
> > Flip a coin and I can argue either side.  So I would love to hear others 
> > thoughts to convince me one way to the other.
> >
> > -Jeremiah
> >
> >
> >
> > On Feb 11, 2025 at 12:55:35 PM, Caleb Rackliffe <calebrackli...@gmail.com> 
> > wrote:
> >>
> >> The case where allowsEmpty == true AND is meaningless == true is 
> >> especially confusing. If I could design this from scratch, I would reject 
> >> writes and filtering on EMPTY values for int and the other types where 
> >> meaningless == true. (In other words, if we allow EMPTY, it is meaningful 
> >> and queryable. If we don't, it isn't.) That avoids problems that can't 
> >> have anything other than an arbitrary solution, like what we do with < and 
> >> > for EMPTY for int. When we add IS [NOT] NULL support, that would 
> >> preferably NOT match EMPTY values for the types where empty means 
> >> something, like strings. For everything else, EMPTY could be equivalent to 
> >> null and match IS NULL.
> >>
> >> The only real way to make SAI compatible with the current behavior is to 
> >> add something like a special postings list to its data structures that 
> >> corresponds to the rows where the indexed column value is EMPTY.
> >>
> >> On Tue, Feb 11, 2025 at 12:21 PM David Capwell <dcapw...@apple.com> wrote:
> >>>
> >>> Bringing this discussion to dev@ rather than Slack as we try to figure 
> >>> out CASSANDRA-20313 and CASSANDRA-19461.
> >>>
> >>> In the type system, we have 2 different (but related) methods:
> >>>
> >>> AbstractType#allowsEmpty                        - if the user gives empty 
> >>> bytes (new byte[0]) will the type reject it
> >>> AbstractType#isEmptyValueMeaningless  - if the user gives empty bytes, 
> >>> should this be handled like null?
> >>>
> >>> In practice, there are 2 cases that matter:
> >>>
> >>> allowsEmpty = true AND is meaningless = false - stuff like text and bytes
> >>> allowsEmpty = true AND is meaningless = true  - many types, example "int"
> >>>
> >>> What this means is that users are able to use empty bytes when writing to 
> >>> these types, but this leads to complexity in the filter path, and is 
> >>> something we are trying to flesh out the “correct” semantics for SAI.
> >>>
> >>> Simple example:
> >>>
> >>> {code}
> >>>
> >>> @Test
> >>> public void test() throws IOException
> >>> {
> >>>     try (Cluster cluster = Cluster.build(1).start())
> >>>     {
> >>>         init(cluster);
> >>>         cluster.schemaChange(withKeyspace("CREATE TABLE %s.tbl (pk int 
> >>> primary key, v int)"));
> >>>         IInvokableInstance node = cluster.get(1);
> >>>         for (int i = 0; i < 10; i++)
> >>>             node.executeInternal(withKeyspace("INSERT INTO %s.tbl (pk, v) 
> >>> VALUES (?, ?)"), i, ByteBufferUtil.EMPTY_BYTE_BUFFER);
> >>>
> >>>         var qr = node.executeInternalWithResult(withKeyspace("SELECT * 
> >>> FROM %s.tbl WHERE v=? ALLOW FILTERING"), 
> >>> ByteBufferUtil.EMPTY_BYTE_BUFFER);
> >>>         StringBuilder sb = new StringBuilder();
> >>>         sb.append(qr.names());
> >>>         while (qr.hasNext())
> >>>         {
> >>>             var next = qr.next();
> >>>             sb.append('\n').append(next);
> >>>         }
> >>>         System.out.println(sb);
> >>>     }
> >>> }
> >>>
> >>> {code}
> >>>
> >>> “Should” this return 10 rows or 0?  In this case, the type is int, and 
> >>> int defines empty as meaningless, which means it should act as a null; 
> >>> yet this query returns 10 rows, which violates CQL as foo = null == false.
> >>>
> >>> Right now there really isn’t a way to query for NULL (CASSANDRA-10715 is 
> >>> still open), but if we did add such a thing we would also need to figure 
> >>> out the semantics with regard to these cases.
> >
> >

Reply via email to