aboutsummaryrefslogtreecommitdiff
path: root/src/expr.c
diff options
context:
space:
mode:
authordrh <>2022-12-14 17:46:35 +0000
committerdrh <>2022-12-14 17:46:35 +0000
commitdaa46142ecf8dd3b886fb5940e1faf4366a36df3 (patch)
tree08e3b0f18a367bb7f8478926ffe06704716d4429 /src/expr.c
parente5e61d40e977cf6a620e4b1d2f35d3649c3fada6 (diff)
parented07d0ea765386c5bdf52891154c70f048046e60 (diff)
downloadsqlite-daa46142ecf8dd3b886fb5940e1faf4366a36df3.tar.gz
sqlite-daa46142ecf8dd3b886fb5940e1faf4366a36df3.zip
Rework the code that computes the datatypes and affinities for subqueries
and views. If the subquery/view is constructed from a compound SELECT where the affinity varies across arms of the compound, set the affinity for the corresponding column in the constructed view to be BLOB so that it is allowed to take on any data type. FossilOrigin-Name: 27655c9353620aa58105e87d1e171d1f0a637deedde41c081824078385cd49ac
Diffstat (limited to 'src/expr.c')
-rw-r--r--src/expr.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/expr.c b/src/expr.c
index 3d96868b6..5608128ad 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -90,6 +90,72 @@ char sqlite3ExprAffinity(const Expr *pExpr){
}
/*
+** Make a guess at all the possible datatypes of the result that could
+** be returned by an expression. Return a bitmask indicating the answer:
+**
+** 0x01 Numeric
+** 0x02 Text
+** 0x04 Blob
+**
+** If the expression must return NULL, then 0x00 is returned.
+*/
+int sqlite3ExprDataType(const Expr *pExpr){
+ while( pExpr ){
+ switch( pExpr->op ){
+ case TK_COLLATE:
+ case TK_IF_NULL_ROW:
+ case TK_UPLUS: {
+ pExpr = pExpr->pLeft;
+ break;
+ }
+ case TK_NULL: {
+ return 0x00;
+ }
+ case TK_STRING: {
+ return 0x02;
+ }
+ case TK_BLOB: {
+ return 0x04;
+ }
+ case TK_CONCAT: {
+ return 0x06;
+ }
+ case TK_VARIABLE:
+ case TK_AGG_FUNCTION:
+ case TK_FUNCTION: {
+ return 0x07;
+ }
+ case TK_COLUMN:
+ case TK_AGG_COLUMN:
+ case TK_SELECT:
+ case TK_CAST:
+ case TK_SELECT_COLUMN:
+ case TK_VECTOR: {
+ int aff = sqlite3ExprAffinity(pExpr);
+ if( aff>=SQLITE_AFF_NUMERIC ) return 0x05;
+ if( aff==SQLITE_AFF_TEXT ) return 0x06;
+ return 0x07;
+ }
+ case TK_CASE: {
+ int res = 0;
+ int ii;
+ ExprList *pList = pExpr->x.pList;
+ assert( ExprUseXList(pExpr) && pList!=0 );
+ assert( pList->nExpr > 0);
+ for(ii=1; ii<pList->nExpr; ii+=2){
+ res |= sqlite3ExprDataType(pList->a[ii].pExpr);
+ }
+ return res;
+ }
+ default: {
+ return 0x01;
+ }
+ } /* End of switch(op) */
+ } /* End of while(pExpr) */
+ return 0;
+}
+
+/*
** Set the collating sequence for expression pExpr to be the collating
** sequence named by pToken. Return a pointer to a new Expr node that
** implements the COLLATE operator.