/ Changes On Branch cursor-hints-displayP4
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Changes In Branch cursor-hints-displayP4 Excluding Merge-Ins

This is equivalent to a diff from 1efa6ed5 to 12640cb2

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: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:07
Merge in all the trunk changes from the previous year. This breaks the cursor-hint mechanism, but provides a baseline for trouble-shooting. check-in: 82a7a61b user: drh tags: cursor-hints
2014-07-15
11:59
Add simple tests for new sqlite3BtreeCursorHint() functionality. check-in: 1efa6ed5 user: dan tags: cursor-hints
2014-07-14
19:04
In the expression passed to sqlite3BtreeCursorHint() for the inner loops of joins, replace any TK_COLUMN references to columns in the outer loops with TK_REGISTER expressions (Expr.iTable indicates the specific register containing the value). There are no automated tests for this yet. check-in: f9dddd00 user: dan tags: cursor-hints

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.

943
944
945
946
947
948
949











950
951
952




























































953
954
955
956
957
958
959
...
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
....
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
    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







>
>
>
>
>
>
>
>
>
>
>

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







 







|







 







|







943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961


962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
....
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
....
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
    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