Skip to content

sql: values of type BLOB are encoded as strings #4023

Closed
@Korablev77

Description

@Korablev77
CREATE TABLE t (key BLOB PRIMARY KEY);
INSERT INTO t VALUES ('abc');

In a nutshell, to execute last query following actions are performed:

1. OP_String8 r, 'abc' //Save constant string 'abc' to memory cell r
2. OP_ApplyType r, BLOB //Cast value in r to SCALAR type
3. OP_MakeRecord r, r1 //Encode value in r to msgpack and store to r1
4. OP_Insert r1, space(t) //Insert value of r1 to space(t)

At step 2 to convert value we are calling mem_apply_type() routine. If we want to convert string to scalar, next procedure is called:

 366         case FIELD_TYPE_SCALAR:                                                 
 367                 if (record->flags & (MEM_Str | MEM_Blob))                       
 368                         record->flags |= MEM_Blob;                              
 369                 return 0;     

So, in fact after type SCALAR is applied to STRING, value features both flags: MEM_Blob and MEM_Str.
And during msgpack encoding at stage 3, we set type of tuple format as MP_STR:

1714 void                                                                            
1715 mpstream_encode_vdbe_mem(struct mpstream *stream, struct Mem *var)              
1716 {        
...
1740         } else if (var->flags & MEM_Str) {                                      
1741                 mpstream_encode_strn(stream, var->z, var->n);    

Which is obviously wrong action, since after fetching value from tuple it will be treated as STRING (BLOB is detected as MP_BIN in tuple format). To resolve this problem, we should allow only one type-flag at once. Fix in this case is obvious, but it affects other type-related issues.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions