Tarantool development patches archive
 help / color / mirror / Atom feed
From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
To: tarantool-patches@freelists.org, "n.pettik" <korablev@tarantool.org>
Subject: [tarantool-patches] Re: [PATCH 6/8] sql: replace affinity with field type in struct Expr
Date: Tue, 5 Feb 2019 18:08:20 +0300	[thread overview]
Message-ID: <e62e4d70-fa58-4ef4-35ab-f1142f85a254@tarantool.org> (raw)
In-Reply-To: <3256389D-8BEA-4FB2-B214-D4F66067F333@tarantool.org>

Thanks for the fixes! See 5 comments below.

> diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c
> index 5676d0720..db8577d1c 100644
> --- a/src/box/sql/expr.c
> +++ b/src/box/sql/expr.c
> @@ -252,74 +244,57 @@ sql_expr_coll(Parse *parse, Expr *p, bool *is_explicit_coll, uint32_t *coll_id)
> -/*
> - * pExpr is a comparison expression, eg. '=', '<', IN(...) etc.
> - * idx_affinity is the affinity of an indexed column. Return true
> - * if the index with affinity idx_affinity may be used to implement
> - * the comparison in pExpr.
> +/**
> + * @param expr is a comparison expression, eg. '=', '<', IN(...) etc.
> + * @param field_type is the type of an indexed column.
> + * @retval Return true if the index with @field_type may be used to
> + * implement the comparison in expr.
>   */
> -int
> -sqlite3IndexAffinityOk(Expr * pExpr, char idx_affinity)
> +bool
> +sql_expr_cmp_type_is_compatible(struct Expr *expr, enum field_type field_type)
>  {
> -	char aff = comparisonAffinity(pExpr);
> -	switch (aff) {
> -	case AFFINITY_BLOB:
> -		return 1;
> -	case AFFINITY_TEXT:
> -		return idx_affinity == AFFINITY_TEXT;
> +	enum field_type type = expr_cmp_mutual_type(expr);
> +	switch (type) {
> +	case FIELD_TYPE_SCALAR:
> +		return true;
> +	case FIELD_TYPE_STRING:
> +		return field_type == FIELD_TYPE_STRING;

1. But type is never == FIELD_TYPE_STRING here. Because
expr_cmp_mutual_type() returns either SCALAR or NUMBER.
I added an assertion type != FIELD_TYPE_STRING and it did
not fail in tests.

>  	default:
> -		return sqlite3IsNumericAffinity(idx_affinity);
> +		return sql_type_is_numeric(field_type);

2. Also, I do not understand, why not to just use
field_type1_contains_type2(). sql_expr_cmp_type_is_compatible()
says, that it returns true, if a column of type field_type can
be used to "implement comparison" in an expression. So
this is the same as

     field_type1_contains_type2(field_type, expr_cmp_mutual_type(expr));

If I correctly understood what does it mean - "implement comparison".
Then I tried to replace sql_expr_cmp_type_is_compatible() with the
call above and the tests failed. Then I swapped the arguments:

     field_type1_contains_type2(expr_cmp_mutual_type(expr), field_type);

And the tests passed. Why?

>  	}
>  }
>  
> diff --git a/src/box/sql/select.c b/src/box/sql/select.c
> index ef4514374..9843eb4a5 100644
> --- a/src/box/sql/select.c
> +++ b/src/box/sql/select.c
> @@ -1728,38 +1727,31 @@ generateColumnNames(Parse * pParse,	/* Parser context */
>  		p = pEList->a[i].pExpr;
>  		if (NEVER(p == 0))
>  			continue;
> -		switch (p->affinity) {
> -		case AFFINITY_INTEGER:
> +		if (p->op == TK_VARIABLE)
> +			var_pos[var_count++] = i;

3. Why did you move these two lines out of 'switch:' clause? As I
understand, for field types INTEGER, NUMBER, STRING, SCALAR op
never == TK_VARIABLE. So this check now executes mostly without
necessity, and should be done only for FIELD_TYPE_BOOLEAN. I
did this and the tests passed:

	diff --git a/src/box/sql/select.c b/src/box/sql/select.c
	index 9843eb4a5..d8ab9a40d 100644
	--- a/src/box/sql/select.c
	+++ b/src/box/sql/select.c
	@@ -1727,8 +1727,6 @@ generateColumnNames(Parse * pParse,	/* Parser context */
	 		p = pEList->a[i].pExpr;
	 		if (NEVER(p == 0))
	 			continue;
	-		if (p->op == TK_VARIABLE)
	-			var_pos[var_count++] = i;
	 		switch (p->type) {
	 		case FIELD_TYPE_INTEGER:
	 			sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, "INTEGER",
	@@ -1747,6 +1745,8 @@ generateColumnNames(Parse * pParse,	/* Parser context */
	 					      SQLITE_TRANSIENT);
	 			break;
	 		case FIELD_TYPE_BOOLEAN:
	+			if (p->op == TK_VARIABLE)
	+				var_pos[var_count++] = i;
	 			sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, "BOOLEAN",
	 					      SQLITE_TRANSIENT);
	 			break;

> +		switch (p->type) {
> +		case FIELD_TYPE_INTEGER:
>  			sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, "INTEGER",
>  					      SQLITE_TRANSIENT);
>  			break;
> -		case AFFINITY_REAL:
> +		case FIELD_TYPE_NUMBER:
>  			sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, "NUMERIC",
>  					      SQLITE_TRANSIENT);
>  			break;
> -		case AFFINITY_TEXT:
> +		case FIELD_TYPE_STRING:
>  			sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, "TEXT",
>  					      SQLITE_TRANSIENT);
>  			break;
> -		case AFFINITY_BLOB:
> +		case FIELD_TYPE_SCALAR:
>  			sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, "BLOB",
>  					      SQLITE_TRANSIENT);
>  			break;
> -		default: ;
> -			char *type;
> -			/*
> -			 * For variables we set BOOLEAN type since
> -			 * unassigned bindings will be replaced
> -			 * with NULL automatically, i.e. without
> -			 * explicit call of sql_bind_value().
> -			 */
> -			if (p->op == TK_VARIABLE) {
> -				var_pos[var_count++] = i;
> -				type = "BOOLEAN";
> -			} else {
> -				type = "UNKNOWN";
> -			}
> -			sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, type,
> +		case FIELD_TYPE_BOOLEAN:
> +			sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, "BOOLEAN",
> +					      SQLITE_TRANSIENT);
> +			break;
> +		default:
> +			sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, "UNKNOWN",
>  					      SQLITE_TRANSIENT);
>  		}
>  		if (pEList->a[i].zName) {
> diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h
> index 79999509c..047a77b68 100644
> --- a/src/box/sql/sqliteInt.h
> +++ b/src/box/sql/sqliteInt.h
> @@ -2091,8 +2093,8 @@ typedef int ynVar;
>  struct Expr {
>  	u8 op;			/* Operation performed by this node */
>  	union {
> -		/** The affinity of the column. */
> -		enum affinity_type affinity;
> +		/** The Type of the column. */

4. 'Type' -> 'type'.

> +		enum field_type type;
>  		/** Conflict action for RAISE() function. */
>  		enum on_conflict_action on_conflict_action;
>  	};
> @@ -4267,26 +4281,30 @@ sql_index_type_str(struct sqlite3 *db, const struct index_def *idx_def);
>  /**
> - * Return the affinity character for a single column of a table.
> - * @param def space definition.
> - * @param idx column index.
> - * @retval AFFINITY
> + * Return the type of the expression pExpr.
> + *
> + * If pExpr is a column, a reference to a column via an 'AS' alias,
> + * or a sub-select with a column as the return value, then the
> + * type of that column is returned. Otherwise, type ANY is returned,
> + * indicating that the expression can feature any type.
> + *
> + * The WHERE clause expressions in the following statements all
> + * have an type:
> + *
> + * CREATE TABLE t1(a);
> + * SELECT * FROM t1 WHERE a;
> + * SELECT a AS b FROM t1 WHERE b;
> + * SELECT * FROM t1 WHERE (select a from t1);
>   */
> -char
> -sqlite3TableColumnAffinity(struct space_def *def, int idx);
> -
> -char sqlite3ExprAffinity(Expr * pExpr);
> +enum field_type
> +sql_expr_type(Expr *pExpr);

5. Expr -> struct Expr.

  reply	other threads:[~2019-02-05 15:08 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-28  9:34 [tarantool-patches] [PATCH 0/8] Eliminate affinity from source code Nikita Pettik
2018-12-28  9:34 ` [tarantool-patches] [PATCH 1/8] sql: remove SQLITE_ENABLE_UPDATE_DELETE_LIMIT define Nikita Pettik
2018-12-29 17:42   ` [tarantool-patches] " Vladislav Shpilevoy
2019-01-16 14:25     ` n.pettik
2018-12-28  9:34 ` [tarantool-patches] [PATCH 2/8] sql: use field type instead of affinity for type_def Nikita Pettik
2018-12-29 17:42   ` [tarantool-patches] " Vladislav Shpilevoy
2019-01-16 14:26     ` n.pettik
2018-12-28  9:34 ` [tarantool-patches] [PATCH 3/8] sql: remove numeric affinity Nikita Pettik
2018-12-29  9:01   ` [tarantool-patches] " Konstantin Osipov
2018-12-29 17:42   ` Vladislav Shpilevoy
2019-01-09  8:26     ` Konstantin Osipov
2019-01-16 14:26     ` n.pettik
2019-01-22 15:41       ` Vladislav Shpilevoy
2019-01-28 16:39         ` n.pettik
2019-01-30 13:04           ` Vladislav Shpilevoy
2019-02-01 16:39             ` n.pettik
2019-01-09  8:20   ` Konstantin Osipov
2018-12-28  9:34 ` [tarantool-patches] [PATCH 4/8] sql: replace affinity with field type for func Nikita Pettik
2018-12-28  9:34 ` [tarantool-patches] [PATCH 5/8] sql: replace field type with affinity for VDBE runtime Nikita Pettik
2018-12-29 17:42   ` [tarantool-patches] " Vladislav Shpilevoy
2019-01-16 14:26     ` n.pettik
2019-01-22 15:41       ` Vladislav Shpilevoy
2019-01-28 16:39         ` n.pettik
2019-01-30 13:04           ` Vladislav Shpilevoy
2019-02-01 16:39             ` n.pettik
2019-02-05 15:08               ` Vladislav Shpilevoy
2019-02-05 17:46                 ` n.pettik
2018-12-28  9:34 ` [tarantool-patches] [PATCH 6/8] sql: replace affinity with field type in struct Expr Nikita Pettik
2018-12-29 17:42   ` [tarantool-patches] " Vladislav Shpilevoy
2019-01-16 14:26     ` n.pettik
2019-01-22 15:41       ` Vladislav Shpilevoy
2019-01-28 16:39         ` n.pettik
2019-01-30 13:04           ` Vladislav Shpilevoy
2019-02-01 16:39             ` n.pettik
2019-02-05 15:08               ` Vladislav Shpilevoy [this message]
2019-02-05 17:46                 ` n.pettik
2018-12-28  9:34 ` [tarantool-patches] [PATCH 7/8] sql: clean-up affinity from SQL source code Nikita Pettik
2018-12-29 17:42   ` [tarantool-patches] " Vladislav Shpilevoy
2019-01-16 14:26     ` n.pettik
2019-01-22 15:41       ` Vladislav Shpilevoy
2019-01-28 16:40         ` n.pettik
2019-01-30 13:04           ` Vladislav Shpilevoy
2019-02-01 16:39             ` n.pettik
2019-02-05 15:08               ` Vladislav Shpilevoy
2019-02-05 17:46                 ` n.pettik
2018-12-28  9:34 ` [tarantool-patches] [PATCH 8/8] Remove affinity from field definition Nikita Pettik
2019-02-05 19:41 ` [tarantool-patches] Re: [PATCH 0/8] Eliminate affinity from source code Vladislav Shpilevoy
2019-02-08 13:37 ` Kirill Yukhin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e62e4d70-fa58-4ef4-35ab-f1142f85a254@tarantool.org \
    --to=v.shpilevoy@tarantool.org \
    --cc=korablev@tarantool.org \
    --cc=tarantool-patches@freelists.org \
    --subject='[tarantool-patches] Re: [PATCH 6/8] sql: replace affinity with field type in struct Expr' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox