/ Check-in [20688471]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Convert the hint expression of the CursorHint opcode into a string for display by EXPLAIN.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | cursor-hints
Files: files | file ages | folders
SHA1: 206884718782331a7aaacc2c811e4e9d2effae91
User & Date: drh 2015-08-13 21:32:41
Context
2015-08-13
21:43
Convert the hint expression of the CursorHint opcode into a string for display by EXPLAIN. Leaf check-in: 12640cb2 user: drh tags: cursor-hints-displayP4
21:38
Fix a harmless compiler warning. check-in: 608ab4ac user: drh tags: cursor-hints
21:32
Convert the hint expression of the CursorHint opcode into a string for display by EXPLAIN. check-in: 20688471 user: drh tags: cursor-hints
20:34
Fix a bug in sqlite3ExprContainsSubquery(). check-in: be254715 user: drh tags: cursor-hints
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/vdbeInt.h.

22
23
24
25
26
27
28











29
30
31
32
33
34
35
** The maximum number of times that a statement will try to reparse
** itself before giving up and returning SQLITE_SCHEMA.
*/
#ifndef SQLITE_MAX_SCHEMA_RETRY
# define SQLITE_MAX_SCHEMA_RETRY 50
#endif












/*
** SQL is translated into a sequence of instructions to be
** executed by a virtual machine.  Each instruction is an instance
** of the following structure.
*/
typedef struct VdbeOp Op;








>
>
>
>
>
>
>
>
>
>
>







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
** The maximum number of times that a statement will try to reparse
** itself before giving up and returning SQLITE_SCHEMA.
*/
#ifndef SQLITE_MAX_SCHEMA_RETRY
# define SQLITE_MAX_SCHEMA_RETRY 50
#endif

/*
** VDBE_DISPLAY_P4 is true or false depending on whether or not the
** "explain" P4 display logic is enabled.
*/
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
     || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
# define VDBE_DISPLAY_P4 1
#else
# define VDBE_DISPLAY_P4 0
#endif

/*
** SQL is translated into a sequence of instructions to be
** executed by a virtual machine.  Each instruction is an instance
** of the following structure.
*/
typedef struct VdbeOp Op;

Changes to src/vdbeaux.c.

1080
1081
1082
1083
1084
1085
1086











1087
1088
1089




























































1090
1091
1092
1093
1094
1095
1096
....
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
....
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
    zTemp[0] = 0;
    jj = 0;
  }
  return jj;
}
#endif /* SQLITE_DEBUG */













#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
     || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)




























































/*
** Compute a string that describes the P4 parameter for an opcode.
** Use zTemp for any required temporary buffer space.
*/
static char *displayP4(Op *pOp, char *zTemp, int nTemp){
  char *zP4 = zTemp;
  assert( nTemp>=20 );
................................................................................
      zTemp[i++] = ')';
      zTemp[i] = 0;
      assert( i<nTemp );
      break;
    }
#ifdef SQLITE_ENABLE_CURSOR_HINTS
    case P4_EXPR: {
      sqlite3_snprintf(nTemp, zTemp, "(expr)");
      break;
    }
#endif
    case P4_COLLSEQ: {
      CollSeq *pColl = pOp->p4.pColl;
      sqlite3_snprintf(nTemp, zTemp, "(%.20s)", pColl->zName);
      break;
................................................................................
        zTemp[0] = 0;
      }
    }
  }
  assert( zP4!=0 );
  return zP4;
}
#endif

/*
** Declare to the Vdbe that the BTree object at db->aDb[i] is used.
**
** The prepared statements need to know in advance the complete set of
** attached databases that will be use.  A mask of these databases
** is maintained in p->btreeMask.  The p->lockMask value is the subset of







>
>
>
>
>
>
>
>
>
>
>

<
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







 







|







1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098


1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
....
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
....
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
    zTemp[0] = 0;
    jj = 0;
  }
  return jj;
}
#endif /* SQLITE_DEBUG */

