[tarantool-patches] [PATCH v4 7/7] sql: space_def* instead of Table* in Expr
Kirill Shcherbatov
kshcherbatov at tarantool.org
Sat Apr 28 21:26:58 MSK 2018
Part of #3272.
---
src/box/field_def.c | 1 +
src/box/field_def.h | 5 ++++
src/box/sql.c | 10 ++++----
src/box/sql/build.c | 48 ++++++++++++++++++++------------------
src/box/sql/delete.c | 4 ++--
src/box/sql/expr.c | 61 ++++++++++++++++++++++++++-----------------------
src/box/sql/fkey.c | 13 +++++------
src/box/sql/insert.c | 24 ++++++++++---------
src/box/sql/pragma.c | 8 ++++---
src/box/sql/resolve.c | 10 ++++----
src/box/sql/select.c | 26 +++++++++++++--------
src/box/sql/sqliteInt.h | 21 +++++++++--------
src/box/sql/update.c | 29 +++++++++++------------
src/box/sql/vdbeaux.c | 20 ++++++----------
src/box/sql/where.c | 13 +++++++----
src/box/sql/wherecode.c | 18 +++++++++------
src/box/sql/whereexpr.c | 2 +-
17 files changed, 167 insertions(+), 146 deletions(-)
diff --git a/src/box/field_def.c b/src/box/field_def.c
index 010b3b7..63aab46 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 = 0,
.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 dfc1950..4577f6b 100644
--- a/src/box/field_def.h
+++ b/src/box/field_def.h
@@ -102,6 +102,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.
+ */
+ char 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 9f5a124..11ec0b1 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));
@@ -1532,7 +1532,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);
@@ -1569,7 +1568,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 a98a6bd..742f8a5 100644
--- a/src/box/sql/build.c
+++ b/src/box/sql/build.c
@@ -701,7 +701,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 {
@@ -712,14 +712,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;
}
@@ -1032,8 +1032,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);
+ }
}
}
}
@@ -1046,10 +1048,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
@@ -1064,9 +1066,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;
}
@@ -1322,18 +1324,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);
@@ -1843,6 +1846,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) {
@@ -3094,7 +3098,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..4e20098 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 != 0) {
/* 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,10 @@ sqlite3ExprCanBeNull(const Expr * p)
case TK_BLOB:
return 0;
case TK_COLUMN:
- assert(p->pTab != 0);
+ assert(p->space_def!= 0);
return ExprHasProperty(p, EP_CanBeNull) ||
(p->iColumn >= 0
- && table_column_is_nullable(p->pTab, p->iColumn));
+ && table_column_is_nullable(p->space_def, p->iColumn));
default:
return 1;
}
@@ -2435,7 +2437,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 +3179,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,7 +3524,7 @@ 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);
}
}
@@ -3529,7 +3534,7 @@ sqlite3ExprCodeLoadIndexColumn(Parse * pParse, /* The parsing context */
*/
void
sqlite3ExprCodeGetColumnOfTable(Vdbe * v, /* The VDBE under construction */
- Table * pTab, /* The table containing the value */
+ struct space_def *space_def,
int iTabCur, /* The PK cursor */
int iCol, /* Index of the column to extract */
int regOut /* Extract the value into this register */
@@ -3537,7 +3542,7 @@ sqlite3ExprCodeGetColumnOfTable(Vdbe * v, /* The VDBE under construction */
{
sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut);
if (iCol >= 0) {
- sqlite3ColumnDefault(v, pTab, iCol, regOut);
+ sqlite3ColumnDefault(v, space_def, iCol, regOut);
}
}
@@ -3552,7 +3557,7 @@ sqlite3ExprCodeGetColumnOfTable(Vdbe * v, /* The VDBE under construction */
*/
int
sqlite3ExprCodeGetColumn(Parse * pParse, /* Parsing and code generating context */
- Table * pTab, /* Description of the table we are reading from */
+ struct space_def * space_def,
int iColumn, /* Index of the table column */
int iTable, /* The cursor pointing to the table */
int iReg, /* Store results here */
@@ -3572,7 +3577,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 {
@@ -3583,14 +3588,14 @@ sqlite3ExprCodeGetColumn(Parse * pParse, /* Parsing and code generating context
void
sqlite3ExprCodeGetColumnToReg(Parse * pParse, /* Parsing and code generating context */
- Table * pTab, /* Description of the table we are reading from */
+ struct space_def * space_def,
int iColumn, /* Index of the table column */
int iTable, /* The cursor pointing to the table */
int iReg /* Store results here */
)
{
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 +3782,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 +4246,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 +4270,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 +5443,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 16f72d8..52f86d4 100644
--- a/src/box/sql/fkey.c
+++ b/src/box/sql/fkey.c
@@ -299,7 +299,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);
@@ -527,15 +527,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;
const char *coll_name = "binary";
pExpr = sqlite3ExprAddCollateString(pParse, pExpr,
coll_name);
@@ -553,14 +552,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;
}
@@ -673,7 +672,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 bde0cc1..7c21359 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 (table_column_is_nullable(pTab->def, i)
|| (pTab->tabFlags & TF_Autoincrement
&& pTab->iAutoIncPKey == i))
continue; /* This column is allowed to be NULL */
@@ -1805,17 +1807,17 @@ 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) {
+ char pdest_affinity = pDest->def->fields[i].affinity;
+ char psrc_affinity = pSrc->def->fields[i].affinity;
+ if (pdest_affinity != psrc_affinity) {
return 0; /* Affinity must be the same on all columns */
}
- if (sql_column_collation(pDest, i) !=
- sql_column_collation(pSrc, i)) {
+ if (sql_column_collation(pDest->def, i) !=
+ sql_column_collation(pSrc->def, 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)) {
+ if (!table_column_is_nullable(pDest->def, i)
+ && table_column_is_nullable(pSrc->def, i)) {
return 0; /* tab2 must be NOT NULL if tab1 is */
}
/* Default values for second and subsequent columns need to match. */
diff --git a/src/box/sql/pragma.c b/src/box/sql/pragma.c
index 463bb7e..c49817f 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 =
+ table_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 5d85ef7..f24399c 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 */
@@ -301,7 +301,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) {
@@ -365,7 +365,7 @@ lookupName(Parse * pParse, /* The parsing context */
: (((u32) 1) << iCol));
}
pExpr->iColumn = (i16) iCol;
- pExpr->pTab = pTab;
+ pExpr->space_def = pTab->def;
isTrigger = 1;
}
}
@@ -499,9 +499,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 34d296d..ff9f18b 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 && 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
@@ -1842,19 +1842,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;
@@ -1946,11 +1950,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)
@@ -5931,7 +5937,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 6eddbec..4c2c6fb 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 */
};
@@ -2226,7 +2225,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 +2361,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 +3521,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 +3608,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 +3803,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 +3891,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 *);
@@ -4141,6 +4142,6 @@ 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);
+table_column_is_nullable(struct space_def *def, uint32_t column);
#endif /* SQLITEINT_H */
diff --git a/src/box/sql/update.c b/src/box/sql/update.c
index 2f36423..38f824f 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));
+ space_cache_find(def->id);
if (space != NULL && space->def->fields != NULL)
expr = space->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 f76c689..f9927ed 100644
--- a/src/box/sql/vdbeaux.c
+++ b/src/box/sql/vdbeaux.c
@@ -4724,28 +4724,22 @@ 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)
+table_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 space *space = space_cache_find(def->id);
+ if (space != NULL && !space->def->opts.is_view) {
struct tuple_format *format = space->format;
-
assert(format);
assert(format->field_count > column);
-
return format->fields[column].nullable_action ==
- ON_CONFLICT_ACTION_NONE;
+ ON_CONFLICT_ACTION_NONE;
} else {
/* tab is ephemeral (in SQLite sense). */
- assert(tab->def->fields[column].is_nullable ==
- (tab->def->fields[column].nullable_action ==
+ assert(def->fields[column].is_nullable ==
+ (def->fields[column].nullable_action ==
ON_CONFLICT_ACTION_NONE));
- return tab->def->fields[column].is_nullable;
+ return def->fields[column].is_nullable;
}
}
diff --git a/src/box/sql/where.c b/src/box/sql/where.c
index 88f4c28..d33fd9c 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 !table_column_is_nullable(pIdx->pTable->def, j);
} else if (j == (-1)) {
return 1;
} else {
@@ -2237,7 +2239,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;
@@ -3331,8 +3334,8 @@ wherePathSatisfiesOrderBy(WhereInfo * pWInfo, /* The WHERE clause */
if (isOrderDistinct
&& iColumn >= 0
&& j >= pLoop->nEq
- && table_column_is_nullable(pIndex->pTable,
- iColumn)) {
+ && table_column_is_nullable(
+ pIndex->pTable->def, iColumn)) {
isOrderDistinct = 0;
}
diff --git a/src/box/sql/wherecode.c b/src/box/sql/wherecode.c
index 3da7cdb..3459020 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;
@@ -1261,8 +1261,9 @@ 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 &&
+ table_column_is_nullable(pIdx->pTable->def, j)) ||
+ j == XN_EXPR) {
assert(pLoop->nSkip == 0);
bSeekPastNull = 1;
nExtraReg = 1;
@@ -1308,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) {
+ && table_column_is_nullable(
+ pIdx->pTable->def, j)) ||
+ j == XN_EXPR) {
bSeekPastNull = 1;
}
}
@@ -1387,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
@@ -1725,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
More information about the Tarantool-patches
mailing list