[Tarantool-patches] [PATCH 4/6] sql: extend result set with nullability

Vladislav Shpilevoy v.shpilevoy at tarantool.org
Fri Nov 29 01:41:57 MSK 2019


Thanks for the patch!

You added a leading whitespace to the commit title.

Here is a strange example:

    box.cfg{}
    s = box.schema.create_space('TEST', {
        format = {{'ID', 'unsigned'}, {'COL', 'unsigned', is_nullable = true}}
    })
    pk = s:create_index('pk', {parts = {{'ID'}, {'COL', is_nullable = false}}})

In that example I defined a 'false-nullable' column. It
is nullable in the space format, but is not in the
index format. The strictest rule wins, so it is not nullable
after all. That can be seen in struct tuple_format. SQL says,
that it is nullable. But this is not a real problem. Perhaps
this might be even right. However the next example certainly
misses something:

    box.execute('SELECT * FROM test')
    ---
    - metadata:
      - name: ID
        type: unsigned
      - name: COL
        type: unsigned
      rows: []
    ...

    box.execute('SELECT col FROM test')
    ---
    - metadata:
      - type: unsigned
        name: COL
        is_nullable: true
      rows: []
    ...

As you can see, nullable depends on whether I select a
column explicitly or not. Perhaps the same happens to
autoincrement meta, I didn't check.

See 5 comments below.

On 27/11/2019 13:15, Nikita Pettik wrote:
> If member of result set is (solely) column identifier, then metadata
> will contain its corresponding field nullability as boolean property.
> Note that indicating nullability for other expressions (like x + 1)
> may make sense but it requires derived nullability calculation which in
> turn seems to be overkill (at least in scope of current patch).
> 
> Part of #4407
> ---
>  src/box/execute.c                                |  18 +-
>  src/box/iproto_constants.h                       |   1 +
>  src/box/lua/execute.c                            |   5 +
>  src/box/lua/net_box.c                            |   7 +-
>  src/box/sql/select.c                             |   6 +-
>  src/box/sql/sqlInt.h                             |   3 +
>  src/box/sql/vdbe.h                               |   3 +
>  src/box/sql/vdbeInt.h                            |   5 +
>  src/box/sql/vdbeapi.c                            |   7 +
>  src/box/sql/vdbeaux.c                            |   7 +
>  test/box/sql-update-with-nested-select.result    |   5 +-
>  test/sql/boolean.result                          | 425 ++++++++++++++---------
>  test/sql/check-clear-ephemeral.result            |   5 +-
>  test/sql/collation.result                        |  74 ++--
>  test/sql/gh-3199-no-mem-leaks.result             | 120 ++++---
>  test/sql/gh2141-delete-trigger-drop-table.result |  20 +-
>  test/sql/gh2251-multiple-update.result           |  10 +-
>  test/sql/iproto.result                           | 105 +++---
>  test/sql/misc.result                             |  25 +-
>  test/sql/on-conflict.result                      |  20 +-
>  test/sql/persistency.result                      | 190 ++++++----
>  test/sql/row-count.result                        |  25 +-
>  test/sql/sql-debug.result                        |  15 +-
>  test/sql/transition.result                       | 190 ++++++----
>  test/sql/types.result                            | 105 +++---
>  test/sql/update-with-nested-select.result        |   5 +-
>  26 files changed, 862 insertions(+), 539 deletions(-)
> 
> diff --git a/src/box/execute.c b/src/box/execute.c
> index 20bfd0957..98812ae1e 100644
> --- a/src/box/execute.c
> +++ b/src/box/execute.c
> @@ -267,8 +267,10 @@ error:
>  	region_truncate(region, svp);
>  	return -1;
>  }
> +
>  static size_t
> -metadata_map_sizeof(const char *name, const char *type, const char *coll)
> +metadata_map_sizeof(const char *name, const char *type, const char *coll,
> +		    int nullable)

1. Please, rename to 'is_nullable'. Here and in other places.

>  {
>  	uint32_t members_count = 2;
>  	size_t map_size = 0;
> @@ -277,6 +279,11 @@ metadata_map_sizeof(const char *name, const char *type, const char *coll)
>  		map_size += mp_sizeof_uint(IPROTO_FIELD_COLL);
>  		map_size += mp_sizeof_str(strlen(coll));
>  	}
> +	if (nullable != -1) {
> +		members_count++;
> +		map_size += mp_sizeof_uint(IPROTO_FIELD_NULLABLE);

2. This too. IPROTO_FIELD_IS_NULLABLE.

> +		map_size += mp_sizeof_bool(nullable);
> +	}
>  	map_size += mp_sizeof_uint(IPROTO_FIELD_NAME);
>  	map_size += mp_sizeof_uint(IPROTO_FIELD_TYPE);
>  	map_size += mp_sizeof_str(strlen(name));
> @@ -334,6 +342,10 @@ sql_get_metadata(struct sql_stmt *stmt, struct obuf *out, int column_count)
>  			pos = mp_encode_uint(pos, IPROTO_FIELD_COLL);
>  			pos = mp_encode_str(pos, coll, strlen(coll));
>  		}
> +		if (nullable != -1) {
> +			pos = mp_encode_uint(pos, IPROTO_FIELD_NULLABLE);
> +			pos = mp_encode_bool(pos, nullable);
> +		}

3. We send autoincrement only in case it is true.
Then how about sending nullability only in case it
is true? To save a bit of the network.

>  	}
>  	return 0;
>  }
> diff --git a/src/box/iproto_constants.h b/src/box/iproto_constants.h
> index fa9c029a2..030c25531 100644
> --- a/src/box/iproto_constants.h
> +++ b/src/box/iproto_constants.h
> @@ -132,6 +132,7 @@ enum iproto_metadata_key {
>  	IPROTO_FIELD_NAME = 0,
>  	IPROTO_FIELD_TYPE = 1,
>  	IPROTO_FIELD_COLL = 2,
> +	IPROTO_FIELD_NULLABLE = 3

4. Please, add a comma after 3 so as not to
change this line in the next commit.

>  };
>  
>  enum iproto_ballot_key {
> diff --git a/src/box/sql/select.c b/src/box/sql/select.c
> index 66e8c1274..b772bcead 100644
> --- a/src/box/sql/select.c
> +++ b/src/box/sql/select.c
> @@ -1836,7 +1837,10 @@ generate_column_metadata(struct Parse *pParse, struct SrcList *pTabList,
>  			} else {
>  				vdbe_set_metadata_col_name(v, i, zCol);
>  			}
> -
> +			bool is_nullable = space_def->fields[iCol].is_nullable;
> +			if (p->op == TK_COLUMN)
> +				vdbe_set_metadata_col_nullability(v, i,
> +								  is_nullable);

5. Please, wrap into {}.


More information about the Tarantool-patches mailing list