#if VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS)
/*
** Translate the P4.pExpr value for an OP_CursorHint opcode into text
** that can be displayed in the P4 column of EXPLAIN output.
*/
static int displayP4Expr(int nTemp, char *zTemp, Expr *pExpr){
  const char *zBinOp = 0;
  switch( pExpr->op ){
    case TK_STRING:
      sqlite3_snprintf(nTemp, zTemp, "%Q", pExpr->u.zToken);
      break;



    case TK_INTEGER:
      sqlite3_snprintf(nTemp, zTemp, "%d", pExpr->u.iValue);
      break;

    case TK_NULL:
      sqlite3_snprintf(nTemp, zTemp, "NULL");
      break;

    case TK_REGISTER: {
      sqlite3_snprintf(nTemp, zTemp, "r[%d]", pExpr->iTable);
      break;
    }

    case TK_COLUMN: {
      sqlite3_snprintf(nTemp, zTemp, "c%d", (int)pExpr->iColumn);
      break;
    }

    case TK_LT:      zBinOp = "<";        break;
    case TK_LE:      zBinOp = "<=";       break;
    case TK_GT:      zBinOp = ">";        break;
    case TK_GE:      zBinOp = ">=";       break;
    case TK_NE:      zBinOp = "!=";       break;
    case TK_EQ:      zBinOp = "==";       break;
    case TK_IS:      zBinOp = " IS ";     break;
    case TK_ISNOT:   zBinOp = " IS NOT "; break;
    case TK_AND:     zBinOp = " AND ";    break;
    case TK_OR:      zBinOp = " OR ";     break;
    case TK_PLUS:    zBinOp = "+";        break;
    case TK_STAR:    zBinOp = "*";        break;
    case TK_MINUS:   zBinOp = "-";        break;
    case TK_REM:     zBinOp = "%";        break;
    case TK_BITAND:  zBinOp = "&";        break;
    case TK_BITOR:   zBinOp = "|";        break;
    case TK_SLASH:   zBinOp = "/";        break;
    case TK_LSHIFT:  zBinOp = "<<";       break;
    case TK_RSHIFT:  zBinOp = ">>";       break;
    case TK_CONCAT:  zBinOp = "||";       break;

    default:
      sqlite3_snprintf(nTemp, zTemp, "%s", "expr");
      break;
  }

  if( zBinOp && nTemp>5 ){
    int n = 1;
    zTemp[0] = '(';
    n += displayP4Expr(nTemp-n, zTemp+n, pExpr->pLeft);
    sqlite3_snprintf(nTemp-n, zTemp+n, "%s", zBinOp);
    n += sqlite3Strlen30(zTemp+n);
    n += displayP4Expr(nTemp-n, zTemp+n, pExpr->pRight);
    sqlite3_snprintf(nTemp-n, zTemp+n, ")");
  }

  return sqlite3Strlen30(zTemp);
}
#endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */


#if VDBE_DISPLAY_P4
/*
** Compute a string that describes the P4 parameter for an opcode.
** Use zTemp for any required temporary buffer space.
*/
static char *displayP4(Op *pOp, char *zTemp, int nTemp){
  char *zP4 = zTemp;
  assert( nTemp>=20 );
................................................................................
      zTemp[i++] = ')';
      zTemp[i] = 0;
      assert( i<nTemp );
      break;
    }
#ifdef SQLITE_ENABLE_CURSOR_HINTS
    case P4_EXPR: {
      displayP4Expr(nTemp, zTemp, pOp->p4.pExpr);
      break;
    }
#endif
    case P4_COLLSEQ: {
      CollSeq *pColl = pOp->p4.pColl;
      sqlite3_snprintf(nTemp, zTemp, "(%.20s)", pColl->zName);
      break;
................................................................................
        zTemp[0] = 0;
      }
    }
  }
  assert( zP4!=0 );
  return zP4;
}
#endif /* VDBE_DISPLAY_P4 */

/*
** Declare to the Vdbe that the BTree object at db->aDb[i] is used.
**
** The prepared statements need to know in advance the complete set of
** attached databases that will be use.  A mask of these databases
** is maintained in p->btreeMask.  The p->lockMask value is the subset of