[tarantool-patches] [PATCH v3 2/4] sql: Remove zName and nColumn from SQL.
Kirill Shcherbatov
kshcherbatov at tarantool.org
Wed Apr 25 19:52:21 MSK 2018
1. Removed zName from SQL Column.
2. Removed zColumns from SQL Table.
3. Refactored Parser to use def_expression directly.
4. Introduced sql_table_def_rebuild intended for collect
fragmented with sql_field_retrieve space_def into memory
located in one allocation.
Needed for #3272.
---
src/box/space_def.c | 29 ++++----
src/box/sql.c | 61 +++++++++++++---
src/box/sql.h | 23 ++++++
src/box/sql/alter.c | 32 ++++++---
src/box/sql/analyze.c | 5 +-
src/box/sql/build.c | 181 ++++++++++++++++++++++--------------------------
src/box/sql/delete.c | 6 +-
src/box/sql/expr.c | 11 +--
src/box/sql/fkey.c | 20 +++---
src/box/sql/insert.c | 55 ++++++++-------
src/box/sql/pragma.c | 24 ++++---
src/box/sql/resolve.c | 16 +++--
src/box/sql/select.c | 92 ++++++++++++------------
src/box/sql/sqliteInt.h | 4 +-
src/box/sql/update.c | 29 ++++----
src/box/sql/where.c | 6 +-
src/box/sql/wherecode.c | 2 +-
src/box/sql/whereexpr.c | 4 +-
18 files changed, 338 insertions(+), 262 deletions(-)
diff --git a/src/box/space_def.c b/src/box/space_def.c
index 22bd3ca..77c0e02 100644
--- a/src/box/space_def.c
+++ b/src/box/space_def.c
@@ -70,11 +70,12 @@ space_def_sizeof(uint32_t name_len, const struct field_def *fields,
for (uint32_t i = 0; i < field_count; ++i) {
field_strs_size += strlen(fields[i].name) + 1;
if (fields[i].default_value != NULL) {
- assert(fields[i].default_value_expr != NULL);
int len = strlen(fields[i].default_value);
field_strs_size += len + 1;
- struct Expr *e = fields[i].default_value_expr;
- def_exprs_size += sql_expr_sizeof(e, 0);
+ if (fields[i].default_value_expr != NULL) {
+ struct Expr *e = fields[i].default_value_expr;
+ def_exprs_size += sql_expr_sizeof(e, 0);
+ }
}
}
@@ -116,12 +117,13 @@ space_def_dup(const struct space_def *src)
if (src->fields[i].default_value != NULL) {
ret->fields[i].default_value = strs_pos;
strs_pos += strlen(strs_pos) + 1;
-
- struct Expr *e =
- src->fields[i].default_value_expr;
- assert(e != NULL);
+ }
+ struct Expr *e =
+ src->fields[i].default_value_expr;
+ if (e != NULL) {
char *expr_pos_old = expr_pos;
- e = sql_expr_dup(sql_get(), e, 0, &expr_pos);
+ e = sql_expr_dup(sql_get(), e, 0,
+ &expr_pos);
assert(e != NULL);
/* Note: due to SQL legacy
* duplicactor pointer is not
@@ -201,12 +203,13 @@ space_def_new(uint32_t id, uint32_t uid, uint32_t exact_field_count,
fields[i].default_value, len);
def->fields[i].default_value[len] = 0;
strs_pos += len + 1;
-
- struct Expr *e =
- fields[i].default_value_expr;
- assert(e != NULL);
+ }
+ struct Expr *e =
+ fields[i].default_value_expr;
+ if (e != NULL) {
char *expr_pos_old = expr_pos;
- e = sql_expr_dup(sql_get(), e, 0, &expr_pos);
+ e = sql_expr_dup(sql_get(), e, 0,
+ &expr_pos);
assert(e != NULL);
/* Note: due to SQL legacy
* duplicactor pointer is
diff --git a/src/box/sql.c b/src/box/sql.c
index 166bb71..38aeac6 100644
--- a/src/box/sql.c
+++ b/src/box/sql.c
@@ -1433,7 +1433,7 @@ int tarantoolSqlite3MakeTableFormat(Table *pTable, void *buf)
struct SqliteIndex *pk_idx = sqlite3PrimaryKeyIndex(pTable);
int pk_forced_int = -1;
char *base = buf, *p;
- int i, n = pTable->nCol;
+ int i, n = pTable->def->field_count;
p = enc->encode_array(base, n);
@@ -1449,15 +1449,15 @@ int tarantoolSqlite3MakeTableFormat(Table *pTable, void *buf)
const char *t;
struct coll *coll = aCol[i].coll;
struct field_def *field = &pTable->def->fields[i];
- struct Expr *def = field->default_value_expr;
+ const char *zToken = field->default_value;
int base_len = 4;
if (coll != NULL)
base_len += 1;
- if (def != NULL)
+ if (zToken != NULL)
base_len += 1;
p = enc->encode_map(p, base_len);
p = enc->encode_str(p, "name", 4);
- p = enc->encode_str(p, aCol[i].zName, strlen(aCol[i].zName));
+ p = enc->encode_str(p, field->name, strlen(field->name));
p = enc->encode_str(p, "type", 4);
if (i == pk_forced_int) {
t = "integer";
@@ -1477,11 +1477,9 @@ int tarantoolSqlite3MakeTableFormat(Table *pTable, void *buf)
p = enc->encode_str(p, "collation", strlen("collation"));
p = enc->encode_uint(p, coll->id);
}
- if (def != NULL) {
- assert((def->flags & EP_IntValue) == 0);
- assert(def->u.zToken != NULL);
- p = enc->encode_str(p, "default", strlen("default"));
- p = enc->encode_str(p, def->u.zToken, strlen(def->u.zToken));
+ if (zToken != NULL) {
+ p = enc->encode_str(p, "default", strlen("default"));
+ p = enc->encode_str(p, zToken, strlen(zToken));
}
}
return (int)(p - base);
@@ -1681,3 +1679,48 @@ space_column_default_expr(uint32_t space_id, uint32_t fieldno)
return space->def->fields[fieldno].default_value_expr;
}
+
+Table *
+sql_ephemeral_table_new(Parse *parser)
+{
+ sqlite3 *db = parser->db;
+ struct space_def *def = NULL;
+ Table *table = sqlite3DbMallocZero(db, sizeof(Table));
+ if (table != NULL) {
+ def = space_def_new(0, 0, 0, NULL, 0, NULL, 0,
+ &space_opts_default, NULL, 0);
+ }
+ if (def == NULL) {
+ sqlite3DbFree(db, table);
+ parser->rc = SQLITE_NOMEM_BKPT;
+ parser->nErr++;
+ return NULL;
+ }
+ table->def = def;
+ return table;
+}
+
+int
+sql_table_def_rebuild(struct sqlite3 *db, struct Table *pTable)
+{
+ struct space_def *old_def = pTable->def;
+ struct space_def *new_def = NULL;
+ new_def = space_def_new(old_def->id, old_def->uid,
+ old_def->field_count, old_def->name,
+ strlen(old_def->name), old_def->engine_name,
+ strlen(old_def->engine_name), &old_def->opts,
+ old_def->fields, old_def->field_count);
+ if (new_def == NULL) {
+ sqlite3OomFault(db);
+ return -1;
+ }
+ struct field_def *fields = old_def->fields;
+ for (uint32_t i = 0; i < old_def->field_count; ++i) {
+ sqlite3DbFree(db, fields[i].default_value);
+ sqlite3DbFree(db, fields[i].name);
+ }
+ space_def_delete(old_def);
+ sqlite3DbFree(db, fields);
+ pTable->def = new_def;
+ return 0;
+}
diff --git a/src/box/sql.h b/src/box/sql.h
index db92d80..9fb3ad1 100644
--- a/src/box/sql.h
+++ b/src/box/sql.h
@@ -65,6 +65,7 @@ sql_get();
struct Expr;
struct Parse;
struct Select;
+struct Table;
/**
* Perform parsing of provided expression. This is done by
@@ -143,6 +144,28 @@ sql_expr_dup(struct sqlite3 *db, struct Expr *p, int flags, char **buffer);
void
sql_expr_free(struct sqlite3 *db, struct Expr *expr, bool extern_alloc);
+/**
+ * Create and initialize a new ephemeric SQL Table object.
+ * @param pParse SQL Parser object.
+ * @param zName Table to create name.
+ * @retval NULL on memory allocation error, Parser state changed.
+ * @retval not NULL on success.
+ */
+struct Table *
+sql_ephemeral_table_new(struct Parse *parser);
+
+/**
+ * Rebuild struct def in Table with memory allocated on a single
+ * malloc. Fields and strings are expected to be allocated with
+ * sqlite3DbMalloc.
+ * @param db The database connection.
+ * @param pTable The Table with fragmented def to rebuild.
+ * @retval 1 on memory allocation error
+ * @retval 0 on success
+ */
+int
+sql_table_def_rebuild(struct sqlite3 *db, struct Table *table);
+
#if defined(__cplusplus)
} /* extern "C" { */
#endif
diff --git a/src/box/sql/alter.c b/src/box/sql/alter.c
index 24f0965..bedf602 100644
--- a/src/box/sql/alter.c
+++ b/src/box/sql/alter.c
@@ -144,6 +144,9 @@ sqlite3AlterRenameTable(Parse * pParse, /* Parser context. */
void
sqlite3AlterFinishAddColumn(Parse * pParse, Token * pColDef)
{
+ /* This function is not implemented yet #3075. */
+ assert(false);
+
Table *pNew; /* Copy of pParse->pNewTable */
Table *pTab; /* Table being altered */
const char *zTab; /* Table name */
@@ -161,10 +164,10 @@ sqlite3AlterFinishAddColumn(Parse * pParse, Token * pColDef)
assert(pNew);
zTab = &pNew->zName[16]; /* Skip the "sqlite_altertab_" prefix on the name */
- pCol = &pNew->aCol[pNew->nCol - 1];
+ pCol = &pNew->aCol[pNew->def->field_count - 1];
assert(pNew->def != NULL);
pDflt = space_column_default_expr(SQLITE_PAGENO_TO_SPACEID(pNew->tnum),
- pNew->nCol - 1);
+ pNew->def->field_count - 1);
pTab = sqlite3HashFind(&db->pSchema->tblHash, zTab);;
assert(pTab);
@@ -248,10 +251,13 @@ sqlite3AlterFinishAddColumn(Parse * pParse, Token * pColDef)
void
sqlite3AlterBeginAddColumn(Parse * pParse, SrcList * pSrc)
{
+ /* This function is not implemented yet #3075. */
+ assert(false);
+
Table *pNew;
Table *pTab;
Vdbe *v;
- int i;
+ uint32_t i;
int nAlloc;
sqlite3 *db = pParse->db;
@@ -281,13 +287,17 @@ sqlite3AlterBeginAddColumn(Parse * pParse, SrcList * pSrc)
pNew = (Table *) sqlite3DbMallocZero(db, sizeof(Table));
if (!pNew)
goto exit_begin_add_column;
+ pNew->def = space_def_dup(pTab->def);
+ if (pNew->def == NULL) {
+ sqlite3DbFree(db, pNew);
+ goto exit_begin_add_column;
+ }
pParse->pNewTable = pNew;
pNew->nTabRef = 1;
- pNew->nCol = pTab->nCol;
- assert(pNew->nCol > 0);
- nAlloc = (((pNew->nCol - 1) / 8) * 8) + 8;
- assert(nAlloc >= pNew->nCol && nAlloc % 8 == 0
- && nAlloc - pNew->nCol < 8);
+ assert(pNew->def->field_count > 0);
+ nAlloc = (((pNew->def->field_count - 1) / 8) * 8) + 8;
+ assert((uint32_t)nAlloc >= pNew->def->field_count && nAlloc % 8 == 0
+ && nAlloc - pNew->def->field_count < 8);
pNew->aCol =
(Column *) sqlite3DbMallocZero(db, sizeof(Column) * nAlloc);
pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName);
@@ -295,10 +305,10 @@ sqlite3AlterBeginAddColumn(Parse * pParse, SrcList * pSrc)
assert(db->mallocFailed);
goto exit_begin_add_column;
}
- memcpy(pNew->aCol, pTab->aCol, sizeof(Column) * pNew->nCol);
- for (i = 0; i < pNew->nCol; i++) {
+ memcpy(pNew->aCol, pTab->aCol, sizeof(Column) * pNew->def->field_count);
+ for (i = 0; i < pNew->def->field_count; i++) {
Column *pCol = &pNew->aCol[i];
- pCol->zName = sqlite3DbStrDup(db, pCol->zName);
+ /* FIXME: pCol->zName = sqlite3DbStrDup(db, pCol->zName); */
pCol->coll = NULL;
}
pNew->pSchema = db->pSchema;
diff --git a/src/box/sql/analyze.c b/src/box/sql/analyze.c
index f0054c5..a0ad511 100644
--- a/src/box/sql/analyze.c
+++ b/src/box/sql/analyze.c
@@ -1023,9 +1023,10 @@ analyzeOneTable(Parse * pParse, /* Parser context */
regKeyStat = sqlite3GetTempRange(pParse, nPkColumn);
for (j = 0; j < nPkColumn; j++) {
k = pPk->aiColumn[j];
- assert(k >= 0 && k < pTab->nCol);
+ assert(k >= 0 && k < (int)pTab->def->field_count);
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKeyStat + j);
- VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName));
+ VdbeComment((v, "%s",
+ pTab->def->fields[pPk->aiColumn[j]].name));
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regKeyStat,
nPkColumn, regKey);
diff --git a/src/box/sql/build.c b/src/box/sql/build.c
index a2b712a..c712b46 100644
--- a/src/box/sql/build.c
+++ b/src/box/sql/build.c
@@ -291,15 +291,8 @@ sqlite3CommitInternalChanges()
void
sqlite3DeleteColumnNames(sqlite3 * db, Table * pTable)
{
- int i;
- Column *pCol;
assert(pTable != 0);
- if ((pCol = pTable->aCol) != 0) {
- for (i = 0; i < pTable->nCol; i++, pCol++) {
- sqlite3DbFree(db, pCol->zName);
- }
- sqlite3DbFree(db, pTable->aCol);
- }
+ sqlite3DbFree(db, pTable->aCol);
}
/*
@@ -393,12 +386,8 @@ deleteTable(sqlite3 * db, Table * pTable)
sqlite3DbFree(db, pTable->zColAff);
sqlite3SelectDelete(db, pTable->pSelect);
sqlite3ExprListDelete(db, pTable->pCheck);
- if (pTable->def != NULL) {
- /* Fields has been allocated independently. */
- struct field_def *fields = pTable->def->fields;
+ if (pTable->def != NULL)
space_def_delete(pTable->def);
- sqlite3DbFree(db, fields);
- }
sqlite3DbFree(db, pTable);
/* Verify that no lookaside memory was used by schema tables */
@@ -496,28 +485,16 @@ sqlite3PrimaryKeyIndex(Table * pTab)
* Create and initialize a new SQL Table object.
* @param parser SQL Parser object.
* @param name Table to create name.
- * @retval NULL on memory allocation error, Parser state is
- * changed.
+ * @retval NULL on memory allocation error.
* @retval not NULL on success.
*/
static Table *
sql_table_new(Parse *parser, char *name)
{
sqlite3 *db = parser->db;
-
- Table *table = sqlite3DbMallocZero(db, sizeof(Table));
- struct space_def *def = space_def_new(0, 0, 0, NULL, 0, NULL, 0,
- &space_opts_default, NULL, 0);
- if (table == NULL || def == NULL) {
- if (def != NULL)
- space_def_delete(def);
- sqlite3DbFree(db, table);
- parser->rc = SQLITE_NOMEM_BKPT;
- parser->nErr++;
+ struct Table *table = sql_ephemeral_table_new(parser);
+ if (table == NULL)
return NULL;
- }
-
- table->def = def;
table->zName = name;
table->iPKey = -1;
table->iAutoIncPKey = -1;
@@ -629,7 +606,6 @@ sql_field_retrieve(Parse *parser, Table *table, uint32_t id)
sqlite3 *db = parser->db;
struct field_def *field;
assert(table->def != NULL);
- assert(table->def->exact_field_count >= (uint32_t)table->nCol);
assert(id < SQLITE_MAX_COLUMN);
if (id >= table->def->exact_field_count) {
@@ -676,12 +652,12 @@ sqlite3AddColumn(Parse * pParse, Token * pName, Token * pType)
if ((p = pParse->pNewTable) == 0)
return;
#if SQLITE_MAX_COLUMN
- if (p->nCol + 1 > db->aLimit[SQLITE_LIMIT_COLUMN]) {
+ if ((int)p->def->field_count + 1 > db->aLimit[SQLITE_LIMIT_COLUMN]) {
sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName);
return;
}
#endif
- if (sql_field_retrieve(pParse, p, (uint32_t) p->nCol) == NULL)
+ if (sql_field_retrieve(pParse, p, (uint32_t) p->def->field_count) == NULL)
return;
z = sqlite3DbMallocRaw(db, pName->n + 1);
if (z == 0)
@@ -689,28 +665,27 @@ sqlite3AddColumn(Parse * pParse, Token * pName, Token * pType)
memcpy(z, pName->z, pName->n);
z[pName->n] = 0;
sqlite3NormalizeName(z);
- for (i = 0; i < p->nCol; i++) {
- if (strcmp(z, p->aCol[i].zName) == 0) {
+ for (i = 0; i < (int)p->def->field_count; i++) {
+ if (strcmp(z, p->def->fields[i].name) == 0) {
sqlite3ErrorMsg(pParse, "duplicate column name: %s", z);
sqlite3DbFree(db, z);
return;
}
}
- if ((p->nCol & 0x7) == 0) {
+ if ((p->def->field_count & 0x7) == 0) {
Column *aNew;
aNew =
sqlite3DbRealloc(db, p->aCol,
- (p->nCol + 8) * sizeof(p->aCol[0]));
+ (p->def->field_count + 8) * sizeof(p->aCol[0]));
if (aNew == 0) {
sqlite3DbFree(db, z);
return;
}
p->aCol = aNew;
}
- pCol = &p->aCol[p->nCol];
+ pCol = &p->aCol[p->def->field_count];
memset(pCol, 0, sizeof(p->aCol[0]));
- pCol->zName = z;
-
+ p->def->fields[p->def->field_count].name = z;
if (pType->n == 0) {
/* If there is no type specified, columns have the default affinity
* 'BLOB' and type SCALAR.
@@ -740,7 +715,6 @@ sqlite3AddColumn(Parse * pParse, Token * pName, Token * pType)
sqlite3_free(zType);
}
}
- p->nCol++;
p->def->field_count++;
pParse->constraintName.n = 0;
}
@@ -756,9 +730,9 @@ sqlite3AddNotNull(Parse * pParse, int onError)
{
Table *p;
p = pParse->pNewTable;
- if (p == 0 || NEVER(p->nCol < 1))
+ if (p == 0 || NEVER(p->def->field_count < 1))
return;
- p->aCol[p->nCol - 1].notNull = (u8) onError;
+ p->aCol[p->def->field_count - 1].notNull = (u8) onError;
}
/*
@@ -871,38 +845,30 @@ void
sqlite3AddDefaultValue(Parse * pParse, ExprSpan * pSpan)
{
Table *p;
- Column *pCol;
sqlite3 *db = pParse->db;
p = pParse->pNewTable;
if (p != 0) {
- pCol = &(p->aCol[p->nCol - 1]);
if (!sqlite3ExprIsConstantOrFunction
(pSpan->pExpr, db->init.busy)) {
sqlite3ErrorMsg(pParse,
"default value of column [%s] is not constant",
- pCol->zName);
+ p->def->fields[p->def->field_count - 1].name);
} else {
- /* A copy of pExpr is used instead of the original, as pExpr contains
- * tokens that point to volatile memory. The 'span' of the expression
- * is required by pragma table_info.
- */
- Expr x;
assert(p->def != NULL);
struct field_def *field =
- &p->def->fields[p->nCol - 1];
- sql_expr_free(db, field->default_value_expr, false);
-
- memset(&x, 0, sizeof(x));
- x.op = TK_SPAN;
- x.u.zToken = sqlite3DbStrNDup(db, (char *)pSpan->zStart,
- (int)(pSpan->zEnd -
- pSpan->zStart));
- x.pLeft = pSpan->pExpr;
- x.flags = EP_Skip;
-
- field->default_value_expr =
- sqlite3ExprDup(db, &x, EXPRDUP_REDUCE);
- sqlite3DbFree(db, x.u.zToken);
+ &p->def->fields[p->def->field_count - 1];
+ struct region *region = &fiber()->gc;
+ uint32_t default_length = (int)(pSpan->zEnd - pSpan->zStart);
+ field->default_value = region_alloc(region,
+ default_length + 1);
+ if (field->default_value == NULL) {
+ pParse->rc = SQLITE_NOMEM_BKPT;
+ pParse->nErr++;
+ return;
+ }
+ strncpy(field->default_value, (char *)pSpan->zStart,
+ default_length);
+ field->default_value[default_length] = '\0';
}
}
sql_expr_free(db, pSpan->pExpr, false);
@@ -947,7 +913,7 @@ sqlite3AddPrimaryKey(Parse * pParse, /* Parsing context */
}
pTab->tabFlags |= TF_HasPrimaryKey;
if (pList == 0) {
- iCol = pTab->nCol - 1;
+ iCol = pTab->def->field_count - 1;
pCol = &pTab->aCol[iCol];
pCol->is_primkey = 1;
nTerm = 1;
@@ -962,10 +928,10 @@ sqlite3AddPrimaryKey(Parse * pParse, /* Parsing context */
goto primary_key_exit;
}
const char *zCName = pCExpr->u.zToken;
- for (iCol = 0; iCol < pTab->nCol; iCol++) {
+ for (iCol = 0; iCol < (int)pTab->def->field_count; iCol++) {
if (strcmp
(zCName,
- pTab->aCol[iCol].zName) == 0) {
+ pTab->def->fields[iCol].name) == 0) {
pCol = &pTab->aCol[iCol];
pCol->is_primkey = 1;
break;
@@ -1036,7 +1002,7 @@ sqlite3AddCollateType(Parse * pParse, Token * pToken)
if ((p = pParse->pNewTable) == 0)
return;
- i = p->nCol - 1;
+ i = p->def->field_count - 1;
db = pParse->db;
zColl = sqlite3NameFromToken(db, pToken);
if (!zColl)
@@ -1087,7 +1053,7 @@ sql_column_collation(Table *table, uint32_t column)
* SQL specific structures.
*/
if (space == NULL || space_index(space, 0) == NULL) {
- assert(column < (uint32_t)table->nCol);
+ assert(column < (uint32_t)table->def->field_count);
return table->aCol[column].coll;
}
@@ -1306,9 +1272,8 @@ createTableStmt(sqlite3 * db, Table * p)
char *zSep, *zSep2, *zEnd;
Column *pCol;
n = 0;
- for (pCol = p->aCol, i = 0; i < p->nCol; i++, pCol++) {
- n += identLength(pCol->zName) + 5;
- }
+ for (i = 0; i < (int)p->def->field_count; i++)
+ n += identLength(p->def->fields[i].name) + 5;
n += identLength(p->zName);
if (n < 50) {
zSep = "";
@@ -1319,7 +1284,7 @@ createTableStmt(sqlite3 * db, Table * p)
zSep2 = ",\n ";
zEnd = "\n)";
}
- n += 35 + 6 * p->nCol;
+ n += 35 + 6 * p->def->field_count;
zStmt = sqlite3DbMallocRaw(0, n);
if (zStmt == 0) {
sqlite3OomFault(db);
@@ -1329,7 +1294,7 @@ createTableStmt(sqlite3 * db, Table * p)
k = sqlite3Strlen30(zStmt);
identPut(zStmt, &k, p->zName);
zStmt[k++] = '(';
- for (pCol = p->aCol, i = 0; i < p->nCol; i++, pCol++) {
+ for (pCol = p->aCol, i = 0; i < (int)p->def->field_count; i++, pCol++) {
static const char *const azType[] = {
/* SQLITE_AFF_BLOB */ "",
/* SQLITE_AFF_TEXT */ " TEXT",
@@ -1343,7 +1308,7 @@ createTableStmt(sqlite3 * db, Table * p)
sqlite3_snprintf(n - k, &zStmt[k], zSep);
k += sqlite3Strlen30(&zStmt[k]);
zSep = zSep2;
- identPut(zStmt, &k, pCol->zName);
+ 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);
@@ -1373,7 +1338,8 @@ estimateTableWidth(Table * pTab)
unsigned wTable = 0;
const Column *pTabCol;
int i;
- for (i = pTab->nCol, pTabCol = pTab->aCol; i > 0; i--, pTabCol++) {
+ for (i = pTab->def->field_count,
+ pTabCol = pTab->aCol; i > 0; i--, pTabCol++) {
wTable += pTabCol->szEst;
}
if (pTab->iPKey < 0)
@@ -1392,7 +1358,7 @@ estimateIndexWidth(Index * pIdx)
const Column *aCol = pIdx->pTable->aCol;
for (i = 0; i < pIdx->nColumn; i++) {
i16 x = pIdx->aiColumn[i];
- assert(x < pIdx->pTable->nCol);
+ assert(x < (int)pIdx->pTable->def->field_count);
wIndex += x < 0 ? 1 : aCol[pIdx->aiColumn[i]].szEst;
}
pIdx->szIdxRow = sqlite3LogEst(wIndex * 4);
@@ -1433,7 +1399,7 @@ convertToWithoutRowidTable(Parse * pParse, Table * pTab)
/* Mark every PRIMARY KEY column as NOT NULL (except for imposter tables)
*/
if (!db->init.imposterTable) {
- for (i = 0; i < pTab->nCol; i++) {
+ for (i = 0; i < (int)pTab->def->field_count; i++) {
if (pTab->aCol[i].is_primkey) {
pTab->aCol[i].notNull = ON_CONFLICT_ACTION_ABORT;
}
@@ -1446,7 +1412,7 @@ convertToWithoutRowidTable(Parse * pParse, Table * pTab)
if (pTab->iPKey >= 0) {
ExprList *pList;
Token ipkToken;
- sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zName);
+ sqlite3TokenInit(&ipkToken, pTab->def->fields[pTab->iPKey].name);
pList = sqlite3ExprListAppend(pParse, 0,
sqlite3ExprAlloc(db, TK_ID,
&ipkToken, 0));
@@ -1663,7 +1629,7 @@ createSpace(Parse * pParse, int iSpaceId, char *zStmt)
sqlite3DbStrDup(pParse->db, p->zName), P4_DYNAMIC);
sqlite3VdbeAddOp4(v, OP_String8, 0, iFirstCol + 3 /* engine */ , 0,
"memtx", P4_STATIC);
- sqlite3VdbeAddOp2(v, OP_Integer, p->nCol,
+ sqlite3VdbeAddOp2(v, OP_Integer, p->def->field_count,
iFirstCol + 4 /* field_count */ );
sqlite3VdbeAddOp4(v, OP_Blob, zOptsSz, iFirstCol + 5, MSGPACK_SUBTYPE,
zOpts, P4_DYNAMIC);
@@ -1853,6 +1819,8 @@ sqlite3EndTable(Parse * pParse, /* Parse context */
p = pParse->pNewTable;
if (p == 0)
return;
+ if (sql_table_def_rebuild(db, p) != 0)
+ return;
assert(!db->init.busy || !pSelect);
@@ -2101,7 +2069,7 @@ sqlite3ViewGetColumnNames(Parse * pParse, Table * pTable)
/* A positive nCol means the columns names for this view are
* already known.
*/
- if (pTable->nCol > 0)
+ if (pTable->def->field_count > 0)
return 0;
/* A negative nCol is a special marker meaning that we are currently
@@ -2119,12 +2087,12 @@ sqlite3ViewGetColumnNames(Parse * pParse, Table * pTable)
* CREATE TEMP VIEW ex1 AS SELECT a FROM ex1;
* SELECT * FROM temp.ex1;
*/
- if (pTable->nCol < 0) {
+ if ((int)pTable->def->field_count < 0) {
sqlite3ErrorMsg(pParse, "view %s is circularly defined",
pTable->zName);
return 1;
}
- assert(pTable->nCol >= 0);
+ assert((int)pTable->def->field_count >= 0);
/* If we get this far, it means we need to compute the table names.
* Note that the call to sqlite3ResultSetOfSelect() will expand any
@@ -2138,7 +2106,7 @@ sqlite3ViewGetColumnNames(Parse * pParse, Table * pTable)
if (pSel) {
n = pParse->nTab;
sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
- pTable->nCol = -1;
+ pTable->def->field_count = -1;
db->lookaside.bDisable++;
pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
pParse->nTab = n;
@@ -2149,11 +2117,9 @@ sqlite3ViewGetColumnNames(Parse * pParse, Table * pTable)
* normally holds CHECK constraints on an ordinary table, but for
* a VIEW it holds the list of column names.
*/
- sqlite3ColumnsFromExprList(pParse, pTable->pCheck,
- &pTable->nCol,
- &pTable->aCol);
+ sqlite3ColumnsFromExprList(pParse, pTable->pCheck, pTable);
if (db->mallocFailed == 0 && pParse->nErr == 0
- && pTable->nCol == pSel->pEList->nExpr) {
+ && (int)pTable->def->field_count == pSel->pEList->nExpr) {
sqlite3SelectAddColumnTypeAndCollation(pParse,
pTable,
pSel);
@@ -2163,12 +2129,15 @@ sqlite3ViewGetColumnNames(Parse * pParse, Table * pTable)
* the column names from the SELECT statement that defines the view.
*/
assert(pTable->aCol == 0);
- pTable->nCol = pSelTab->nCol;
+ assert((int)pTable->def->field_count == -1);
+ struct space_def *def = pSelTab->def;
+ pSelTab->def = pTable->def;
+ pSelTab->def->field_count = 0;
+ pTable->def = def;
pTable->aCol = pSelTab->aCol;
- pSelTab->nCol = 0;
pSelTab->aCol = 0;
} else {
- pTable->nCol = 0;
+ pTable->def->field_count = 0;
nErr++;
}
sqlite3DeleteTable(db, pSelTab);
@@ -2195,8 +2164,18 @@ sqliteViewResetAll(sqlite3 * db)
Table *pTab = sqliteHashData(i);
if (pTab->pSelect) {
sqlite3DeleteColumnNames(db, pTab);
+ struct space_def *old_def = pTab->def;
+ pTab->def = space_def_new(old_def->id, old_def->uid,
+ 0,
+ old_def->name,
+ strlen(old_def->name),
+ old_def->engine_name,
+ strlen(old_def->engine_name),
+ &old_def->opts,
+ NULL, 0);
+ assert(pTab->def);
+ space_def_delete(old_def);
pTab->aCol = 0;
- pTab->nCol = 0;
}
}
}
@@ -2469,13 +2448,13 @@ sqlite3CreateForeignKey(Parse * pParse, /* Parsing context */
if (p == 0)
goto fk_end;
if (pFromCol == 0) {
- int iCol = p->nCol - 1;
+ int iCol = p->def->field_count - 1;
if (NEVER(iCol < 0))
goto fk_end;
if (pToCol && pToCol->nExpr != 1) {
sqlite3ErrorMsg(pParse, "foreign key on %s"
" should reference only one column of table %T",
- p->aCol[iCol].zName, pTo);
+ p->def->fields[iCol].name, pTo);
goto fk_end;
}
nCol = 1;
@@ -2508,19 +2487,19 @@ sqlite3CreateForeignKey(Parse * pParse, /* Parsing context */
z += pTo->n + 1;
pFKey->nCol = nCol;
if (pFromCol == 0) {
- pFKey->aCol[0].iFrom = p->nCol - 1;
+ pFKey->aCol[0].iFrom = p->def->field_count - 1;
} else {
for (i = 0; i < nCol; i++) {
int j;
- for (j = 0; j < p->nCol; j++) {
+ for (j = 0; j < (int)p->def->field_count; j++) {
if (strcmp
- (p->aCol[j].zName,
+ (p->def->fields[j].name,
pFromCol->a[i].zName) == 0) {
pFKey->aCol[i].iFrom = j;
break;
}
}
- if (j >= p->nCol) {
+ if (j >= (int)p->def->field_count) {
sqlite3ErrorMsg(pParse,
"unknown column \"%s\" in foreign key definition",
pFromCol->a[i].zName);
@@ -2966,7 +2945,9 @@ sqlite3CreateIndex(Parse * pParse, /* All information about this parse */
*/
if (pList == 0) {
Token prevCol;
- sqlite3TokenInit(&prevCol, pTab->aCol[pTab->nCol - 1].zName);
+ sqlite3TokenInit(&prevCol,
+ pTab->def->
+ fields[pTab->def->field_count - 1].name);
pList = sqlite3ExprListAppend(pParse, 0,
sqlite3ExprAlloc(db, TK_ID,
&prevCol, 0));
@@ -4018,7 +3999,7 @@ sqlite3UniqueConstraint(Parse * pParse, /* Parsing context */
for (j = 0; j < pIdx->nColumn; j++) {
char *zCol;
assert(pIdx->aiColumn[j] >= 0);
- zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
+ zCol = pTab->def->fields[pIdx->aiColumn[j]].name;
if (j)
sqlite3StrAccumAppend(&errMsg, ", ", 2);
sqlite3XPrintf(&errMsg, "%s.%s", pTab->zName, zCol);
@@ -4181,7 +4162,7 @@ sqlite3KeyInfoOfIndex(Parse * pParse, sqlite3 * db, Index * pIdx)
{
int i;
int nCol = pIdx->nColumn;
- int nTableCol = pIdx->pTable->nCol;
+ int nTableCol = pIdx->pTable->def->field_count;
KeyInfo *pKey;
if (pParse && pParse->nErr)
diff --git a/src/box/sql/delete.c b/src/box/sql/delete.c
index 3f74b93..65d20fa 100644
--- a/src/box/sql/delete.c
+++ b/src/box/sql/delete.c
@@ -382,7 +382,7 @@ sqlite3DeleteFrom(Parse * pParse, /* The parser context */
* there is no PK for it, so columns should be loaded manually.
*/
if (isView) {
- nPk = pTab->nCol;
+ nPk = pTab->def->field_count;
iPk = pParse->nMem + 1;
pParse->nMem += nPk;
iEphCur = pParse->nTab++;
@@ -734,13 +734,13 @@ sqlite3GenerateRowDelete(Parse * pParse, /* Parsing context */
onconf);
mask |= sqlite3FkOldmask(pParse, pTab);
iOld = pParse->nMem + 1;
- pParse->nMem += (1 + pTab->nCol);
+ pParse->nMem += (1 + pTab->def->field_count);
/* Populate the OLD.* pseudo-table register array. These values will be
* used by any BEFORE and AFTER triggers that exist.
*/
sqlite3VdbeAddOp2(v, OP_Copy, iPk, iOld);
- for (iCol = 0; iCol < pTab->nCol; iCol++) {
+ for (iCol = 0; iCol < (int)pTab->def->field_count; iCol++) {
testcase(mask != 0xffffffff && iCol == 31);
testcase(mask != 0xffffffff && iCol == 32);
if (mask == 0xffffffff
diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c
index 0c86761..5f7d741 100644
--- a/src/box/sql/expr.c
+++ b/src/box/sql/expr.c
@@ -48,7 +48,7 @@ static int exprCodeVector(Parse * pParse, Expr * p, int *piToFree);
char
sqlite3TableColumnAffinity(Table * pTab, int iCol)
{
- assert(iCol < pTab->nCol);
+ assert(iCol < (int)pTab->def->field_count);
return iCol >= 0 ? pTab->aCol[iCol].affinity : SQLITE_AFF_INTEGER;
}
@@ -4242,20 +4242,21 @@ sqlite3ExprCodeTarget(Parse * pParse, Expr * pExpr, int target)
*/
Table *pTab = pExpr->pTab;
int p1 =
- pExpr->iTable * (pTab->nCol + 1) + 1 +
+ pExpr->iTable * (pTab->def->field_count + 1) + 1 +
pExpr->iColumn;
assert(pExpr->iTable == 0 || pExpr->iTable == 1);
assert(pExpr->iColumn >= 0
- && pExpr->iColumn < pTab->nCol);
+ && pExpr->iColumn < (int)pTab->def->field_count);
assert(pTab->iPKey < 0
|| pExpr->iColumn != pTab->iPKey);
- assert(p1 >= 0 && p1 < (pTab->nCol * 2 + 2));
+ assert(p1 >= 0 && p1 <
+ ((int)pTab->def->field_count * 2 + 2));
sqlite3VdbeAddOp2(v, OP_Param, p1, target);
VdbeComment((v, "%s.%s -> $%d",
(pExpr->iTable ? "new" : "old"),
- pExpr->pTab->aCol[pExpr->iColumn].zName,
+ pExpr->pTab->def->fields[pExpr->iColumn].name,
target));
#ifndef SQLITE_OMIT_FLOATING_POINT
diff --git a/src/box/sql/fkey.c b/src/box/sql/fkey.c
index fb9a310..c15ad8c 100644
--- a/src/box/sql/fkey.c
+++ b/src/box/sql/fkey.c
@@ -243,7 +243,7 @@ sqlite3FkLocateIndex(Parse * pParse, /* Parse context to store any error in */
if (!zKey)
return 0;
if (!strcmp
- (pParent->aCol[pParent->iPKey].zName, zKey))
+ (pParent->def->fields[pParent->iPKey].name, zKey))
return 0;
}
} else if (paiCol) {
@@ -305,7 +305,7 @@ sqlite3FkLocateIndex(Parse * pParse, /* Parse context to store any error in */
if (def_coll != coll)
break;
- zIdxCol = pParent->aCol[iCol].zName;
+ zIdxCol = pParent->def->fields[iCol].name;
for (j = 0; j < nCol; j++) {
if (strcmp
(pFKey->aCol[j].zCol,
@@ -650,7 +650,7 @@ fkScanChildren(Parse * pParse, /* Parse context */
pLeft = exprTableRegister(pParse, pTab, regData, iCol);
iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
assert(iCol >= 0);
- zCol = pFKey->pFrom->aCol[iCol].zName;
+ zCol = pFKey->pFrom->def->fields[iCol].name;
pRight = sqlite3Expr(db, TK_ID, zCol);
pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
pWhere = sqlite3ExprAnd(db, pWhere, pEq);
@@ -863,12 +863,12 @@ fkParentIsModified(Table * pTab, FKey * p, int *aChange)
for (i = 0; i < p->nCol; i++) {
char *zKey = p->aCol[i].zCol;
int iKey;
- for (iKey = 0; iKey < pTab->nCol; iKey++) {
+ for (iKey = 0; iKey < (int)pTab->def->field_count; iKey++) {
if (aChange[iKey] >= 0) {
- Column *pCol = &pTab->aCol[iKey];
if (zKey) {
if (0 ==
- strcmp(pCol->zName, zKey))
+ strcmp(pTab->def->fields[iKey].name,
+ zKey))
return 1;
} else if (table_column_is_in_pk(pTab, iKey)) {
return 1;
@@ -1282,14 +1282,14 @@ fkActionTrigger(Parse * pParse, /* Parse context */
assert(iFromCol >= 0);
assert(pIdx != 0
|| (pTab->iPKey >= 0
- && pTab->iPKey < pTab->nCol));
+ && pTab->iPKey < (int)pTab->def->field_count));
assert(pIdx == 0 || pIdx->aiColumn[i] >= 0);
sqlite3TokenInit(&tToCol,
- pTab->aCol[pIdx ? pIdx->
+ pTab->def->fields[pIdx ? pIdx->
aiColumn[i] : pTab->iPKey].
- zName);
+ name);
sqlite3TokenInit(&tFromCol,
- pFKey->pFrom->aCol[iFromCol].zName);
+ pFKey->pFrom->def->fields[iFromCol].name);
/* Create the expression "OLD.zToCol = zFromCol". It is important
* that the "OLD.zToCol" term is on the LHS of the = operator, so
diff --git a/src/box/sql/insert.c b/src/box/sql/insert.c
index 1cb9525..06635ee 100644
--- a/src/box/sql/insert.c
+++ b/src/box/sql/insert.c
@@ -146,13 +146,14 @@ sqlite3TableAffinity(Vdbe * v, Table * pTab, int iReg)
char *zColAff = pTab->zColAff;
if (zColAff == 0) {
sqlite3 *db = sqlite3VdbeDb(v);
- zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol + 1);
+ zColAff = (char *)sqlite3DbMallocRaw(0,
+ pTab->def->field_count + 1);
if (!zColAff) {
sqlite3OomFault(db);
return;
}
- for (i = 0; i < pTab->nCol; i++) {
+ for (i = 0; i < (int)pTab->def->field_count; i++) {
zColAff[i] = pTab->aCol[i].affinity;
}
do {
@@ -446,7 +447,7 @@ sqlite3Insert(Parse * pParse, /* Parser context */
* the content of the new row, and the assembled row record.
*/
regTupleid = regIns = pParse->nMem + 1;
- pParse->nMem += pTab->nCol + 1;
+ pParse->nMem += pTab->def->field_count + 1;
regData = regTupleid + 1;
/* If the INSERT statement included an IDLIST term, then make sure
@@ -465,17 +466,17 @@ sqlite3Insert(Parse * pParse, /* Parser context */
/* The size of used_columns buffer is checked during compilation time
* using SQLITE_MAX_COLUMN constant.
*/
- memset(used_columns, 0, (pTab->nCol + 7) / 8);
+ memset(used_columns, 0, (pTab->def->field_count + 7) / 8);
bIdListInOrder = 1;
if (pColumn) {
for (i = 0; i < pColumn->nId; i++) {
pColumn->a[i].idx = -1;
}
for (i = 0; i < pColumn->nId; i++) {
- for (j = 0; j < pTab->nCol; j++) {
+ for (j = 0; j < (int)pTab->def->field_count; j++) {
if (strcmp
(pColumn->a[i].zName,
- pTab->aCol[j].zName) == 0) {
+ pTab->def->fields[j].name) == 0) {
pColumn->a[i].idx = j;
if (i != j)
bIdListInOrder = 0;
@@ -486,7 +487,7 @@ sqlite3Insert(Parse * pParse, /* Parser context */
break;
}
}
- if (j >= pTab->nCol) {
+ if (j >= (int)pTab->def->field_count) {
sqlite3ErrorMsg(pParse,
"table %S has no column named %s",
pTabList, 0, pColumn->a[i].zName);
@@ -522,7 +523,7 @@ sqlite3Insert(Parse * pParse, /* Parser context */
sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
dest.iSdst = bIdListInOrder ? regData : 0;
- dest.nSdst = pTab->nCol;
+ dest.nSdst = pTab->def->field_count;
rc = sqlite3Select(pParse, pSelect, &dest);
regFromSelect = dest.iSdst;
if (rc || db->mallocFailed || pParse->nErr)
@@ -611,10 +612,10 @@ sqlite3Insert(Parse * pParse, /* Parser context */
ipkColumn = pTab->iPKey;
}
- if (pColumn == 0 && nColumn && nColumn != (pTab->nCol)) {
+ if (pColumn == 0 && nColumn && nColumn != ((int)pTab->def->field_count)) {
sqlite3ErrorMsg(pParse,
"table %S has %d columns but %d values were supplied",
- pTabList, 0, pTab->nCol, nColumn);
+ pTabList, 0, pTab->def->field_count, nColumn);
goto insert_cleanup;
}
if (pColumn != 0 && nColumn != pColumn->nId) {
@@ -682,11 +683,12 @@ sqlite3Insert(Parse * pParse, /* Parser context */
*/
endOfLoop = sqlite3VdbeMakeLabel(v);
if (tmask & TRIGGER_BEFORE) {
- int regCols = sqlite3GetTempRange(pParse, pTab->nCol + 1);
+ int regCols = sqlite3GetTempRange(pParse,
+ pTab->def->field_count + 1);
/* Create the new column data
*/
- for (i = j = 0; i < pTab->nCol; i++) {
+ for (i = j = 0; i < (int)pTab->def->field_count; i++) {
if (pColumn) {
for (j = 0; j < pColumn->nId; j++) {
if (pColumn->a[j].idx == i)
@@ -732,10 +734,11 @@ sqlite3Insert(Parse * pParse, /* Parser context */
/* Fire BEFORE or INSTEAD OF triggers */
sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0,
TRIGGER_BEFORE, pTab,
- regCols - pTab->nCol - 1, onError,
- endOfLoop);
+ regCols - pTab->def->field_count - 1,
+ onError, endOfLoop);
- sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol + 1);
+ sqlite3ReleaseTempRange(pParse, regCols,
+ pTab->def->field_count + 1);
}
/* Compute the content of the next row to insert into a range of
@@ -758,7 +761,7 @@ sqlite3Insert(Parse * pParse, /* Parser context */
/* Compute data for all columns of the new entry, beginning
* with the first column.
*/
- for (i = 0; i < pTab->nCol; i++) {
+ for (i = 0; i < (int)pTab->def->field_count; i++) {
int iRegStore = regData + i;
if (pColumn == 0) {
j = i;
@@ -879,8 +882,8 @@ sqlite3Insert(Parse * pParse, /* Parser context */
/* Code AFTER triggers */
sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0,
TRIGGER_AFTER, pTab,
- regData - 2 - pTab->nCol, onError,
- endOfLoop);
+ regData - 2 - pTab->def->field_count,
+ onError, endOfLoop);
}
/* The bottom of the main insertion loop, if the data source
@@ -1093,7 +1096,7 @@ sqlite3GenerateConstraintChecks(Parse * pParse, /* The parser context */
assert(v != 0);
/* This table is not a VIEW */
assert(!space_is_view(pTab));
- nCol = pTab->nCol;
+ nCol = pTab->def->field_count;
pPk = sqlite3PrimaryKeyIndex(pTab);
nPkField = index_column_count(pPk);
@@ -1143,7 +1146,7 @@ sqlite3GenerateConstraintChecks(Parse * pParse, /* The parser context */
case ON_CONFLICT_ACTION_FAIL: {
char *zMsg =
sqlite3MPrintf(db, "%s.%s", pTab->zName,
- pTab->aCol[i].zName);
+ pTab->def->fields[i].name);
sqlite3VdbeAddOp3(v, OP_HaltIfNull,
SQLITE_CONSTRAINT_NOTNULL,
onError, regNewData + 1 + i);
@@ -1282,7 +1285,8 @@ sqlite3GenerateConstraintChecks(Parse * pParse, /* The parser context */
sqlite3VdbeAddOp2(v, OP_SCopy,
x, regIdx + i);
VdbeComment((v, "%s",
- pTab->aCol[iField].zName));
+ pTab->def->fields[iField].
+ name));
}
}
}
@@ -1310,7 +1314,7 @@ sqlite3GenerateConstraintChecks(Parse * pParse, /* The parser context */
}
if (IsPrimaryKeyIndex(pIdx) || uniqueByteCodeNeeded) {
sqlite3VdbeAddOp3(v, OP_MakeRecord, regNewData + 1,
- pTab->nCol, aRegIdx[ix]);
+ pTab->def->field_count, aRegIdx[ix]);
VdbeComment((v, "for %s", pIdx->zName));
}
} else {
@@ -1401,7 +1405,8 @@ sqlite3GenerateConstraintChecks(Parse * pParse, /* The parser context */
sqlite3VdbeAddOp3(v, OP_Column,
iThisCur, x, regR + i);
VdbeComment((v, "%s.%s", pTab->zName,
- pTab->aCol[pPk->aiColumn[i]].zName));
+ pTab->def->fields[
+ pPk->aiColumn[i]].name));
}
}
if (isUpdate && uniqueByteCodeNeeded) {
@@ -1792,13 +1797,13 @@ xferOptimization(Parse * pParse, /* Parser context */
if (space_is_view(pSrc)) {
return 0; /* tab2 may not be a view */
}
- if (pDest->nCol != pSrc->nCol) {
+ if (pDest->def->field_count != pSrc->def->field_count) {
return 0; /* Number of columns must be the same in tab1 and tab2 */
}
if (pDest->iPKey != pSrc->iPKey) {
return 0; /* Both tables must have the same INTEGER PRIMARY KEY */
}
- for (i = 0; i < pDest->nCol; i++) {
+ 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) {
diff --git a/src/box/sql/pragma.c b/src/box/sql/pragma.c
index 4a68cad..e93f377 100644
--- a/src/box/sql/pragma.c
+++ b/src/box/sql/pragma.c
@@ -359,7 +359,8 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */
Index *pPk = sqlite3PrimaryKeyIndex(pTab);
pParse->nMem = 6;
sqlite3ViewGetColumnNames(pParse, pTab);
- for (i = 0, pCol = pTab->aCol; i < pTab->nCol;
+ for (i = 0, pCol = pTab->aCol;
+ i < (int)pTab->def->field_count;
i++, pCol++) {
if (!table_column_is_in_pk(pTab, i)) {
k = 0;
@@ -367,7 +368,7 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */
k = 1;
} else {
for (k = 1;
- k <= pTab->nCol
+ k <= (int)pTab->def->field_count
&& pPk->aiColumn[k - 1] !=
i; k++) {
}
@@ -381,7 +382,9 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */
char *expr_str = space->
def->fields[i].default_value;
sqlite3VdbeMultiLoad(v, 1, "issisi",
- i, pCol->zName,
+ i,
+ pTab->def->fields[i].
+ name,
field_type_strs[
sqlite3ColumnType
(pCol)],
@@ -453,8 +456,9 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */
0 ? 0 :
pIdx->
pTable->
- aCol[cnum].
- zName);
+ def->
+ fields[cnum].
+ name);
if (pPragma->iArg) {
const char *c_n;
struct coll *coll;
@@ -559,7 +563,7 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */
while (pFK) {
for (int j = 0; j < pFK->nCol; j++) {
const char *name =
- pTab->aCol[pFK->aCol[j].iFrom].zName;
+ pTab->def->fields[pFK->aCol[j].iFrom].name;
sqlite3VdbeMultiLoad(v, 1, "iissssss", i, j,
pFK->zTo, name,
pFK->aCol[j].zCol,
@@ -614,8 +618,9 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */
}
if (pTab == 0 || pTab->pFKey == 0)
continue;
- if (pTab->nCol + regRow > pParse->nMem)
- pParse->nMem = pTab->nCol + regRow;
+ if ((int)pTab->def->field_count + regRow > pParse->nMem)
+ pParse->nMem =
+ pTab->def->field_count + regRow;
sqlite3OpenTable(pParse, 0, pTab, OP_OpenRead);
sqlite3VdbeLoadString(v, regResult,
pTab->zName);
@@ -677,7 +682,8 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */
if (pParent && pIdx == 0) {
int iKey = pFK->aCol[0].iFrom;
assert(iKey >= 0
- && iKey < pTab->nCol);
+ && iKey <
+ (int)pTab->def->field_count);
if (iKey != pTab->iPKey) {
sqlite3VdbeAddOp3(v,
OP_Column,
diff --git a/src/box/sql/resolve.c b/src/box/sql/resolve.c
index 823062a..109c410 100644
--- a/src/box/sql/resolve.c
+++ b/src/box/sql/resolve.c
@@ -240,7 +240,7 @@ lookupName(Parse * pParse, /* The parsing context */
i++, pItem++) {
pTab = pItem->pTab;
assert(pTab != 0 && pTab->zName != 0);
- assert(pTab->nCol > 0);
+ assert(pTab->def->field_count > 0);
if (pItem->pSelect
&& (pItem->pSelect->
selFlags & SF_NestedFrom) != 0) {
@@ -272,9 +272,10 @@ lookupName(Parse * pParse, /* The parsing context */
if (0 == (cntTab++)) {
pMatch = pItem;
}
- for (j = 0, pCol = pTab->aCol; j < pTab->nCol;
+ for (j = 0, pCol = pTab->aCol;
+ j < (int)pTab->def->field_count;
j++, pCol++) {
- if (strcmp(pCol->zName, zCol) ==
+ if (strcmp(pTab->def->fields[j].name, zCol) ==
0) {
/* If there has been exactly one prior match and this match
* is for the right-hand table of a NATURAL JOIN or is in a
@@ -332,16 +333,17 @@ lookupName(Parse * pParse, /* The parsing context */
int iCol;
cntTab++;
for (iCol = 0, pCol = pTab->aCol;
- iCol < pTab->nCol; iCol++, pCol++) {
- if (strcmp(pCol->zName, zCol) ==
- 0) {
+ iCol < (int)pTab->def->field_count;
+ iCol++, pCol++) {
+ if (strcmp(pTab->def->fields[iCol].name,
+ zCol) == 0) {
if (iCol == pTab->iPKey) {
iCol = -1;
}
break;
}
}
- if (iCol < pTab->nCol) {
+ if (iCol < (int)pTab->def->field_count) {
cnt++;
if (iCol < 0) {
pExpr->affinity =
diff --git a/src/box/sql/select.c b/src/box/sql/select.c
index 5a50413..1390c5d 100644
--- a/src/box/sql/select.c
+++ b/src/box/sql/select.c
@@ -318,9 +318,9 @@ sqlite3JoinType(Parse * pParse, Token * pA, Token * pB, Token * pC)
static int
columnIndex(Table * pTab, const char *zCol)
{
- int i;
- for (i = 0; i < pTab->nCol; i++) {
- if (strcmp(pTab->aCol[i].zName, zCol) == 0)
+ uint32_t i;
+ for (i = 0; i < pTab->def->field_count; i++) {
+ if (strcmp(pTab->def->fields[i].name, zCol) == 0)
return i;
}
return -1;
@@ -492,12 +492,12 @@ sqliteProcessJoin(Parse * pParse, Select * p)
"an ON or USING clause", 0);
return 1;
}
- for (j = 0; j < pRightTab->nCol; j++) {
+ for (j = 0; j < (int)pRightTab->def->field_count; j++) {
char *zName; /* Name of column in the right table */
int iLeft; /* Matching left table */
int iLeftCol; /* Matching column in the left table */
- zName = pRightTab->aCol[j].zName;
+ zName = pRightTab->def->fields[j].name;
if (tableAndColumnIndex
(pSrc, i + 1, zName, &iLeft, &iLeftCol)) {
addWhereTerm(pParse, pSrc, iLeft,
@@ -1661,7 +1661,8 @@ columnTypeImpl(NameContext * pNC, Expr * pExpr,
} else if (pTab->pSchema) {
/* A real table */
assert(!pS);
- assert(iCol >= 0 && iCol < pTab->nCol);
+ assert(iCol >= 0 && iCol <
+ (int)pTab->def->field_count);
#ifdef SQLITE_ENABLE_COLUMN_METADATA
zOrigCol = pTab->aCol[iCol].zName;
zType = sqlite3ColumnType(&pTab->aCol[iCol], 0);
@@ -1754,8 +1755,8 @@ generateColumnNames(Parse * pParse, /* Parser context */
pTab = pTabList->a[j].pTab;
if (iCol < 0)
iCol = pTab->iPKey;
- assert(iCol >= 0 && iCol < pTab->nCol);
- zCol = pTab->aCol[iCol].zName;
+ assert(iCol >= 0 && iCol < (int)pTab->def->field_count);
+ zCol = pTab->def->fields[iCol].name;
if (!shortNames && !fullNames) {
sqlite3VdbeSetColName(v, i, COLNAME_NAME,
sqlite3DbStrDup(db,
@@ -1799,8 +1800,7 @@ generateColumnNames(Parse * pParse, /* Parser context */
int
sqlite3ColumnsFromExprList(Parse * pParse, /* Parsing context */
ExprList * pEList, /* Expr list from which to derive column names */
- i16 * pnCol, /* Write the number of columns here */
- Column ** paCol) /* Write the new column list here */
+ Table * pTable) /* Pointer to SQL Table Object*/
{
sqlite3 *db = pParse->db; /* Database connection */
int i, j; /* Loop counters */
@@ -1822,8 +1822,11 @@ sqlite3ColumnsFromExprList(Parse * pParse, /* Parsing context */
aCol = 0;
}
assert(nCol == (i16) nCol);
- *pnCol = nCol;
- *paCol = aCol;
+ assert(pTable->def->fields == NULL);
+ pTable->def->fields =
+ sqlite3DbMallocZero(db, nCol*sizeof(pTable->def->fields[0]));
+ pTable->def->field_count = (uint32_t)nCol;
+ pTable->aCol = aCol;
for (i = 0, pCol = aCol; i < nCol && !db->mallocFailed; i++, pCol++) {
/* Get an appropriate name for the column
@@ -1845,7 +1848,7 @@ sqlite3ColumnsFromExprList(Parse * pParse, /* Parsing context */
pTab = pColExpr->pTab;
if (iCol < 0)
iCol = pTab->iPKey;
- zName = pTab->aCol[iCol].zName;
+ zName = pTab->def->fields[iCol].name;
} else if (pColExpr->op == TK_ID) {
assert(!ExprHasProperty(pColExpr, EP_IntValue));
zName = pColExpr->u.zToken;
@@ -1874,22 +1877,24 @@ sqlite3ColumnsFromExprList(Parse * pParse, /* Parsing context */
if (cnt > 3)
sqlite3_randomness(sizeof(cnt), &cnt);
}
- pCol->zName = zName;
+ pTable->def->fields[i].name = zName;
if (zName && sqlite3HashInsert(&ht, zName, pCol) == pCol) {
sqlite3OomFault(db);
}
}
sqlite3HashClear(&ht);
- if (db->mallocFailed) {
- for (j = 0; j < i; j++) {
- sqlite3DbFree(db, aCol[j].zName);
- }
+ int rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_OK;
+ if (sql_table_def_rebuild(db, pTable) != 0)
+ rc = SQLITE_NOMEM_BKPT;
+ if (rc != SQLITE_OK) {
sqlite3DbFree(db, aCol);
- *paCol = 0;
- *pnCol = 0;
- return SQLITE_NOMEM_BKPT;
+ sqlite3DbFree(db, pTable->def->fields);
+ pTable->def->fields = NULL;
+ pTable->def->field_count = 0;
+ pTable->aCol = 0;
+ rc = SQLITE_NOMEM_BKPT;
}
- return SQLITE_OK;
+ return rc;
}
/*
@@ -1918,13 +1923,15 @@ sqlite3SelectAddColumnTypeAndCollation(Parse * pParse, /* Parsing contexts */
assert(pSelect != 0);
assert((pSelect->selFlags & SF_Resolved) != 0);
- assert(pTab->nCol == pSelect->pEList->nExpr || db->mallocFailed);
+ assert((int)pTab->def->field_count == pSelect->pEList->nExpr
+ || db->mallocFailed);
if (db->mallocFailed)
return;
memset(&sNC, 0, sizeof(sNC));
sNC.pSrcList = pSelect->pSrc;
a = pSelect->pEList->a;
- for (i = 0, pCol = pTab->aCol; i < pTab->nCol; i++, pCol++) {
+ for (i = 0, pCol = pTab->aCol;
+ i < (int)pTab->def->field_count; i++, pCol++) {
enum field_type type;
p = a[i].pExpr;
type = columnType(&sNC, p, 0, 0, 0, &pCol->szEst);
@@ -1963,10 +1970,9 @@ sqlite3ResultSetOfSelect(Parse * pParse, Select * pSelect)
while (pSelect->pPrior)
pSelect = pSelect->pPrior;
user_session->sql_flags = savedFlags;
- pTab = sqlite3DbMallocZero(db, sizeof(Table));
- if (pTab == 0) {
+ pTab = sql_ephemeral_table_new(pParse);
+ if (pTab == NULL)
return 0;
- }
/* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside
* is disabled
*/
@@ -1975,8 +1981,7 @@ sqlite3ResultSetOfSelect(Parse * pParse, Select * pSelect)
pTab->zName = 0;
pTab->nRowLogEst = 200;
assert(200 == sqlite3LogEst(1048576));
- sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol,
- &pTab->aCol);
+ sqlite3ColumnsFromExprList(pParse, pSelect->pEList, pTab);
sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSelect);
pTab->iPKey = -1;
if (db->mallocFailed) {
@@ -4497,8 +4502,8 @@ withExpand(Walker * pWalker, struct SrcList_item *pFrom)
return SQLITE_ERROR;
assert(pFrom->pTab == 0);
- pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
- if (pTab == 0)
+ pFrom->pTab = pTab = sql_ephemeral_table_new(pParse);
+ if (pTab == NULL)
return WRC_Abort;
pTab->nTabRef = 1;
pTab->zName = sqlite3DbStrDup(db, pCte->zName);
@@ -4562,8 +4567,7 @@ withExpand(Walker * pWalker, struct SrcList_item *pFrom)
pEList = pCte->pCols;
}
- sqlite3ColumnsFromExprList(pParse, pEList, &pTab->nCol,
- &pTab->aCol);
+ sqlite3ColumnsFromExprList(pParse, pEList, pTab);
if (bMayRecursive) {
if (pSel->selFlags & SF_Recursive) {
pCte->zCteErr =
@@ -4684,8 +4688,8 @@ selectExpander(Walker * pWalker, Select * p)
if (sqlite3WalkSelect(pWalker, pSel))
return WRC_Abort;
pFrom->pTab = pTab =
- sqlite3DbMallocZero(db, sizeof(Table));
- if (pTab == 0)
+ sql_ephemeral_table_new(pParse);
+ if (pTab == NULL)
return WRC_Abort;
pTab->nTabRef = 1;
pTab->zName =
@@ -4693,8 +4697,7 @@ selectExpander(Walker * pWalker, Select * p)
while (pSel->pPrior) {
pSel = pSel->pPrior;
}
- sqlite3ColumnsFromExprList(pParse, pSel->pEList,
- &pTab->nCol, &pTab->aCol);
+ sqlite3ColumnsFromExprList(pParse, pSel->pEList, pTab);
pTab->iPKey = -1;
pTab->nRowLogEst = 200;
assert(200 == sqlite3LogEst(1048576));
@@ -4727,10 +4730,10 @@ selectExpander(Walker * pWalker, Select * p)
sqlite3SelectDup(db, pTab->pSelect, 0);
sqlite3SelectSetName(pFrom->pSelect,
pTab->zName);
- nCol = pTab->nCol;
- pTab->nCol = -1;
+ nCol = pTab->def->field_count;
+ pTab->def->field_count = -1;
sqlite3WalkSelect(pWalker, pFrom->pSelect);
- pTab->nCol = nCol;
+ pTab->def->field_count = nCol;
}
#endif
}
@@ -4835,9 +4838,8 @@ selectExpander(Walker * pWalker, Select * p)
continue;
}
}
- for (j = 0; j < pTab->nCol; j++) {
- char *zName =
- pTab->aCol[j].zName;
+ for (j = 0; j < (int)pTab->def->field_count; j++) {
+ char *zName = pTab->def->fields[j].name;
char *zColname; /* The computed column name */
char *zToFree; /* Malloced string that needs to be freed */
Token sColname; /* Computed column name as a token */
@@ -5372,10 +5374,10 @@ sqlite3Select(Parse * pParse, /* The parser context */
/* Catch mismatch in the declared columns of a view and the number of
* columns in the SELECT on the RHS
*/
- if (pTab->nCol != pSub->pEList->nExpr) {
+ if ((int)pTab->def->field_count != pSub->pEList->nExpr) {
sqlite3ErrorMsg(pParse,
"expected %d columns for '%s' but got %d",
- pTab->nCol, pTab->zName,
+ pTab->def->field_count, pTab->zName,
pSub->pEList->nExpr);
goto select_end;
}
diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h
index 8bb45c9..8e1c135 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 *zName; /* Name of this column */
enum field_type type; /* Column type. */
/** Collating sequence. */
struct coll *coll;
@@ -1950,7 +1949,6 @@ struct Table {
i16 iPKey; /* If not negative, use aCol[iPKey] as the rowid */
i16 iAutoIncPKey; /* If PK is marked INTEGER PRIMARY KEY AUTOINCREMENT, store
column number here, -1 otherwise Tarantool specifics */
- i16 nCol; /* Number of columns in this table */
LogEst nRowLogEst; /* Estimated rows in table - from _sql_stat1 table */
LogEst szTabRow; /* Estimated size of each table row in bytes */
#ifdef SQLITE_ENABLE_COSTMULT
@@ -3515,7 +3513,7 @@ void sqlite3ResetAllSchemasOfConnection(sqlite3 *);
void sqlite3CommitInternalChanges();
void sqlite3DeleteColumnNames(sqlite3 *, Table *);
bool table_column_is_in_pk(Table *, uint32_t);
-int sqlite3ColumnsFromExprList(Parse *, ExprList *, i16 *, Column **);
+int sqlite3ColumnsFromExprList(Parse *, ExprList *, Table *);
void sqlite3SelectAddColumnTypeAndCollation(Parse *, Table *, Select *);
Table *sqlite3ResultSetOfSelect(Parse *, Select *);
Index *sqlite3PrimaryKeyIndex(Table *);
diff --git a/src/box/sql/update.c b/src/box/sql/update.c
index f3bd0b7..464feee 100644
--- a/src/box/sql/update.c
+++ b/src/box/sql/update.c
@@ -75,8 +75,8 @@ sqlite3ColumnDefault(Vdbe * v, Table * pTab, int i, int iReg)
if (!pTab->pSelect) {
sqlite3_value *pValue = 0;
Column *pCol = &pTab->aCol[i];
- VdbeComment((v, "%s.%s", pTab->zName, pCol->zName));
- assert(i < pTab->nCol);
+ VdbeComment((v, "%s.%s", pTab->zName, pTab->def->fields[i].name));
+ assert(i < (int)pTab->def->field_count);
Expr *expr = NULL;
struct space *space =
@@ -212,14 +212,15 @@ sqlite3Update(Parse * pParse, /* The parser context */
*/
aXRef =
sqlite3DbMallocRawNN(db,
- sizeof(int) * (pTab->nCol + nIdx) + nIdx + 2);
+ sizeof(int) *
+ (pTab->def->field_count + nIdx) + nIdx + 2);
if (aXRef == 0)
goto update_cleanup;
- aRegIdx = aXRef + pTab->nCol;
+ aRegIdx = aXRef + pTab->def->field_count;
aToOpen = (u8 *) (aRegIdx + nIdx);
memset(aToOpen, 1, nIdx + 1);
aToOpen[nIdx + 1] = 0;
- for (i = 0; i < pTab->nCol; i++)
+ for (i = 0; i < (int)pTab->def->field_count; i++)
aXRef[i] = -1;
/* Initialize the name-context */
@@ -236,8 +237,8 @@ sqlite3Update(Parse * pParse, /* The parser context */
if (sqlite3ResolveExprNames(&sNC, pChanges->a[i].pExpr)) {
goto update_cleanup;
}
- for (j = 0; j < pTab->nCol; j++) {
- if (strcmp(pTab->aCol[j].zName,
+ for (j = 0; j < (int)pTab->def->field_count; j++) {
+ if (strcmp(pTab->def->fields[j].name,
pChanges->a[i].zName) == 0) {
if (pPk && table_column_is_in_pk(pTab, j)) {
chngPk = 1;
@@ -253,7 +254,7 @@ sqlite3Update(Parse * pParse, /* The parser context */
break;
}
}
- if (j >= pTab->nCol) {
+ if (j >= (int)pTab->def->field_count) {
sqlite3ErrorMsg(pParse, "no such column: %s",
pChanges->a[i].zName);
pParse->checkSchema = 1;
@@ -311,13 +312,13 @@ sqlite3Update(Parse * pParse, /* The parser context */
if (chngPk || pTrigger || hasFK) {
regOld = pParse->nMem + 1;
- pParse->nMem += pTab->nCol;
+ pParse->nMem += pTab->def->field_count;
}
if (chngPk || pTrigger || hasFK) {
regNewPk = ++pParse->nMem;
}
regNew = pParse->nMem + 1;
- pParse->nMem += pTab->nCol;
+ pParse->nMem += pTab->def->field_count;
/* If we are trying to update a view, realize that view into
* an ephemeral table.
@@ -326,7 +327,7 @@ sqlite3Update(Parse * pParse, /* The parser context */
if (isView) {
sqlite3MaterializeView(pParse, pTab, pWhere, iDataCur);
/* Number of columns from SELECT plus ID.*/
- nKey = pTab->nCol + 1;
+ nKey = pTab->def->field_count + 1;
}
#endif
@@ -478,7 +479,7 @@ sqlite3Update(Parse * pParse, /* The parser context */
pTrigger, pChanges, 0,
TRIGGER_BEFORE | TRIGGER_AFTER,
pTab, onError);
- for (i = 0; i < pTab->nCol; i++) {
+ for (i = 0; i < (int)pTab->def->field_count; i++) {
if (oldmask == 0xffffffff
|| (i < 32 && (oldmask & MASKBIT32(i)) != 0)
|| table_column_is_in_pk(pTab, i)) {
@@ -509,7 +510,7 @@ sqlite3Update(Parse * pParse, /* The parser context */
newmask =
sqlite3TriggerColmask(pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE,
pTab, onError);
- for (i = 0; i < pTab->nCol; i++) {
+ for (i = 0; i < (int)pTab->def->field_count; i++) {
if (i == pTab->iPKey) {
sqlite3VdbeAddOp2(v, OP_Null, 0, regNew + i);
} else {
@@ -565,7 +566,7 @@ sqlite3Update(Parse * pParse, /* The parser context */
* all columns not modified by the update statement into their
* registers in case this has happened.
*/
- for (i = 0; i < pTab->nCol; i++) {
+ for (i = 0; i < (int)pTab->def->field_count; i++) {
if (aXRef[i] < 0 && i != pTab->iPKey) {
sqlite3ExprCodeGetColumnOfTable(v, pTab,
iDataCur, i,
diff --git a/src/box/sql/where.c b/src/box/sql/where.c
index 7a7103c..fc0f84c 100644
--- a/src/box/sql/where.c
+++ b/src/box/sql/where.c
@@ -716,7 +716,7 @@ constructAutomaticIndex(Parse * pParse, /* The parsing context */
sqlite3_log(SQLITE_WARNING_AUTOINDEX,
"automatic index on %s(%s)",
pTable->zName,
- pTable->aCol[iCol].zName);
+ pTable->def->fields[iCol].name);
sentWarning = 1;
}
if ((idxCols & cMask) == 0) {
@@ -4514,9 +4514,9 @@ sqlite3WhereBegin(Parse * pParse, /* The parser context */
sqlite3OpenTable(pParse, pTabItem->iCursor, pTab, op);
assert(pTabItem->iCursor == pLevel->iTabCur);
testcase(pWInfo->eOnePass == ONEPASS_OFF
- && pTab->nCol == BMS - 1);
+ && pTab->def->field_count == BMS - 1);
testcase(pWInfo->eOnePass == ONEPASS_OFF
- && pTab->nCol == BMS);
+ && pTab->def->field_count == BMS);
#ifdef SQLITE_ENABLE_CURSOR_HINTS
if (pLoop->pIndex != 0) {
sqlite3VdbeChangeP5(v,
diff --git a/src/box/sql/wherecode.c b/src/box/sql/wherecode.c
index f1112f2..233fde0 100644
--- a/src/box/sql/wherecode.c
+++ b/src/box/sql/wherecode.c
@@ -50,7 +50,7 @@ explainIndexColumnName(Index * pIdx, int i)
i = pIdx->aiColumn[i];
if (i == XN_EXPR)
return "<expr>";
- return pIdx->pTable->aCol[i].zName;
+ return pIdx->pTable->def->fields[i].name;
}
/*
diff --git a/src/box/sql/whereexpr.c b/src/box/sql/whereexpr.c
index 86ee273..1b0d961 100644
--- a/src/box/sql/whereexpr.c
+++ b/src/box/sql/whereexpr.c
@@ -1502,10 +1502,10 @@ sqlite3WhereTabFuncArgs(Parse * pParse, /* Parsing context */
if (pArgs == 0)
return;
for (j = k = 0; j < pArgs->nExpr; j++) {
- while (k < pTab->nCol) {
+ while (k < (int)pTab->def->field_count) {
k++;
}
- if (k >= pTab->nCol) {
+ if (k >= (int)pTab->def->field_count) {
sqlite3ErrorMsg(pParse,
"too many arguments on %s() - max %d",
pTab->zName, j);
--
2.7.4
More information about the Tarantool-patches
mailing list