Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sql: extend VDBE memory cell with field_type member #4148

Closed
Korablev77 opened this issue Apr 12, 2019 · 3 comments
Closed

sql: extend VDBE memory cell with field_type member #4148

Korablev77 opened this issue Apr 12, 2019 · 3 comments
Assignees
Labels
Milestone

Comments

@Korablev77
Copy link
Contributor

During execution of bytecode virtual machine uses its own type system to operate on memory cells. Types of this system can be matched with Tarantool's field types (at least now). But when it comes for NULLs, we can't say exact type of initial value:

CREATE TABLE t (id INT PRIMARY KEY, a INT);
INSERT INTO t VALUES (1, 1), (2, NULL);
SELECT typeof(a) FROM t;
---
- metadata:
  - name: typeof(a)
    type: string
  rows:
  - ['integer']
  - ['null']
...

Problem of determining initial type of value will become even more complicated when we add user-defined types. So, to improve our type system, we have to keep in memory cell not only type of value (in other words - msgpack format type), but also type of space's field (in case value is fetched from tuple).

@kostja
Copy link
Contributor

kostja commented Apr 25, 2019

test case:
it isn't what i expected ...tarantool> insert into t2 values (1,null);

  • row_count: 1
    ...

tarantool> select typeof(s2) from t2;

  • metadata:
    • name: typeof(s2)
      type: string
      rows:
    • ['null']
      ...

@pgulutzan
Copy link
Contributor

I hope that the intent is: (a) for a NULL in a column which is defined as INT, the data type is 'integer'; (b) for NULL outside of a column and therefore not subject to column-definition rules as in "select null;", the data type is 'boolean'; (c) for NULL in a column which is defined as SCALAR, the data type is 'boolean'. Is that outside the scope of this issue?

Korablev77 added a commit that referenced this issue Jul 25, 2019
There's several reasons to do so. First one is to improve operability of
built-in function 'typeof()' which returns string containing argument's
type. Using only format (msgpack) type we can't determine real field
type of null values. Moreover, result of CAST should feature the same
type as it was specified in operation. For instance:
typeof(CAST(0 AS INTEGER)) should return "integer", not "unsigned".

The second reason is different rules for comparison involving values of
SCALAR type. In Tarantool NoSQL it is allowed to compare values of
"incompatible" types like booleans and strings (using heuristics which
says that values of one type always are greater/less that values of
another type), in case they are stored in SCALAR field type. Without
storing actual field type in struct Mem it is obvious impossible to
achieve.

Closes #4148
Korablev77 added a commit that referenced this issue Jul 25, 2019
It was decided that null value in SQL by default should be of type
boolean. Justification of such change is that according to ANSI boolean
type in fact has three different values: true, false and unknown. The
latter is basically an alias to null value.

Follow up #4148
Korablev77 added a commit that referenced this issue Jul 27, 2019
There's several reasons to do so. First one is to improve operability of
built-in function 'typeof()' which returns string containing argument's
type. Using only format (msgpack) type we can't determine real field
type of null values. Moreover, result of CAST should feature the same
type as it was specified in operation. For instance:
typeof(CAST(0 AS INTEGER)) should return "integer", not "unsigned".

The second reason is different rules for comparison involving values of
SCALAR type. In Tarantool NoSQL it is allowed to compare values of
"incompatible" types like booleans and strings (using heuristics which
says that values of one type always are greater/less that values of
another type), in case they are stored in SCALAR field type. Without
storing actual field type in struct Mem it is obvious impossible to
achieve.

Thus, now field_type member in struct Mem represents supposed field type
in case value is fetched from tuple or is a result of CAST operation.

Closes #4148
Korablev77 added a commit that referenced this issue Jul 31, 2019
There's several reasons to do so. First one is to improve operability of
built-in function 'typeof()' which returns string containing argument's
type. Using only format (msgpack) type we can't determine real field
type of null values. Moreover, result of CAST should feature the same
type as it was specified in operation. For instance:
typeof(CAST(0 AS INTEGER)) should return "integer", not "unsigned".

The second reason is different rules for comparison involving values of
SCALAR type. In Tarantool NoSQL it is allowed to compare values of
"incompatible" types like booleans and strings (using heuristics which
says that values of one type always are greater/less that values of
another type), in case they are stored in SCALAR field type. Without
storing actual field type in struct Mem it is obvious impossible to
achieve.

Thus, now field_type member in struct Mem represents supposed field type
in case value is fetched from tuple or is a result of CAST operation.

Closes #4148
@kyukhin kyukhin added ready for review feature A new functionality and removed in progress labels Jul 31, 2019
Korablev77 added a commit that referenced this issue Aug 1, 2019
There's several reasons to do so. First one is to improve operability of
built-in function 'typeof()' which returns string containing argument's
type. Using only format (msgpack) type we can't determine real field
type of null values. Moreover, result of CAST should feature the same
type as it was specified in operation. For instance:
typeof(CAST(0 AS INTEGER)) should return "integer", not "unsigned".

The second reason is different rules for comparison involving values of
SCALAR type. In Tarantool NoSQL it is allowed to compare values of
"incompatible" types like booleans and strings (using heuristics which
says that values of one type always are greater/less that values of
another type), in case they are stored in SCALAR field type. Without
storing actual field type in struct Mem it is obvious impossible to
achieve.

Thus, now field_type member in struct Mem represents supposed field type
in case value is fetched from tuple or is a result of CAST operation.

Closes #4148
Korablev77 added a commit that referenced this issue Aug 2, 2019
There's several reasons to do so. First one is to improve operability of
built-in function 'typeof()' which returns string containing argument's
type. Using only format (msgpack) type we can't determine real field
type of null values. Moreover, result of CAST should feature the same
type as it was specified in operation. For instance:
typeof(CAST(0 AS INTEGER)) should return "integer", not "unsigned".

The second reason is different rules for comparison involving values of
SCALAR type. In Tarantool NoSQL it is allowed to compare values of
"incompatible" types like booleans and strings (using heuristics which
says that values of one type always are greater/less that values of
another type), in case they are stored in SCALAR field type. Without
storing actual field type in struct Mem it is obvious impossible to
achieve.

Thus, now field_type member in struct Mem represents supposed field type
in case value is fetched from tuple or is a result of CAST operation.

Closes #4148
@kyukhin
Copy link
Contributor

kyukhin commented Aug 2, 2019

Done by 931d58a

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants