From: "n.pettik" <korablev@tarantool.org> To: tarantool-patches@freelists.org Cc: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> Subject: [tarantool-patches] Re: [PATCH 6/8] sql: replace affinity with field type in struct Expr Date: Tue, 5 Feb 2019 20:46:21 +0300 [thread overview] Message-ID: <1F427E20-6022-4D86-8CE0-15BC01939CBF@tarantool.org> (raw) In-Reply-To: <e62e4d70-fa58-4ef4-35ab-f1142f85a254@tarantool.org> >> 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. Well, that is actually true. See below, I removed this function at all. > >> 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? I guess because expr_cmp_mutal_type returns SCALAR or NUMBER as you noticed. The first one is compatible with all scalar types and not vice versa. So ..._type2(expr_cmp_mutual_type(expr), field_type) is not the same as …_type2(field_type, expr_cmp_mutual_type(expr)); I’ve made comparative table and …_type2(expr_cmp_mutal_type, field_type) gives us the same results as sql_expr_type_is_compatible. Hence, I will remove this function and use …_type2() instead. Diff: diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c index db8577d1c..36da1ecdb 100644 --- a/src/box/sql/expr.c +++ b/src/box/sql/expr.c @@ -252,12 +252,7 @@ sql_type_result(enum field_type lhs, enum field_type rhs) return FIELD_TYPE_SCALAR; } -/** - * pExpr is a comparison operator. Return the type affinity - * that should be applied to both operands prior to doing - * the comparison. - */ -static enum field_type +enum field_type expr_cmp_mutual_type(struct Expr *pExpr) { assert(pExpr->op == TK_EQ || pExpr->op == TK_IN || pExpr->op == TK_LT || @@ -278,25 +273,6 @@ expr_cmp_mutual_type(struct Expr *pExpr) return type; } -/** - * @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. - */ -bool -sql_expr_cmp_type_is_compatible(struct Expr *expr, enum field_type field_type) -{ - 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; - default: - return sql_type_is_numeric(field_type); - } -} diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h index 047a77b68..61f316550 100644 --- a/src/box/sql/sqliteInt.h +++ b/src/box/sql/sqliteInt.h @@ -4284,8 +4284,13 @@ sql_emit_table_types(struct Vdbe *v, struct space_def *def, int reg); enum field_type sql_type_result(enum field_type lhs, enum field_type rhs); -bool -sql_expr_cmp_type_is_compatible(struct Expr *expr, enum field_type idx_type); +/** + * pExpr is a comparison operator. Return the type affinity + * that should be applied to both operands prior to doing + * the comparison. + */ +enum field_type +expr_cmp_mutual_type(struct Expr *pExpr); diff --git a/src/box/sql/where.c b/src/box/sql/where.c index 219009ef8..6a47f8c99 100644 --- a/src/box/sql/where.c +++ b/src/box/sql/where.c @@ -298,7 +298,9 @@ whereScanNext(WhereScan * pScan) /* Verify the affinity and collating sequence match */ if ((pTerm->eOperator & WO_ISNULL) == 0) { pX = pTerm->pExpr; - if (!sql_expr_cmp_type_is_compatible(pX, pScan->idx_type)) + enum field_type expr_type = + expr_cmp_mutual_type(pX); + if (!field_type1_contains_type2(expr_type, pScan->idx_type)) continue; if (pScan->is_column_seen) { Parse *pParse = @@ -690,7 +692,6 @@ termCanDriveIndex(WhereTerm * pTerm, /* WHERE clause term to check */ Bitmask notReady /* Tables in outer loops of the join */ ) { - char aff; if (pTerm->leftCursor != pSrc->iCursor) return 0; if ((pTerm->eOperator & WO_EQ) == 0) @@ -699,8 +700,9 @@ termCanDriveIndex(WhereTerm * pTerm, /* WHERE clause term to check */ return 0; if (pTerm->u.leftColumn < 0) return 0; - aff = pSrc->pTab->aCol[pTerm->u.leftColumn].affinity; - if (!sql_expr_cmp_type_is_compatible(pTerm->pExpr, aff)) + enum field_type type = pSrc->pTab->def->fields[pTerm->u.leftColumn].type; + enum field_type expr_type = expr_cmp_mutual_type(pTerm->pExpr); + if (!field_type1_contains_type2(expr_type, type)) return 0; return 1; } (The last change is related to dead code). >> 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: You are absolutely right, just wanted to make it look better (indeed, not the best try). Returned back: 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; >> 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’. diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h index 047a77b68..6e4ead573 100644 --- a/src/box/sql/sqliteInt.h +++ b/src/box/sql/sqliteInt.h @@ -2093,7 +2093,7 @@ typedef int ynVar; struct Expr { u8 op; /* Operation performed by this node */ union { - /** The Type of the column. */ + /** The type of the column. */ >> @@ -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. @@ -4304,7 +4304,7 @@ sql_expr_cmp_type_is_compatible(struct Expr *expr, enum field_type idx_type); * SELECT * FROM t1 WHERE (select a from t1); */ enum field_type -sql_expr_type(Expr *pExpr); +sql_expr_type(struct Expr *pExpr);
next prev parent reply other threads:[~2019-02-05 17:46 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 2019-02-05 17:46 ` n.pettik [this message] 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=1F427E20-6022-4D86-8CE0-15BC01939CBF@tarantool.org \ --to=korablev@tarantool.org \ --cc=tarantool-patches@freelists.org \ --cc=v.shpilevoy@tarantool.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