Eliminate the need for the Column.zDflt (using Column.pDflt instead) to reduce
the amount of memory needed to hold the schema.
FossilOrigin-Name: d8c94a46dfa94930732c2de2aa79675c5087d36e
diff --git a/src/alter.c b/src/alter.c
index f10a850..9edd7ff 100644
--- a/src/alter.c
+++ b/src/alter.c
@@ -628,7 +628,8 @@
** literal NULL, then set pDflt to 0. This simplifies checking
** for an SQL NULL default below.
*/
- if( pDflt && pDflt->op==TK_NULL ){
+ assert( pDflt==0 || pDflt->op==TK_SPAN );
+ if( pDflt && pDflt->pLeft->op==TK_NULL ){
pDflt = 0;
}
@@ -787,7 +788,6 @@
pCol->zColl = 0;
pCol->zType = 0;
pCol->pDflt = 0;
- pCol->zDflt = 0;
}
pNew->pSchema = db->aDb[iDb].pSchema;
pNew->addColOffset = pTab->addColOffset;
diff --git a/src/build.c b/src/build.c
index b14d45f..bcf7144 100644
--- a/src/build.c
+++ b/src/build.c
@@ -571,7 +571,6 @@
for(i=0; i<pTable->nCol; i++, pCol++){
sqlite3DbFree(db, pCol->zName);
sqlite3ExprDelete(db, pCol->pDflt);
- sqlite3DbFree(db, pCol->zDflt);
sqlite3DbFree(db, pCol->zType);
sqlite3DbFree(db, pCol->zColl);
}
@@ -1231,11 +1230,16 @@
** tokens that point to volatile memory. The 'span' of the expression
** is required by pragma table_info.
*/
+ Expr x;
sqlite3ExprDelete(db, pCol->pDflt);
- pCol->pDflt = sqlite3ExprDup(db, pSpan->pExpr, EXPRDUP_REDUCE);
- sqlite3DbFree(db, pCol->zDflt);
- pCol->zDflt = sqlite3DbStrNDup(db, (char*)pSpan->zStart,
- (int)(pSpan->zEnd - pSpan->zStart));
+ 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;
+ pCol->pDflt = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE);
+ sqlite3DbFree(db, x.u.zToken);
}
}
sqlite3ExprDelete(db, pSpan->pExpr);
diff --git a/src/expr.c b/src/expr.c
index 3070de9..8a69732 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -3070,6 +3070,7 @@
sqlite3ReleaseTempReg(pParse, r4);
break;
}
+ case TK_SPAN:
case TK_COLLATE:
case TK_UPLUS: {
inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
diff --git a/src/insert.c b/src/insert.c
index 7ff884b..03fdf09 100644
--- a/src/insert.c
+++ b/src/insert.c
@@ -1999,11 +1999,15 @@
return 0; /* tab2 must be NOT NULL if tab1 is */
}
/* Default values for second and subsequent columns need to match. */
- if( i>0
- && ((pDestCol->zDflt==0)!=(pSrcCol->zDflt==0)
- || (pDestCol->zDflt && strcmp(pDestCol->zDflt, pSrcCol->zDflt)!=0))
- ){
- return 0; /* Default values must be the same for all columns */
+ if( i>0 ){
+ assert( pDestCol->pDflt==0 || pDestCol->pDflt->op==TK_SPAN );
+ assert( pSrcCol->pDflt==0 || pSrcCol->pDflt->op==TK_SPAN );
+ if( (pDestCol->pDflt==0)!=(pSrcCol->pDflt==0)
+ || (pDestCol->pDflt && strcmp(pDestCol->pDflt->u.zToken,
+ pSrcCol->pDflt->u.zToken)!=0)
+ ){
+ return 0; /* Default values must be the same for all columns */
+ }
}
}
for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
diff --git a/src/pragma.c b/src/pragma.c
index 8b8f1f7..0460f66 100644
--- a/src/pragma.c
+++ b/src/pragma.c
@@ -1076,12 +1076,13 @@
}else{
for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
}
+ assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN );
sqlite3VdbeMultiLoad(v, 1, "issisi",
i-nHidden,
pCol->zName,
pCol->zType ? pCol->zType : "",
pCol->notNull ? 1 : 0,
- pCol->zDflt,
+ pCol->pDflt ? pCol->pDflt->u.zToken : 0,
k);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
}
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 759d7ca..7d1757e 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -1545,7 +1545,6 @@
struct Column {
char *zName; /* Name of this column */
Expr *pDflt; /* Default value of this column */
- char *zDflt; /* Original text of the default value */
char *zType; /* Data type for this column */
char *zColl; /* Collating sequence. If NULL, use the default */
u8 notNull; /* An OE_ code for handling a NOT NULL constraint */
diff --git a/src/treeview.c b/src/treeview.c
index ff3b4be..907159c 100644
--- a/src/treeview.c
+++ b/src/treeview.c
@@ -339,6 +339,12 @@
case TK_ISNULL: zUniOp = "ISNULL"; break;
case TK_NOTNULL: zUniOp = "NOTNULL"; break;
+ case TK_SPAN: {
+ sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken);
+ sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
+ break;
+ }
+
case TK_COLLATE: {
sqlite3TreeViewLine(pView, "COLLATE %Q", pExpr->u.zToken);
sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
diff --git a/src/vdbemem.c b/src/vdbemem.c
index 87d233b..b5139fe 100644
--- a/src/vdbemem.c
+++ b/src/vdbemem.c
@@ -1285,7 +1285,7 @@
*ppVal = 0;
return SQLITE_OK;
}
- while( (op = pExpr->op)==TK_UPLUS ) pExpr = pExpr->pLeft;
+ while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
/* Compressed expressions only appear when parsing the DEFAULT clause