From: Kirill Shcherbatov <kshcherbatov@tarantool.org> To: tarantool-patches@freelists.org Cc: v.shpilevoy@tarantool.org, Kirill Shcherbatov <kshcherbatov@tarantool.org> Subject: [tarantool-patches] [PATCH v5 3/3] sql: space_def* instead of Table* in Expr Date: Fri, 11 May 2018 11:49:47 +0300 [thread overview] Message-ID: <bc6936ccf8dddca90350a05b82b71f3c95caded9.1526028449.git.kshcherbatov@tarantool.org> (raw) In-Reply-To: <cover.1526028449.git.kshcherbatov@tarantool.org> In-Reply-To: <cover.1526028449.git.kshcherbatov@tarantool.org> This patch allows to remove Checks from SQL to server as sqlite3ResolveSelfReference requires Expr structure pointer. Part of #3272. --- src/box/field_def.c | 1 + src/box/field_def.h | 14 ++++++ src/box/sql.c | 10 ++--- src/box/sql/build.c | 48 +++++++++++--------- src/box/sql/delete.c | 4 +- src/box/sql/expr.c | 115 +++++++++++++++++++++++++++--------------------- src/box/sql/fkey.c | 13 +++--- src/box/sql/insert.c | 39 +++++++++------- src/box/sql/pragma.c | 8 ++-- src/box/sql/resolve.c | 10 ++--- src/box/sql/select.c | 26 ++++++----- src/box/sql/sqliteInt.h | 41 +++++------------ src/box/sql/update.c | 35 +++++++-------- src/box/sql/vdbeaux.c | 28 +++--------- src/box/sql/where.c | 13 +++--- src/box/sql/wherecode.c | 19 +++++--- src/box/sql/whereexpr.c | 2 +- 17 files changed, 219 insertions(+), 207 deletions(-) diff --git a/src/box/field_def.c b/src/box/field_def.c index 010b3b7..cdae5bc 100644 --- a/src/box/field_def.c +++ b/src/box/field_def.c @@ -100,6 +100,7 @@ const struct opt_def field_def_reg[] = { const struct field_def field_def_default = { .type = FIELD_TYPE_ANY, + .affinity = SQLITE_AFF_UNDEFINED, .name = NULL, .is_nullable = false, .nullable_action = ON_CONFLICT_ACTION_DEFAULT, diff --git a/src/box/field_def.h b/src/box/field_def.h index a42beab..b210756 100644 --- a/src/box/field_def.h +++ b/src/box/field_def.h @@ -70,6 +70,15 @@ enum on_conflict_action { on_conflict_action_MAX }; +enum affinity_type { + SQLITE_AFF_UNDEFINED = 0, + SQLITE_AFF_BLOB = 'A', + SQLITE_AFF_TEXT = 'B', + SQLITE_AFF_NUMERIC = 'C', + SQLITE_AFF_INTEGER = 'D', + SQLITE_AFF_REAL = 'E', +}; + /** \endcond public */ extern const char *field_type_strs[]; @@ -102,6 +111,11 @@ struct field_def { * then UNKNOWN is stored for it. */ enum field_type type; + /** + * Affinity type for comparations in SQL. + * FIXME: Remove affinity after types redesign in SQL. + */ + enum affinity_type affinity; /** 0-terminated field name. */ char *name; /** True, if a field can store NULL. */ diff --git a/src/box/sql.c b/src/box/sql.c index 7d48cdc..5e8c96d 100644 --- a/src/box/sql.c +++ b/src/box/sql.c @@ -1428,7 +1428,6 @@ static const char *convertSqliteAffinity(int affinity, bool allow_nulls) */ int tarantoolSqlite3MakeTableFormat(Table *pTable, void *buf) { - struct Column *aCol = pTable->aCol; const struct Enc *enc = get_enc(buf); const struct space_def *def = pTable->def; assert(def != NULL); @@ -1471,8 +1470,9 @@ int tarantoolSqlite3MakeTableFormat(Table *pTable, void *buf) if (i == pk_forced_int) { t = "integer"; } else { - t = aCol[i].affinity == SQLITE_AFF_BLOB ? "scalar" : - convertSqliteAffinity(aCol[i].affinity, + char affinity = def->fields[i].affinity; + t = affinity == SQLITE_AFF_BLOB ? "scalar" : + convertSqliteAffinity(affinity, def->fields[i].is_nullable); } p = enc->encode_str(p, t, strlen(t)); @@ -1529,7 +1529,6 @@ int tarantoolSqlite3MakeTableOpts(Table *pTable, const char *zSql, void *buf) */ int tarantoolSqlite3MakeIdxParts(SqliteIndex *pIndex, void *buf) { - struct Column *aCol = pIndex->pTable->aCol; struct space_def *def = pIndex->pTable->def; assert(def != NULL); @@ -1566,7 +1565,8 @@ int tarantoolSqlite3MakeIdxParts(SqliteIndex *pIndex, void *buf) if (pk_forced_int == col) { t = "integer"; } else { - t = convertSqliteAffinity(aCol[col].affinity, + char affinity = def->fields[col].affinity; + t = convertSqliteAffinity(affinity, def->fields[col].is_nullable); } /* do not decode default collation */ diff --git a/src/box/sql/build.c b/src/box/sql/build.c index a02fe89..f082d01 100644 --- a/src/box/sql/build.c +++ b/src/box/sql/build.c @@ -703,7 +703,7 @@ sqlite3AddColumn(Parse * pParse, Token * pName, Token * pType) * TODO: since SQL standard prohibits column creation without * specified type, the code below should emit an error. */ - pCol->affinity = SQLITE_AFF_BLOB; + column_def->affinity = SQLITE_AFF_BLOB; pCol->szEst = 1; column_def->type = FIELD_TYPE_SCALAR; } else { @@ -714,14 +714,14 @@ sqlite3AddColumn(Parse * pParse, Token * pName, Token * pType) pType->n == 7) || (sqlite3StrNICmp(pType->z, "INT", 3) == 0 && pType->n == 3)) { - pCol->affinity = SQLITE_AFF_INTEGER; + column_def->affinity = SQLITE_AFF_INTEGER; column_def->type = FIELD_TYPE_INTEGER; } else { zType = sqlite3_malloc(pType->n + 1); memcpy(zType, pType->z, pType->n); zType[pType->n] = 0; sqlite3Dequote(zType); - pCol->affinity = sqlite3AffinityType(zType, 0); + column_def->affinity = sqlite3AffinityType(zType, 0); sqlite3_free(zType); column_def->type = FIELD_TYPE_SCALAR; } @@ -1034,8 +1034,10 @@ sqlite3AddCollateType(Parse * pParse, Token * pToken) */ for (pIdx = p->pIndex; pIdx; pIdx = pIdx->pNext) { assert(pIdx->nColumn == 1); - if (pIdx->aiColumn[0] == i) - pIdx->coll_array[0] = sql_column_collation(p, i); + if (pIdx->aiColumn[0] == i) { + pIdx->coll_array[0] = + sql_column_collation(p->def, i); + } } } sqlite3DbFree(db, zColl); @@ -1049,10 +1051,10 @@ sqlite3AddCollateType(Parse * pParse, Token * pToken) * @retval Pointer to collation. */ struct coll * -sql_column_collation(Table *table, uint32_t column) +sql_column_collation(struct space_def *def, uint32_t column) { - assert(table != NULL); - uint32_t space_id = SQLITE_PAGENO_TO_SPACEID(table->tnum); + assert(def != NULL); + uint32_t space_id = def->id; struct space *space = space_by_id(space_id); /* * It is not always possible to fetch collation directly @@ -1067,9 +1069,9 @@ sql_column_collation(Table *table, uint32_t column) * SQL specific structures. */ if (space == NULL || space_index(space, 0) == NULL) { - assert(column < (uint32_t)table->def->field_count); + assert(column < (uint32_t)def->field_count); struct coll *coll = - coll_by_id(table->def->fields[column].coll_id); + coll_by_id(def->fields[column].coll_id); return coll; } @@ -1325,18 +1327,19 @@ createTableStmt(sqlite3 * db, Table * p) k += sqlite3Strlen30(&zStmt[k]); zSep = zSep2; identPut(zStmt, &k, p->def->fields[i].name); - assert(pCol->affinity - SQLITE_AFF_BLOB >= 0); - assert(pCol->affinity - SQLITE_AFF_BLOB < ArraySize(azType)); - testcase(pCol->affinity == SQLITE_AFF_BLOB); - testcase(pCol->affinity == SQLITE_AFF_TEXT); - testcase(pCol->affinity == SQLITE_AFF_NUMERIC); - testcase(pCol->affinity == SQLITE_AFF_INTEGER); - testcase(pCol->affinity == SQLITE_AFF_REAL); - - zType = azType[pCol->affinity - SQLITE_AFF_BLOB]; + char affinity = p->def->fields[i].affinity; + assert(affinity - SQLITE_AFF_BLOB >= 0); + assert(affinity - SQLITE_AFF_BLOB < ArraySize(azType)); + testcase(affinity == SQLITE_AFF_BLOB); + testcase(affinity == SQLITE_AFF_TEXT); + testcase(affinity == SQLITE_AFF_NUMERIC); + testcase(affinity == SQLITE_AFF_INTEGER); + testcase(affinity == SQLITE_AFF_REAL); + + zType = azType[affinity - SQLITE_AFF_BLOB]; len = sqlite3Strlen30(zType); - assert(pCol->affinity == SQLITE_AFF_BLOB - || pCol->affinity == sqlite3AffinityType(zType, 0)); + assert(affinity == SQLITE_AFF_BLOB + || affinity == sqlite3AffinityType(zType, 0)); memcpy(&zStmt[k], zType, len); k += len; assert(k <= n); @@ -1845,6 +1848,7 @@ sqlite3EndTable(Parse * pParse, /* Parse context */ */ if (db->init.busy) p->tnum = db->init.newTnum; + p->def->id = SQLITE_PAGENO_TO_SPACEID(p->tnum); assert(p->def->opts.is_view == (p->pSelect != NULL)); if (!p->def->opts.is_view) { @@ -3098,7 +3102,7 @@ sqlite3CreateIndex(Parse * pParse, /* All information about this parse */ goto exit_create_index; } } else if (j >= 0) { - coll = sql_column_collation(pTab, j); + coll = sql_column_collation(pTab->def, j); } else { coll = NULL; } diff --git a/src/box/sql/delete.c b/src/box/sql/delete.c index 37baca2..5056005 100644 --- a/src/box/sql/delete.c +++ b/src/box/sql/delete.c @@ -431,7 +431,7 @@ sqlite3DeleteFrom(Parse * pParse, /* The parser context */ if (!isView) { for (i = 0; i < nPk; i++) { assert(pPk->aiColumn[i] >= 0); - sqlite3ExprCodeGetColumnOfTable(v, pTab, + sqlite3ExprCodeGetColumnOfTable(v, pTab->def, iTabCur, pPk-> aiColumn[i], @@ -747,7 +747,7 @@ sqlite3GenerateRowDelete(Parse * pParse, /* Parsing context */ testcase(mask != 0xffffffff && iCol == 32); if (mask == 0xffffffff || (iCol <= 31 && (mask & MASKBIT32(iCol)) != 0)) { - sqlite3ExprCodeGetColumnOfTable(v, pTab, + sqlite3ExprCodeGetColumnOfTable(v, pTab->def, iDataCur, iCol, iOld + iCol + 1); diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c index 119940c..8b34c57 100644 --- a/src/box/sql/expr.c +++ b/src/box/sql/expr.c @@ -46,10 +46,11 @@ static int exprCodeVector(Parse * pParse, Expr * p, int *piToFree); * Return the affinity character for a single column of a table. */ char -sqlite3TableColumnAffinity(Table * pTab, int iCol) +sqlite3TableColumnAffinity(struct space_def *def, int iCol) { - assert(iCol < (int)pTab->def->field_count); - return iCol >= 0 ? pTab->aCol[iCol].affinity : SQLITE_AFF_INTEGER; + assert(iCol < (int)def->field_count); + return iCol >= 0 ? def->fields[iCol].affinity : + SQLITE_AFF_INTEGER; } /* @@ -90,7 +91,8 @@ sqlite3ExprAffinity(Expr * pExpr) } #endif if (op == TK_AGG_COLUMN || op == TK_COLUMN) { - return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn); + return sqlite3TableColumnAffinity(pExpr->space_def, + pExpr->iColumn); } if (op == TK_SELECT_COLUMN) { assert(pExpr->pLeft->flags & EP_xIsSelect); @@ -179,13 +181,13 @@ sql_expr_coll(Parse *parse, Expr *p, bool *is_found) } if ((op == TK_AGG_COLUMN || op == TK_COLUMN || op == TK_REGISTER || op == TK_TRIGGER) && - p->pTab != 0) { + p->space_def != NULL) { /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally * a TK_COLUMN but was previously evaluated and cached in a register */ int j = p->iColumn; if (j >= 0) { - coll = sql_column_collation(p->pTab, j); + coll = sql_column_collation(p->space_def, j); *is_found = true; } break; @@ -2132,10 +2134,11 @@ sqlite3ExprCanBeNull(const Expr * p) case TK_BLOB: return 0; case TK_COLUMN: - assert(p->pTab != 0); + assert(p->space_def != NULL); return ExprHasProperty(p, EP_CanBeNull) || (p->iColumn >= 0 - && table_column_is_nullable(p->pTab, p->iColumn)); + && space_def_column_is_nullable(p->space_def, + p->iColumn)); default: return 1; } @@ -2435,7 +2438,9 @@ sqlite3FindInIndex(Parse * pParse, /* Parsing context */ for (i = 0; i < nExpr && affinity_ok; i++) { Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i); int iCol = pEList->a[i].pExpr->iColumn; - char idxaff = sqlite3TableColumnAffinity(pTab, iCol); /* RHS table */ + /* RHS table */ + char idxaff = + sqlite3TableColumnAffinity(pTab->def, iCol); char cmpaff = sqlite3CompareAffinity(pLhs, idxaff); testcase(cmpaff == SQLITE_AFF_BLOB); testcase(cmpaff == SQLITE_AFF_TEXT); @@ -3175,8 +3180,9 @@ sqlite3ExprCodeIN(Parse * pParse, /* Parsing and code generating context */ struct Index *pk = sqlite3PrimaryKeyIndex(tab); assert(pk); + char affinity = tab->def->fields[pk->aiColumn[0]].affinity; if (pk->nColumn == 1 - && tab->aCol[pk->aiColumn[0]].affinity == 'D' + && affinity == 'D' && pk->aiColumn[0] < nVector) { int reg_pk = rLhs + pk->aiColumn[0]; sqlite3VdbeAddOp2(v, OP_MustBeInt, reg_pk, destIfFalse); @@ -3519,45 +3525,48 @@ sqlite3ExprCodeLoadIndexColumn(Parse * pParse, /* The parsing context */ sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut); } else { - sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pIdx->pTable, + sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pIdx->pTable->def, iTabCur, iTabCol, regOut); } } -/* +/** * Generate code to extract the value of the iCol-th column of a table. + * @param v The VDBE under construction. + * @param space_def Space definition. + * @param iTabCur The PK cursor. + * @param iCol Index of the column to extract. + * @param regOut Extract the value into this register. */ void -sqlite3ExprCodeGetColumnOfTable(Vdbe * v, /* The VDBE under construction */ - Table * pTab, /* The table containing the value */ - int iTabCur, /* The PK cursor */ - int iCol, /* Index of the column to extract */ - int regOut /* Extract the value into this register */ - ) +sqlite3ExprCodeGetColumnOfTable(Vdbe * v, struct space_def *space_def, + int iTabCur, int iCol, int regOut) { sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut); if (iCol >= 0) { - sqlite3ColumnDefault(v, pTab, iCol, regOut); + sqlite3ColumnDefault(v, space_def, iCol, regOut); } } -/* +/** * Generate code that will extract the iColumn-th column from * table pTab and store the column value in a register. * - * An effort is made to store the column value in register iReg. This - * is not garanteeed for GetColumn() - the result can be stored in - * any register. But the result is guaranteed to land in register iReg - * for GetColumnToReg(). + * An effort is made to store the column value in register iReg. + * This is not garanteeed for GetColumn() - the result can be + * stored in any register. But the result is guaranteed to land + * in register iReg for GetColumnToReg(). + * @param pParse Parsing and code generating context. + * @param space_def Space definition. + * @param iColumn Index of the table column. + * @param iTable The cursor pointing to the table. + * @param iReg Store results here. + * @param p5 P5 value for OP_Column + FLAGS. + * @return iReg value. */ int -sqlite3ExprCodeGetColumn(Parse * pParse, /* Parsing and code generating context */ - Table * pTab, /* Description of the table we are reading from */ - int iColumn, /* Index of the table column */ - int iTable, /* The cursor pointing to the table */ - int iReg, /* Store results here */ - u8 p5 /* P5 value for OP_Column + FLAGS */ - ) +sqlite3ExprCodeGetColumn(Parse * pParse, struct space_def * space_def, + int iColumn, int iTable, int iReg, u8 p5) { Vdbe *v = pParse->pVdbe; int i; @@ -3572,7 +3581,7 @@ sqlite3ExprCodeGetColumn(Parse * pParse, /* Parsing and code generating context } } assert(v != 0); - sqlite3ExprCodeGetColumnOfTable(v, pTab, iTable, iColumn, iReg); + sqlite3ExprCodeGetColumnOfTable(v, space_def, iTable, iColumn, iReg); if (p5) { sqlite3VdbeChangeP5(v, p5); } else { @@ -3581,16 +3590,22 @@ sqlite3ExprCodeGetColumn(Parse * pParse, /* Parsing and code generating context return iReg; } +/** + * Generate code that will extract the iColumn-th column from + * table pTab and store the column value in a register, copy the + * result. + * @param pParse Parsing and code generating context. + * @param space_def Space definition. + * @param iColumn Index of the table column. + * @param iTable The cursor pointing to the table. + * @param iReg Store results here. + */ void -sqlite3ExprCodeGetColumnToReg(Parse * pParse, /* Parsing and code generating context */ - Table * pTab, /* Description of the table we are reading from */ - int iColumn, /* Index of the table column */ - int iTable, /* The cursor pointing to the table */ - int iReg /* Store results here */ - ) +sqlite3ExprCodeGetColumnToReg(Parse * pParse, struct space_def * space_def, + int iColumn, int iTable, int iReg) { int r1 = - sqlite3ExprCodeGetColumn(pParse, pTab, iColumn, iTable, iReg, 0); + sqlite3ExprCodeGetColumn(pParse, space_def, iColumn, iTable, iReg, 0); if (r1 != iReg) sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, r1, iReg); } @@ -3777,7 +3792,7 @@ sqlite3ExprCodeTarget(Parse * pParse, Expr * pExpr, int target) iTab = pParse->iSelfTab; } } - return sqlite3ExprCodeGetColumn(pParse, pExpr->pTab, + return sqlite3ExprCodeGetColumn(pParse, pExpr->space_def, pExpr->iColumn, iTab, target, pExpr->op2); } @@ -4241,23 +4256,21 @@ sqlite3ExprCodeTarget(Parse * pParse, Expr * pExpr, int target) * p1==1 -> old.a p1==4 -> new.a * p1==2 -> old.b p1==5 -> new.b */ - Table *pTab = pExpr->pTab; + struct space_def *def = pExpr->space_def; int p1 = - pExpr->iTable * (pTab->def->field_count + 1) + 1 + + pExpr->iTable * (def->field_count + 1) + 1 + pExpr->iColumn; assert(pExpr->iTable == 0 || pExpr->iTable == 1); assert(pExpr->iColumn >= 0 - && pExpr->iColumn < (int)pTab->def->field_count); - assert(pTab->iPKey < 0 - || pExpr->iColumn != pTab->iPKey); + && pExpr->iColumn < (int)def->field_count); assert(p1 >= 0 && p1 < - ((int)pTab->def->field_count * 2 + 2)); + ((int)def->field_count * 2 + 2)); sqlite3VdbeAddOp2(v, OP_Param, p1, target); VdbeComment((v, "%s.%s -> $%d", (pExpr->iTable ? "new" : "old"), - pExpr->pTab->def->fields[pExpr->iColumn].name, + def->fields[pExpr->iColumn].name, target)); #ifndef SQLITE_OMIT_FLOATING_POINT @@ -4267,9 +4280,9 @@ sqlite3ExprCodeTarget(Parse * pParse, Expr * pExpr, int target) * EVIDENCE-OF: R-60985-57662 SQLite will convert the value back to * floating point when extracting it from the record. */ + char affinity = def->fields[pExpr->iColumn].affinity; if (pExpr->iColumn >= 0 - && pTab->aCol[pExpr->iColumn].affinity == - SQLITE_AFF_REAL) { + && affinity == SQLITE_AFF_REAL) { sqlite3VdbeAddOp1(v, OP_RealAffinity, target); } #endif @@ -5440,8 +5453,8 @@ analyzeAggregate(Walker * pWalker, Expr * pExpr) pAggInfo)) >= 0) { pCol = &pAggInfo->aCol[k]; - pCol->pTab = - pExpr->pTab; + pCol->space_def = + pExpr->space_def; pCol->iTable = pExpr->iTable; pCol->iColumn = diff --git a/src/box/sql/fkey.c b/src/box/sql/fkey.c index 916b346..f14a60d 100644 --- a/src/box/sql/fkey.c +++ b/src/box/sql/fkey.c @@ -298,7 +298,7 @@ sqlite3FkLocateIndex(Parse * pParse, /* Parse context to store any error in */ * unusable. Bail out early in this case. */ struct coll *def_coll; - def_coll = sql_column_collation(pParent, + def_coll = sql_column_collation(pParent->def, iCol); struct coll *coll; coll = sql_index_collation(pIdx, i); @@ -526,15 +526,14 @@ exprTableRegister(Parse * pParse, /* Parsing and code generating context */ ) { Expr *pExpr; - Column *pCol; sqlite3 *db = pParse->db; pExpr = sqlite3Expr(db, TK_REGISTER, 0); if (pExpr) { if (iCol >= 0 && iCol != pTab->iPKey) { - pCol = &pTab->aCol[iCol]; pExpr->iTable = regBase + iCol + 1; - pExpr->affinity = pCol->affinity; + char affinity = pTab->def->fields[iCol].affinity; + pExpr->affinity = affinity; pExpr = sqlite3ExprAddCollateString(pParse, pExpr, "binary"); } else { @@ -551,14 +550,14 @@ exprTableRegister(Parse * pParse, /* Parsing and code generating context */ */ static Expr * exprTableColumn(sqlite3 * db, /* The database connection */ - Table * pTab, /* The table whose column is desired */ + struct space_def *def, int iCursor, /* The open cursor on the table */ i16 iCol /* The column that is wanted */ ) { Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0); if (pExpr) { - pExpr->pTab = pTab; + pExpr->space_def = def; pExpr->iTable = iCursor; pExpr->iColumn = iCol; } @@ -671,7 +670,7 @@ fkScanChildren(Parse * pParse, /* Parse context */ i16 iCol = pIdx->aiColumn[i]; assert(iCol >= 0); pLeft = exprTableRegister(pParse, pTab, regData, iCol); - pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, + pRight = exprTableColumn(db, pTab->def, pSrc->a[0].iCursor, iCol); pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight); pAll = sqlite3ExprAnd(db, pAll, pEq); diff --git a/src/box/sql/insert.c b/src/box/sql/insert.c index c272ae1..8ecfe10 100644 --- a/src/box/sql/insert.c +++ b/src/box/sql/insert.c @@ -90,7 +90,6 @@ sqlite3IndexAffinityStr(sqlite3 * db, Index * pIdx) */ int n; int nColumn = index_column_count(pIdx); - Table *pTab = pIdx->pTable; pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, nColumn + 1); if (!pIdx->zColAff) { @@ -100,7 +99,9 @@ sqlite3IndexAffinityStr(sqlite3 * db, Index * pIdx) for (n = 0; n < nColumn; n++) { i16 x = pIdx->aiColumn[n]; if (x >= 0) { - pIdx->zColAff[n] = pTab->aCol[x].affinity; + char affinity = pIdx->pTable-> + def->fields[x].affinity; + pIdx->zColAff[n] = affinity; } else { char aff; assert(x == XN_EXPR); @@ -154,7 +155,8 @@ sqlite3TableAffinity(Vdbe * v, Table * pTab, int iReg) } for (i = 0; i < (int)pTab->def->field_count; i++) { - zColAff[i] = pTab->aCol[i].affinity; + char affinity = pTab->def->fields[i].affinity; + zColAff[i] = affinity; } do { zColAff[i--] = 0; @@ -1115,7 +1117,7 @@ sqlite3GenerateConstraintChecks(Parse * pParse, /* The parser context */ /* Don't bother checking for NOT NULL on columns that do not change */ continue; } - if (table_column_is_nullable(pTab, i) + if (space_def_column_is_nullable(pTab->def, i) || (pTab->tabFlags & TF_Autoincrement && pTab->iAutoIncPKey == i)) continue; /* This column is allowed to be NULL */ @@ -1796,19 +1798,22 @@ xferOptimization(Parse * pParse, /* Parser context */ return 0; /* Both tables must have the same INTEGER PRIMARY KEY */ } for (i = 0; i < (int)pDest->def->field_count; i++) { - Column *pDestCol = &pDest->aCol[i]; - Column *pSrcCol = &pSrc->aCol[i]; - if (pDestCol->affinity != pSrcCol->affinity) { - return 0; /* Affinity must be the same on all columns */ - } - if (sql_column_collation(pDest, i) != - sql_column_collation(pSrc, i)) { - return 0; /* Collating sequence must be the same on all columns */ - } - if (!table_column_is_nullable(pDest, i) - && table_column_is_nullable(pSrc, i)) { - return 0; /* tab2 must be NOT NULL if tab1 is */ - } + char pdest_affinity = pDest->def->fields[i].affinity; + char psrc_affinity = pSrc->def->fields[i].affinity; + /* Affinity must be the same on all columns. */ + if (pdest_affinity != psrc_affinity) + return 0; + /* + * Collating sequence must be the same on all + * columns. + */ + if (sql_column_collation(pDest->def, i) != + sql_column_collation(pSrc->def, i)) + return 0; + /* The tab2 must be NOT NULL if tab1 is */ + if (!space_def_column_is_nullable(pDest->def, i) + && space_def_column_is_nullable(pSrc->def, i)) + return 0; /* Default values for second and subsequent columns need to match. */ if (i > 0) { uint32_t src_space_id = diff --git a/src/box/sql/pragma.c b/src/box/sql/pragma.c index 250c402..0207ee8 100644 --- a/src/box/sql/pragma.c +++ b/src/box/sql/pragma.c @@ -373,7 +373,9 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */ i; k++) { } } - bool nullable = table_column_is_nullable(pTab, i); + bool nullable = + space_def_column_is_nullable( + pTab->def, i); uint32_t space_id = SQLITE_PAGENO_TO_SPACEID( pTab->tnum); @@ -691,7 +693,7 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */ iKey, regRow); sqlite3ColumnDefault(v, - pTab, + pTab->def, iKey, regRow); sqlite3VdbeAddOp2(v, @@ -708,7 +710,7 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */ } else { for (j = 0; j < pFK->nCol; j++) { sqlite3ExprCodeGetColumnOfTable - (v, pTab, 0, + (v, pTab->def, 0, aiCols ? aiCols[j] : pFK->aCol[j]. iFrom, regRow + j); diff --git a/src/box/sql/resolve.c b/src/box/sql/resolve.c index f95ef27..35adb10 100644 --- a/src/box/sql/resolve.c +++ b/src/box/sql/resolve.c @@ -227,7 +227,7 @@ lookupName(Parse * pParse, /* The parsing context */ /* Initialize the node to no-match */ pExpr->iTable = -1; - pExpr->pTab = 0; + pExpr->space_def = NULL; ExprSetVVAProperty(pExpr, EP_NoReduce); /* Start at the inner-most context and move outward until a match is found */ @@ -300,7 +300,7 @@ lookupName(Parse * pParse, /* The parsing context */ } if (pMatch) { pExpr->iTable = pMatch->iCursor; - pExpr->pTab = pMatch->pTab; + pExpr->space_def = pMatch->pTab->def; /* RIGHT JOIN not (yet) supported */ assert((pMatch->fg.jointype & JT_RIGHT) == 0); if ((pMatch->fg.jointype & JT_LEFT) != 0) { @@ -364,7 +364,7 @@ lookupName(Parse * pParse, /* The parsing context */ : (((u32) 1) << iCol)); } pExpr->iColumn = (i16) iCol; - pExpr->pTab = pTab; + pExpr->space_def = pTab->def; isTrigger = 1; } } @@ -498,9 +498,9 @@ sqlite3CreateColumnExpr(sqlite3 * db, SrcList * pSrc, int iSrc, int iCol) Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0); if (p) { struct SrcList_item *pItem = &pSrc->a[iSrc]; - p->pTab = pItem->pTab; + p->space_def = pItem->pTab->def; p->iTable = pItem->iCursor; - if (p->pTab->iPKey == iCol) { + if (pItem->pTab->iPKey == iCol) { p->iColumn = -1; } else { p->iColumn = (ynVar) iCol; diff --git a/src/box/sql/select.c b/src/box/sql/select.c index 32a8e08..5bd958a 100644 --- a/src/box/sql/select.c +++ b/src/box/sql/select.c @@ -1636,7 +1636,7 @@ columnTypeImpl(NameContext * pNC, Expr * pExpr, break; } - assert(pTab && pExpr->pTab == pTab); + assert(pTab != NULL && pExpr->space_def == pTab->def); if (pS) { /* The "table" is actually a sub-select or a view in the FROM clause * of the SELECT statement. Return the declaration type and origin @@ -1846,19 +1846,23 @@ sqlite3ColumnsFromExprList(Parse * pParse, /* Parsing context */ /* If the column contains an "AS <name>" phrase, use <name> as the name */ } else { Expr *pColExpr = p; /* The expression that is the result column name */ - Table *pTab; /* Table associated with this expression */ + struct space_def *space_def; while (pColExpr->op == TK_DOT) { pColExpr = pColExpr->pRight; assert(pColExpr != 0); } if (pColExpr->op == TK_COLUMN - && ALWAYS(pColExpr->pTab != 0)) { + && ALWAYS(pColExpr->space_def != NULL)) { /* For columns use the column name name */ int iCol = pColExpr->iColumn; - pTab = pColExpr->pTab; + space_def = pColExpr->space_def; + Table *pTable = + sqlite3LocateTable(pParse, 0, + space_def->name); + assert(pTable != NULL); if (iCol < 0) - iCol = pTab->iPKey; - zName = pTab->def->fields[iCol].name; + iCol = pTable->iPKey; + zName = space_def->fields[iCol].name; } else if (pColExpr->op == TK_ID) { assert(!ExprHasProperty(pColExpr, EP_IntValue)); zName = pColExpr->u.zToken; @@ -1950,11 +1954,13 @@ sqlite3SelectAddColumnTypeAndCollation(Parse * pParse, /* Parsing contexts */ p = a[i].pExpr; type = columnType(&sNC, p, 0, 0, 0, &pCol->szEst); szAll += pCol->szEst; - pCol->affinity = sqlite3ExprAffinity(p); pTab->def->fields[i].type = type; - if (pCol->affinity == 0) - pCol->affinity = SQLITE_AFF_BLOB; + char affinity = sqlite3ExprAffinity(p); + if (affinity == 0) + affinity = SQLITE_AFF_BLOB; + pTab->def->fields[i].affinity = affinity; + bool unused; struct coll *coll = sql_expr_coll(pParse, p, &unused); if (coll != NULL && pTab->def->fields[i].coll_id == COLL_NONE) @@ -5933,7 +5939,7 @@ sqlite3Select(Parse * pParse, /* The parser context */ if (pCol->iSorterColumn >= j) { int r1 = j + regBase; sqlite3ExprCodeGetColumnToReg - (pParse, pCol->pTab, + (pParse, pCol->space_def, pCol->iColumn, pCol->iTable, r1); j++; diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h index 4fba008..ad7cc54 100644 --- a/src/box/sql/sqliteInt.h +++ b/src/box/sql/sqliteInt.h @@ -1867,7 +1867,6 @@ struct Savepoint { * of this structure. */ struct Column { - char affinity; /* One of the SQLITE_AFF_... values */ u8 szEst; /* Estimated size of value in this column. sizeof(INT)==1 */ u8 is_primkey; /* Boolean propertie for being PK */ }; @@ -1879,26 +1878,6 @@ struct Column { #define SQLITE_SO_DESC 1 /* Sort in ascending order */ #define SQLITE_SO_UNDEFINED -1 /* No sort order specified */ -/* - * Column affinity types. - * - * These used to have mnemonic name like 'i' for SQLITE_AFF_INTEGER and - * 't' for SQLITE_AFF_TEXT. But we can save a little space and improve - * the speed a little by numbering the values consecutively. - * - * But rather than start with 0 or 1, we begin with 'A'. That way, - * when multiple affinity types are concatenated into a string and - * used as the P4 operand, they will be more readable. - * - * Note also that the numeric types are grouped together so that testing - * for a numeric type is a single comparison. And the BLOB type is first. - */ -#define SQLITE_AFF_BLOB 'A' -#define SQLITE_AFF_TEXT 'B' -#define SQLITE_AFF_NUMERIC 'C' -#define SQLITE_AFF_INTEGER 'D' -#define SQLITE_AFF_REAL 'E' - #define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) /* @@ -2226,7 +2205,8 @@ struct AggInfo { int mnReg, mxReg; /* Range of registers allocated for aCol and aFunc */ ExprList *pGroupBy; /* The group by clause */ struct AggInfo_col { /* For each column used in source tables */ - Table *pTab; /* Source table */ + /* Pointer to space definition. */ + struct space_def *space_def; int iTable; /* Cursor number of the source table */ int iColumn; /* Column number within the source table */ int iSorterColumn; /* Column number in the sorting index */ @@ -2361,7 +2341,8 @@ struct Expr { * TK_AGG_FUNCTION: nesting depth */ AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ - Table *pTab; /* Table for TK_COLUMN expressions. */ + /* Pointer for table relative definition. */ + struct space_def *space_def; }; /* @@ -3520,7 +3501,7 @@ void sqlite3AddCollateType(Parse *, Token *); const char * column_collation_name(Table *, uint32_t); struct coll * -sql_column_collation(Table *, uint32_t); +sql_column_collation(struct space_def *, uint32_t); const char * index_collation_name(Index *, uint32_t); struct coll * @@ -3607,9 +3588,9 @@ int sqlite3WhereOkOnePass(WhereInfo *, int *); #define ONEPASS_SINGLE 1 /* ONEPASS valid for a single row update */ #define ONEPASS_MULTI 2 /* ONEPASS is valid for multiple rows */ void sqlite3ExprCodeLoadIndexColumn(Parse *, Index *, int, int, int); -int sqlite3ExprCodeGetColumn(Parse *, Table *, int, int, int, u8); -void sqlite3ExprCodeGetColumnToReg(Parse *, Table *, int, int, int); -void sqlite3ExprCodeGetColumnOfTable(Vdbe *, Table *, int, int, int); +int sqlite3ExprCodeGetColumn(Parse *, struct space_def *, int, int, int, u8); +void sqlite3ExprCodeGetColumnToReg(Parse *, struct space_def *, int, int, int); +void sqlite3ExprCodeGetColumnOfTable(Vdbe *, struct space_def *, int, int, int); void sqlite3ExprCodeMove(Parse *, int, int, int); void sqlite3ExprCacheStore(Parse *, int, int, int); void sqlite3ExprCachePush(Parse *); @@ -3802,7 +3783,7 @@ const char *sqlite3IndexAffinityStr(sqlite3 *, Index *); void sqlite3TableAffinity(Vdbe *, Table *, int); char sqlite3CompareAffinity(Expr * pExpr, char aff2); int sqlite3IndexAffinityOk(Expr * pExpr, char idx_affinity); -char sqlite3TableColumnAffinity(Table *, int); +char sqlite3TableColumnAffinity(struct space_def *, int); char sqlite3ExprAffinity(Expr * pExpr); int sqlite3Atoi64(const char *, i64 *, int); int sqlite3DecOrHexToI64(const char *, i64 *); @@ -3890,7 +3871,7 @@ int sqlite3ResolveExprListNames(NameContext *, ExprList *); void sqlite3ResolveSelectNames(Parse *, Select *, NameContext *); void sqlite3ResolveSelfReference(Parse *, Table *, int, Expr *, ExprList *); int sqlite3ResolveOrderGroupBy(Parse *, Select *, ExprList *, const char *); -void sqlite3ColumnDefault(Vdbe *, Table *, int, int); +void sqlite3ColumnDefault(Vdbe *, struct space_def *, int, int); void sqlite3AlterFinishAddColumn(Parse *, Token *); void sqlite3AlterBeginAddColumn(Parse *, SrcList *); char* rename_table(sqlite3 *, const char *, const char *, bool *); @@ -4140,7 +4121,7 @@ enum on_conflict_action table_column_nullable_action(struct Table *tab, uint32_t column); bool -table_column_is_nullable(struct Table *tab, uint32_t column); +space_def_column_is_nullable(struct space_def *def, uint32_t column); /** * Initialize a new parser object. diff --git a/src/box/sql/update.c b/src/box/sql/update.c index 5f5807c..9ae77e0 100644 --- a/src/box/sql/update.c +++ b/src/box/sql/update.c @@ -69,30 +69,27 @@ * space. */ void -sqlite3ColumnDefault(Vdbe * v, Table * pTab, int i, int iReg) +sqlite3ColumnDefault(Vdbe * v, struct space_def * def, int i, int iReg) { - assert(pTab != 0); - assert(pTab->def->opts.is_view == (pTab->pSelect != NULL)); - if (!pTab->def->opts.is_view) { + assert(def != NULL); + + if (!def->opts.is_view) { sqlite3_value *pValue = 0; - Column *pCol = &pTab->aCol[i]; - VdbeComment((v, "%s.%s", pTab->def->name, - pTab->def->fields[i].name)); - assert(i < (int)pTab->def->field_count); + char affinity = def->fields[i].affinity; + VdbeComment((v, "%s.%s", def->name, def->fields[i].name)); + assert(i < (int)def->field_count); Expr *expr = NULL; - struct space *space = - space_cache_find(SQLITE_PAGENO_TO_SPACEID(pTab->tnum)); - if (space != NULL && space->def->fields != NULL) - expr = space->def->fields[i].default_value_expr; + assert(def->fields != NULL && i < (int)def->field_count); + if (def->fields != NULL) + expr = def->fields[i].default_value_expr; sqlite3ValueFromExpr(sqlite3VdbeDb(v), - expr, - pCol->affinity, &pValue); + expr, affinity, &pValue); if (pValue) { sqlite3VdbeAppendP4(v, pValue, P4_MEM); } #ifndef SQLITE_OMIT_FLOATING_POINT - if (pTab->aCol[i].affinity == SQLITE_AFF_REAL) { + if (affinity == SQLITE_AFF_REAL) { sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); } #endif @@ -381,7 +378,7 @@ sqlite3Update(Parse * pParse, /* The parser context */ } else { for (i = 0; i < nPk; i++) { assert(pPk->aiColumn[i] >= 0); - sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, + sqlite3ExprCodeGetColumnOfTable(v, pTab->def, iDataCur, pPk->aiColumn[i], iPk + i); } @@ -486,7 +483,7 @@ sqlite3Update(Parse * pParse, /* The parser context */ || (i < 32 && (oldmask & MASKBIT32(i)) != 0) || table_column_is_in_pk(pTab, i)) { testcase(oldmask != 0xffffffff && i == 31); - sqlite3ExprCodeGetColumnOfTable(v, pTab, + sqlite3ExprCodeGetColumnOfTable(v, pTab->def, iDataCur, i, regOld + i); } else { @@ -529,7 +526,7 @@ sqlite3Update(Parse * pParse, /* The parser context */ */ testcase(i == 31); testcase(i == 32); - sqlite3ExprCodeGetColumnToReg(pParse, pTab, i, + sqlite3ExprCodeGetColumnToReg(pParse, pTab->def, i, iDataCur, regNew + i); } else { @@ -570,7 +567,7 @@ sqlite3Update(Parse * pParse, /* The parser context */ */ for (i = 0; i < (int)pTab->def->field_count; i++) { if (aXRef[i] < 0 && i != pTab->iPKey) { - sqlite3ExprCodeGetColumnOfTable(v, pTab, + sqlite3ExprCodeGetColumnOfTable(v, pTab->def, iDataCur, i, regNew + i); } diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c index 0ccca77..3054fc3 100644 --- a/src/box/sql/vdbeaux.c +++ b/src/box/sql/vdbeaux.c @@ -4724,28 +4724,10 @@ table_column_nullable_action(struct Table *tab, uint32_t column) * @return return nullability flag value */ bool -table_column_is_nullable(struct Table *tab, uint32_t column) +space_def_column_is_nullable(struct space_def *def, uint32_t column) { - /* Temporary hack: until Tarantoool's ephemeral spaces are on-boarded, - * views are not handled properly in Tarantool as well. */ - if (!(tab->tabFlags | TF_Ephemeral || space_is_view(tab))) { - uint32_t space_id = SQLITE_PAGENO_TO_SPACEID(tab->tnum); - struct space *space = space_cache_find(space_id); - - assert(space); - - struct tuple_format *format = space->format; - - assert(format); - assert(format->field_count > column); - - return nullable_action_to_is_nullable( - format->fields[column].nullable_action); - } else { - /* tab is ephemeral (in SQLite sense). */ - assert(tab->def->fields[column].is_nullable == - nullable_action_to_is_nullable( - tab->def->fields[column].nullable_action)); - return tab->def->fields[column].is_nullable; - } + assert(def->fields[column].is_nullable == + nullable_action_to_is_nullable( + def->fields[column].nullable_action)); + return def->fields[column].is_nullable; } diff --git a/src/box/sql/where.c b/src/box/sql/where.c index 9ab6295..c878a97 100644 --- a/src/box/sql/where.c +++ b/src/box/sql/where.c @@ -378,7 +378,9 @@ whereScanInit(WhereScan * pScan, /* The WhereScan object being initialized */ if (iColumn == XN_EXPR) { pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr; } else if (iColumn >= 0) { - pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity; + char affinity = + pIdx->pTable->def->fields[iColumn].affinity; + pScan->idxaff = affinity; pScan->coll = sql_index_collation(pIdx, j); pScan->is_column_seen = true; } @@ -491,7 +493,7 @@ indexColumnNotNull(Index * pIdx, int iCol) assert(iCol >= 0 && iCol < (int)index_column_count(pIdx)); j = pIdx->aiColumn[iCol]; if (j >= 0) { - return !table_column_is_nullable(pIdx->pTable, j); + return !space_def_column_is_nullable(pIdx->pTable->def, j); } else if (j == (-1)) { return 1; } else { @@ -2236,7 +2238,8 @@ whereRangeVectorLen(Parse * pParse, /* Parsing context */ aff = sqlite3CompareAffinity(pRhs, sqlite3ExprAffinity(pLhs)); idxaff = - sqlite3TableColumnAffinity(pIdx->pTable, pLhs->iColumn); + sqlite3TableColumnAffinity(pIdx->pTable->def, + pLhs->iColumn); if (aff != idxaff) break; @@ -3330,8 +3333,8 @@ wherePathSatisfiesOrderBy(WhereInfo * pWInfo, /* The WHERE clause */ if (isOrderDistinct && iColumn >= 0 && j >= pLoop->nEq - && table_column_is_nullable(pIndex->pTable, - iColumn)) { + && space_def_column_is_nullable( + pIndex->pTable->def, iColumn)) { isOrderDistinct = 0; } diff --git a/src/box/sql/wherecode.c b/src/box/sql/wherecode.c index 9d4055a..1263e05 100644 --- a/src/box/sql/wherecode.c +++ b/src/box/sql/wherecode.c @@ -909,7 +909,7 @@ codeCursorHintFixExpr(Walker * pWalker, Expr * pExpr) if (pExpr->iTable != pHint->iTabCur) { Vdbe *v = pWalker->pParse->pVdbe; int reg = ++pWalker->pParse->nMem; /* Register for column value */ - sqlite3ExprCodeGetColumnOfTable(v, pExpr->pTab, + sqlite3ExprCodeGetColumnOfTable(v, pExpr->pTab->def, pExpr->iTable, pExpr->iColumn, reg); pExpr->op = TK_REGISTER; @@ -1260,8 +1260,10 @@ sqlite3WhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about t * FYI: entries in an index are ordered as follows: * NULL, ... NULL, min_value, ... */ - if ((j >= 0 && table_column_is_nullable(pIdx->pTable, j)) - || j == XN_EXPR) { + if ((j >= 0 && + space_def_column_is_nullable(pIdx->pTable->def, + j)) || + j == XN_EXPR) { assert(pLoop->nSkip == 0); bSeekPastNull = 1; nExtraReg = 1; @@ -1307,7 +1309,9 @@ sqlite3WhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about t if (pRangeStart == 0) { j = pIdx->aiColumn[nEq]; if ((j >= 0 - && table_column_is_nullable(pIdx->pTable, j)) || j == XN_EXPR) { + && space_def_column_is_nullable( + pIdx->pTable->def, j)) || + j == XN_EXPR) { bSeekPastNull = 1; } } @@ -1386,8 +1390,9 @@ sqlite3WhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about t struct Index *pk = sqlite3PrimaryKeyIndex(pIdx->pTable); assert(pk); int nPkCol = index_column_count(pk); - if (nPkCol == 1 - && pIdx->pTable->aCol[pk->aiColumn[0]].affinity == 'D') { + char affinity = + pIdx->pTable->def->fields[pk->aiColumn[0]].affinity; + if (nPkCol == 1 && affinity == 'D') { /* Right now INTEGER PRIMARY KEY is the only option to * get Tarantool's INTEGER column type. Need special handling * here: try to loosely convert FLOAT to INT. If RHS type @@ -1724,7 +1729,7 @@ sqlite3WhereCodeOneLoopStart(WhereInfo * pWInfo, /* Complete information about t for (iPk = 0; iPk < nPk; iPk++) { int iCol = pPk->aiColumn[iPk]; sqlite3ExprCodeGetColumnToReg - (pParse, pTab, + (pParse, pTab->def, iCol, iCur, r + iPk); } diff --git a/src/box/sql/whereexpr.c b/src/box/sql/whereexpr.c index e602111..d1f2cc5 100644 --- a/src/box/sql/whereexpr.c +++ b/src/box/sql/whereexpr.c @@ -1516,7 +1516,7 @@ sqlite3WhereTabFuncArgs(Parse * pParse, /* Parsing context */ return; pColRef->iTable = pItem->iCursor; pColRef->iColumn = k++; - pColRef->pTab = pTab; + pColRef->space_def = pTab->def; pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0)); -- 2.7.4
next prev parent reply other threads:[~2018-05-11 8:49 UTC|newest] Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-05-11 8:49 [tarantool-patches] [PATCH v5 0/3] sql: refactor SQL Parser structures Kirill Shcherbatov 2018-05-11 8:49 ` [tarantool-patches] [PATCH v5 1/3] sql: fix code style in sqlite3Pragma Kirill Shcherbatov 2018-05-11 20:59 ` [tarantool-patches] " Vladislav Shpilevoy 2018-05-11 8:49 ` [tarantool-patches] [PATCH v5 2/3] sql: remove SQL fields from Table and Column Kirill Shcherbatov 2018-05-11 20:59 ` [tarantool-patches] " Vladislav Shpilevoy 2018-05-14 11:20 ` Kirill Shcherbatov 2018-05-14 13:39 ` Vladislav Shpilevoy 2018-05-15 15:56 ` Kirill Shcherbatov 2018-05-11 8:49 ` Kirill Shcherbatov [this message] 2018-05-11 20:59 ` [tarantool-patches] Re: [PATCH v5 3/3] sql: space_def* instead of Table* in Expr Vladislav Shpilevoy 2018-05-14 11:20 ` Kirill Shcherbatov 2018-05-11 8:58 ` [tarantool-patches] Re: [PATCH v5 0/3] sql: refactor SQL Parser structures Vladislav Shpilevoy 2018-05-11 19:40 ` [tarantool-patches] Re[2]: [tarantool-patches] " Kirill Shcherbatov
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=bc6936ccf8dddca90350a05b82b71f3c95caded9.1526028449.git.kshcherbatov@tarantool.org \ --to=kshcherbatov@tarantool.org \ --cc=tarantool-patches@freelists.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [tarantool-patches] [PATCH v5 3/3] sql: space_def* instead of Table* in 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