System.Data.SQLite
Check-in [496499d755]
Not logged in

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

Overview
Comment:More fixes to the optional field handling for the virtual table interface.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | vtabFixes
Files: files | file ages | folders
SHA1: 496499d755a259c04c579f68927f43223e27cbe2
User & Date: mistachkin 2015-12-04 06:14:25
Context
2015-12-04
06:16
Reverse accidental check-in of changes performed on the project file by the IDE. check-in: fe4d272115 user: mistachkin tags: vtabFixes
06:14
More fixes to the optional field handling for the virtual table interface. check-in: 496499d755 user: mistachkin tags: vtabFixes
02:04
Add missing checks for NET_452 and NET_461 compile-time defines. check-in: d5792024ef user: mistachkin tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to SQLite.Designer/SQLite.Designer.2015.csproj.

   110    110       <Compile Include="Design\Index.cs" />
   111    111       <Compile Include="Design\PrimaryKey.cs" />
   112    112       <Compile Include="Design\SimpleTokenizer.cs" />
   113    113       <Compile Include="Design\Table.cs" />
   114    114       <Compile Include="Design\Trigger.cs" />
   115    115       <Compile Include="Design\Unique.cs" />
   116    116       <Compile Include="Design\View.cs" />
   117         -    <Compile Include="Editors\AutoCompleteColumn.cs">
   118         -      <SubType>Component</SubType>
   119         -    </Compile>
          117  +    <Compile Include="Editors\AutoCompleteColumn.cs" />
   120    118       <Compile Include="Editors\TableDesignerDoc.cs">
   121    119         <SubType>UserControl</SubType>
   122    120       </Compile>
   123    121       <Compile Include="Editors\TableDesignerDoc.Designer.cs">
   124    122         <DependentUpon>TableDesignerDoc.cs</DependentUpon>
   125    123       </Compile>
   126    124       <Compile Include="Editors\ViewDesignerDoc.cs">
................................................................................
   204    202     <ItemGroup>
   205    203       <None Include="Resources\info.png" />
   206    204       <None Include="Resources\ToolboxItems.txt" />
   207    205       <None Include="source.extension.vsixmanifest" />
   208    206     </ItemGroup>
   209    207     <Import Project="$(SQLiteNetDir)\System.Data.SQLite\Targets\System.Data.SQLite.Properties.targets" />
   210    208     <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   211         -  <PropertyGroup Condition="'$(VSSDK140Install)' == '' Or
   212         -                            !Exists('$(VSSDK140Install)VisualStudioIntegration\Common\Assemblies\v4.0\Microsoft.Data.ConnectionUI.dll') Or
   213         -                            !Exists('$(VSSDK140Install)VisualStudioIntegration\Common\Assemblies\v4.0\Microsoft.VisualStudio.Data.dll') Or
   214         -                            !Exists('$(VSSDK140Install)VisualStudioIntegration\Common\Assemblies\v4.0\Microsoft.VisualStudio.Data.Services.dll') Or
   215         -                            !Exists('$(VSSDK140Install)VisualStudioIntegration\Common\Assemblies\v2.0\Microsoft.VisualStudio.OLE.Interop.dll') Or
   216         -                            !Exists('$(VSSDK140Install)VisualStudioIntegration\Common\Assemblies\v4.0\Microsoft.VisualStudio.Shell.14.0.dll') Or
   217         -                            !Exists('$(VSSDK140Install)VisualStudioIntegration\Common\Assemblies\v2.0\Microsoft.VisualStudio.Shell.Interop.dll') Or
   218         -                            !Exists('$(VSSDK140Install)VisualStudioIntegration\Common\Assemblies\v2.0\Microsoft.VisualStudio.Shell.Interop.8.0.dll') Or
   219         -                            !Exists('$(VSSDK140Install)VisualStudioIntegration\Common\Assemblies\v2.0\Microsoft.VisualStudio.Shell.Interop.9.0.dll') Or
   220         -                            !Exists('$(VSSDK140Install)VisualStudioIntegration\Common\Assemblies\v2.0\Microsoft.VisualStudio.Shell.Interop.10.0.dll')">
          209  +  <PropertyGroup Condition="'$(VSSDK140Install)' == '' Or&#xD;&#xA;                            !Exists('$(VSSDK140Install)VisualStudioIntegration\Common\Assemblies\v4.0\Microsoft.Data.ConnectionUI.dll') Or&#xD;&#xA;                            !Exists('$(VSSDK140Install)VisualStudioIntegration\Common\Assemblies\v4.0\Microsoft.VisualStudio.Data.dll') Or&#xD;&#xA;                            !Exists('$(VSSDK140Install)VisualStudioIntegration\Common\Assemblies\v4.0\Microsoft.VisualStudio.Data.Services.dll') Or&#xD;&#xA;                            !Exists('$(VSSDK140Install)VisualStudioIntegration\Common\Assemblies\v2.0\Microsoft.VisualStudio.OLE.Interop.dll') Or&#xD;&#xA;                            !Exists('$(VSSDK140Install)VisualStudioIntegration\Common\Assemblies\v4.0\Microsoft.VisualStudio.Shell.14.0.dll') Or&#xD;&#xA;                            !Exists('$(VSSDK140Install)VisualStudioIntegration\Common\Assemblies\v2.0\Microsoft.VisualStudio.Shell.Interop.dll') Or&#xD;&#xA;                            !Exists('$(VSSDK140Install)VisualStudioIntegration\Common\Assemblies\v2.0\Microsoft.VisualStudio.Shell.Interop.8.0.dll') Or&#xD;&#xA;                            !Exists('$(VSSDK140Install)VisualStudioIntegration\Common\Assemblies\v2.0\Microsoft.VisualStudio.Shell.Interop.9.0.dll') Or&#xD;&#xA;                            !Exists('$(VSSDK140Install)VisualStudioIntegration\Common\Assemblies\v2.0\Microsoft.VisualStudio.Shell.Interop.10.0.dll')">
   221    210       <!--
   222    211           NOTE: We cannot build this project without the necessary reference
   223    212                 assemblies; therefore, skip building it altogether.
   224    213       -->
   225    214       <BuildDependsOn>
   226    215         MissingVsSdk
   227    216       </BuildDependsOn>

Changes to System.Data.SQLite/SQLiteModule.cs.

  1041   1041           ///////////////////////////////////////////////////////////////////////
  1042   1042   
  1043   1043           /// <summary>
  1044   1044           /// Determines if the native flags field can be used, based on the
  1045   1045           /// available version of the SQLite core library.
  1046   1046           /// </summary>
  1047   1047           /// <returns>
  1048         -        /// Non-zero if the <see cref="IdxFlags" /> property is supported by
         1048  +        /// Non-zero if the <see cref="IndexFlags" /> property is supported by
  1049   1049           /// the SQLite core library.
  1050   1050           /// </returns>
  1051         -        public bool CanUseIdxFlags()
         1051  +        public bool CanUseIndexFlags()
  1052   1052           {
  1053   1053               if (UnsafeNativeMethods.sqlite3_libversion_number() >= 3009000)
  1054   1054                   return true;
  1055   1055   
  1056   1056               return false;
  1057   1057           }
  1058   1058   
................................................................................
  1059   1059           ///////////////////////////////////////////////////////////////////////
  1060   1060   
  1061   1061           /// <summary>
  1062   1062           /// Determines if the native flags field can be used, based on the
  1063   1063           /// available version of the SQLite core library.
  1064   1064           /// </summary>
  1065   1065           /// <returns>
  1066         -        /// Non-zero if the <see cref="ColUsed" /> property is supported by
         1066  +        /// Non-zero if the <see cref="ColumnsUsed" /> property is supported by
  1067   1067           /// the SQLite core library.
  1068   1068           /// </returns>
  1069         -        public bool CanUseColUsed()
         1069  +        public bool CanUseColumnsUsed()
  1070   1070           {
  1071   1071               if (UnsafeNativeMethods.sqlite3_libversion_number() >= 3010000)
  1072   1072                   return true;
  1073   1073   
  1074   1074               return false;
  1075   1075           }
  1076   1076   
................................................................................
  1167   1167           {
  1168   1168               get { return estimatedRows; }
  1169   1169               set { estimatedRows = value; }
  1170   1170           }
  1171   1171   
  1172   1172           ///////////////////////////////////////////////////////////////////////
  1173   1173   
  1174         -        private SQLiteIndexFlags? idxFlags;
         1174  +        private SQLiteIndexFlags? indexFlags;
  1175   1175           /// <summary>
  1176   1176           /// The flags that should be used with this index.  Using a null value
  1177   1177           /// here indicates that a default flags value should be used.  This
  1178   1178           /// property has no effect if the SQLite core library is not at least
  1179   1179           /// version 3.9.0.
  1180   1180           /// </summary>
  1181         -        public SQLiteIndexFlags? IdxFlags
  1182         -        {
  1183         -            get { return idxFlags; }
  1184         -            set { idxFlags = value; }
  1185         -        }
  1186         -
  1187         -        ///////////////////////////////////////////////////////////////////////
  1188         -
  1189         -        private long? colUsed;
  1190         -        /// <summary>
  1191         -        /// The colUsed field indicates which columns of the virtual table
  1192         -        /// may be required by the current scan.  Virtual table columns are
  1193         -        /// numbered from zero in the order in which they appear within the
  1194         -        /// CREATE TABLE statement passed to sqlite3_declare_vtab().  For the
  1195         -        /// first 63 columns (columns 0-62), the corresponding bit is set
  1196         -        /// within the colUsed mask if the column may be required by SQLite.
  1197         -        /// If the table has at least 64 columns and any column to the right
  1198         -        /// of the first 63 is required, then bit 63 of colUsed is also set.
  1199         -        /// In other words, column iCol may be required if the expression
  1200         -        /// (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol)))
         1181  +        public SQLiteIndexFlags? IndexFlags
         1182  +        {
         1183  +            get { return indexFlags; }
         1184  +            set { indexFlags = value; }
         1185  +        }
         1186  +
         1187  +        ///////////////////////////////////////////////////////////////////////
         1188  +
         1189  +        private long? columnsUsed;
         1190  +        /// <summary>
         1191  +        /// <para>
         1192  +        /// Indicates which columns of the virtual table may be required by the
         1193  +        /// current scan.  Virtual table columns are numbered from zero in the
         1194  +        /// order in which they appear within the CREATE TABLE statement passed
         1195  +        /// to sqlite3_declare_vtab().  For the first 63 columns (columns 0-62),
         1196  +        /// the corresponding bit is set within the bit mask if the column may
         1197  +        /// be required by SQLite.  If the table has at least 64 columns and
         1198  +        /// any column to the right of the first 63 is required, then bit 63 of
         1199  +        /// colUsed is also set.  In other words, column iCol may be required
         1200  +        /// if the expression
         1201  +        /// </para>
         1202  +        /// <para><code>
         1203  +        /// (colUsed &amp; ((sqlite3_uint64)1 &lt;&lt; (iCol&gt;=63 ? 63 : iCol)))
         1204  +        /// </code></para>
         1205  +        /// <para>
  1201   1206           /// evaluates to non-zero.  Using a null value here indicates that a
  1202         -        /// default flags value should be used.  This property has no effect
  1203         -        /// if the SQLite core library is not at least version 3.10.0.
         1207  +        /// default flags value should be used.  This property has no effect if
         1208  +        /// the SQLite core library is not at least version 3.10.0.
         1209  +        /// </para>
  1204   1210           /// </summary>
  1205         -        public long? ColUsed
         1211  +        public long? ColumnsUsed
  1206   1212           {
  1207         -            get { return colUsed; }
  1208         -            set { colUsed = value; }
         1213  +            get { return columnsUsed; }
         1214  +            set { columnsUsed = value; }
  1209   1215           }
  1210   1216           #endregion
  1211   1217       }
  1212   1218       #endregion
  1213   1219   
  1214   1220       ///////////////////////////////////////////////////////////////////////////
  1215   1221   
................................................................................
  1242   1248               outputs = new SQLiteIndexOutputs(nConstraint);
  1243   1249           }
  1244   1250           #endregion
  1245   1251   
  1246   1252           ///////////////////////////////////////////////////////////////////////
  1247   1253   
  1248   1254           #region Internal Marshal Helper Methods
         1255  +        /// <summary>
         1256  +        /// Attempts to determine the structure sizes needed to create and
         1257  +        /// populate a native
         1258  +        /// <see cref="UnsafeNativeMethods.sqlite3_index_info" />
         1259  +        /// structure.
         1260  +        /// </summary>
         1261  +        /// <param name="sizeOfInfoType">
         1262  +        /// The size of the native
         1263  +        /// <see cref="UnsafeNativeMethods.sqlite3_index_info" />
         1264  +        /// structure is stored here.
         1265  +        /// </param>
         1266  +        /// <param name="sizeOfConstraintType">
         1267  +        /// The size of the native
         1268  +        /// <see cref="UnsafeNativeMethods.sqlite3_index_constraint" />
         1269  +        /// structure is stored here.
         1270  +        /// </param>
         1271  +        /// <param name="sizeOfOrderByType">
         1272  +        /// The size of the native
         1273  +        /// <see cref="UnsafeNativeMethods.sqlite3_index_orderby" />
         1274  +        /// structure is stored here.
         1275  +        /// </param>
         1276  +        /// <param name="sizeOfConstraintUsageType">
         1277  +        /// The size of the native
         1278  +        /// <see cref="UnsafeNativeMethods.sqlite3_index_constraint_usage" />
         1279  +        /// structure is stored here.
         1280  +        /// </param>
         1281  +        private static void SizeOf( /* NOTE: For test use only. */
         1282  +            out int sizeOfInfoType,
         1283  +            out int sizeOfConstraintType,
         1284  +            out int sizeOfOrderByType,
         1285  +            out int sizeOfConstraintUsageType
         1286  +            )
         1287  +        {
         1288  +            sizeOfInfoType = Marshal.SizeOf(typeof(
         1289  +                UnsafeNativeMethods.sqlite3_index_info));
         1290  +
         1291  +            sizeOfConstraintType = Marshal.SizeOf(typeof(
         1292  +                UnsafeNativeMethods.sqlite3_index_constraint));
         1293  +
         1294  +            sizeOfOrderByType = Marshal.SizeOf(typeof(
         1295  +                UnsafeNativeMethods.sqlite3_index_orderby));
         1296  +
         1297  +            sizeOfConstraintUsageType = Marshal.SizeOf(typeof(
         1298  +                UnsafeNativeMethods.sqlite3_index_constraint_usage));
         1299  +        }
         1300  +
         1301  +        ///////////////////////////////////////////////////////////////////////
         1302  +
         1303  +        /// <summary>
         1304  +        /// Attempts to allocate and initialize a native
         1305  +        /// <see cref="UnsafeNativeMethods.sqlite3_index_info" />
         1306  +        /// structure.
         1307  +        /// </summary>
         1308  +        /// <param name="nConstraint">
         1309  +        /// The number of <see cref="SQLiteIndexConstraint" /> instances to
         1310  +        /// pre-allocate space for.
         1311  +        /// </param>
         1312  +        /// <param name="nOrderBy">
         1313  +        /// The number of <see cref="SQLiteIndexOrderBy" /> instances to
         1314  +        /// pre-allocate space for.
         1315  +        /// </param>
         1316  +        /// <returns>
         1317  +        /// The newly allocated native
         1318  +        /// <see cref="UnsafeNativeMethods.sqlite3_index_info" /> structure
         1319  +        /// -OR- <see cref="IntPtr.Zero" /> if it could not be fully allocated.
         1320  +        /// </returns>
         1321  +        internal static IntPtr AllocMemoryBlock( /* NOTE: For test use only. */
         1322  +            int nConstraint,
         1323  +            int nOrderBy
         1324  +            )
         1325  +        {
         1326  +            IntPtr pIndex = IntPtr.Zero;
         1327  +            IntPtr pInfo = IntPtr.Zero;
         1328  +            IntPtr pConstraint = IntPtr.Zero;
         1329  +            IntPtr pOrderBy = IntPtr.Zero;
         1330  +            IntPtr pConstraintUsage = IntPtr.Zero;
         1331  +
         1332  +            try
         1333  +            {
         1334  +                int sizeOfInfoType;
         1335  +                int sizeOfOrderByType;
         1336  +                int sizeOfConstraintType;
         1337  +                int sizeOfConstraintUsageType;
         1338  +
         1339  +                SizeOf(out sizeOfInfoType, out sizeOfConstraintType,
         1340  +                    out sizeOfOrderByType, out sizeOfConstraintUsageType);
         1341  +
         1342  +                if ((sizeOfInfoType > 0) &&
         1343  +                    (sizeOfConstraintType > 0) &&
         1344  +                    (sizeOfOrderByType > 0) &&
         1345  +                    (sizeOfConstraintUsageType > 0))
         1346  +                {
         1347  +                    pInfo = SQLiteMemory.Allocate(sizeOfInfoType);
         1348  +
         1349  +                    pConstraint = SQLiteMemory.Allocate(
         1350  +                        sizeOfConstraintType * nConstraint);
         1351  +
         1352  +                    pOrderBy = SQLiteMemory.Allocate(
         1353  +                        sizeOfOrderByType * nOrderBy);
         1354  +
         1355  +                    pConstraintUsage = SQLiteMemory.Allocate(
         1356  +                        sizeOfConstraintUsageType * nConstraint);
         1357  +
         1358  +                    if ((pInfo != IntPtr.Zero) &&
         1359  +                        (pConstraint != IntPtr.Zero) &&
         1360  +                        (pOrderBy != IntPtr.Zero) &&
         1361  +                        (pConstraintUsage != IntPtr.Zero))
         1362  +                    {
         1363  +                        int offset = 0;
         1364  +
         1365  +                        Marshal.WriteInt32(
         1366  +                            pInfo, offset, nConstraint);
         1367  +
         1368  +                        offset = SQLiteMarshal.NextOffsetOf(
         1369  +                            offset, sizeof(int), IntPtr.Size);
         1370  +
         1371  +                        Marshal.WriteIntPtr(
         1372  +                            pInfo, offset, pConstraint);
         1373  +
         1374  +                        offset = SQLiteMarshal.NextOffsetOf(
         1375  +                            offset, IntPtr.Size, sizeof(int));
         1376  +
         1377  +                        Marshal.WriteInt32(
         1378  +                            pInfo, offset, nOrderBy);
         1379  +
         1380  +                        offset = SQLiteMarshal.NextOffsetOf(
         1381  +                            offset, sizeof(int), IntPtr.Size);
         1382  +
         1383  +                        Marshal.WriteIntPtr(
         1384  +                            pInfo, offset, pOrderBy);
         1385  +
         1386  +                        offset = SQLiteMarshal.NextOffsetOf(
         1387  +                            offset, IntPtr.Size, IntPtr.Size);
         1388  +
         1389  +                        Marshal.WriteIntPtr(
         1390  +                            pInfo, offset, pConstraintUsage);
         1391  +
         1392  +                        pIndex = pInfo; /* NOTE: Success. */
         1393  +                    }
         1394  +                }
         1395  +            }
         1396  +            finally
         1397  +            {
         1398  +                if (pIndex == IntPtr.Zero) /* NOTE: Failure? */
         1399  +                {
         1400  +                    if (pConstraintUsage != IntPtr.Zero)
         1401  +                    {
         1402  +                        SQLiteMemory.Free(pConstraintUsage);
         1403  +                        pConstraintUsage = IntPtr.Zero;
         1404  +                    }
         1405  +
         1406  +                    if (pOrderBy != IntPtr.Zero)
         1407  +                    {
         1408  +                        SQLiteMemory.Free(pOrderBy);
         1409  +                        pOrderBy = IntPtr.Zero;
         1410  +                    }
         1411  +
         1412  +                    if (pConstraint != IntPtr.Zero)
         1413  +                    {
         1414  +                        SQLiteMemory.Free(pConstraint);
         1415  +                        pConstraint = IntPtr.Zero;
         1416  +                    }
         1417  +
         1418  +                    if (pInfo != IntPtr.Zero)
         1419  +                    {
         1420  +                        SQLiteMemory.Free(pInfo);
         1421  +                        pInfo = IntPtr.Zero;
         1422  +                    }
         1423  +                }
         1424  +            }
         1425  +
         1426  +            return pIndex;
         1427  +        }
         1428  +
         1429  +        ///////////////////////////////////////////////////////////////////////
         1430  +
         1431  +        /// <summary>
         1432  +        /// Frees all the memory associated with a native
         1433  +        /// <see cref="UnsafeNativeMethods.sqlite3_index_info" />
         1434  +        /// structure.
         1435  +        /// </summary>
         1436  +        /// <param name="pIndex">
         1437  +        /// The native pointer to the native sqlite3_index_info structure to
         1438  +        /// free.
         1439  +        /// </param>
         1440  +        internal static void FreeMemoryBlock( /* NOTE: For test use only. */
         1441  +            IntPtr pIndex
         1442  +            )
         1443  +        {
         1444  +            if (pIndex == IntPtr.Zero)
         1445  +                return;
         1446  +
         1447  +            int offset = 0;
         1448  +
         1449  +            offset = SQLiteMarshal.NextOffsetOf(
         1450  +                offset, sizeof(int), IntPtr.Size);
         1451  +
         1452  +            IntPtr pConstraint = SQLiteMarshal.ReadIntPtr(
         1453  +                pIndex, offset);
         1454  +
         1455  +            offset = SQLiteMarshal.NextOffsetOf(
         1456  +                offset, IntPtr.Size, sizeof(int));
         1457  +
         1458  +            offset = SQLiteMarshal.NextOffsetOf(
         1459  +                offset, sizeof(int), IntPtr.Size);
         1460  +
         1461  +            IntPtr pOrderBy = SQLiteMarshal.ReadIntPtr(pIndex, offset);
         1462  +
         1463  +            offset = SQLiteMarshal.NextOffsetOf(
         1464  +                offset, IntPtr.Size, IntPtr.Size);
         1465  +
         1466  +            IntPtr pConstraintUsage = SQLiteMarshal.ReadIntPtr(
         1467  +                pIndex, offset);
         1468  +
         1469  +            if (pConstraintUsage != IntPtr.Zero)
         1470  +            {
         1471  +                SQLiteMemory.Free(pConstraintUsage);
         1472  +                pConstraintUsage = IntPtr.Zero;
         1473  +            }
         1474  +
         1475  +            if (pOrderBy != IntPtr.Zero)
         1476  +            {
         1477  +                SQLiteMemory.Free(pOrderBy);
         1478  +                pOrderBy = IntPtr.Zero;
         1479  +            }
         1480  +
         1481  +            if (pConstraint != IntPtr.Zero)
         1482  +            {
         1483  +                SQLiteMemory.Free(pConstraint);
         1484  +                pConstraint = IntPtr.Zero;
         1485  +            }
         1486  +
         1487  +            if (pIndex != IntPtr.Zero)
         1488  +            {
         1489  +                SQLiteMemory.Free(pIndex);
         1490  +                pIndex = IntPtr.Zero;
         1491  +            }
         1492  +        }
         1493  +
         1494  +        ///////////////////////////////////////////////////////////////////////
         1495  +
  1249   1496           /// <summary>
  1250   1497           /// Converts a native pointer to a native sqlite3_index_info structure
  1251   1498           /// into a new <see cref="SQLiteIndex" /> object instance.
  1252   1499           /// </summary>
  1253   1500           /// <param name="pIndex">
  1254   1501           /// The native pointer to the native sqlite3_index_info structure to
  1255   1502           /// convert.
  1256   1503           /// </param>
         1504  +        /// <param name="includeOutput">
         1505  +        /// Non-zero to include fields from the outputs portion of the native
         1506  +        /// structure; otherwise, the "output" fields will not be read.
         1507  +        /// </param>
  1257   1508           /// <param name="index">
  1258   1509           /// Upon success, this parameter will be modified to contain the newly
  1259   1510           /// created <see cref="SQLiteIndex" /> object instance.
  1260   1511           /// </param>
  1261   1512           internal static void FromIntPtr(
  1262   1513               IntPtr pIndex,
         1514  +            bool includeOutput,
  1263   1515               ref SQLiteIndex index
  1264   1516               )
  1265   1517           {
  1266   1518               if (pIndex == IntPtr.Zero)
  1267   1519                   return;
  1268   1520   
  1269   1521               int offset = 0;
  1270   1522   
  1271         -            int nConstraint = SQLiteMarshal.ReadInt32(pIndex, offset);
  1272         -
  1273         -            offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(int),
  1274         -                IntPtr.Size);
  1275         -
  1276         -            IntPtr pConstraint = SQLiteMarshal.ReadIntPtr(pIndex, offset);
  1277         -
  1278         -            offset = SQLiteMarshal.NextOffsetOf(offset, IntPtr.Size,
  1279         -                sizeof(int));
  1280         -
  1281         -            int nOrderBy = SQLiteMarshal.ReadInt32(pIndex, offset);
  1282         -
  1283         -            offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(int),
  1284         -                IntPtr.Size);
  1285         -
  1286         -            IntPtr pOrderBy = SQLiteMarshal.ReadIntPtr(pIndex, offset);
         1523  +            int nConstraint = SQLiteMarshal.ReadInt32(
         1524  +                pIndex, offset);
         1525  +
         1526  +            offset = SQLiteMarshal.NextOffsetOf(
         1527  +                offset, sizeof(int), IntPtr.Size);
         1528  +
         1529  +            IntPtr pConstraint = SQLiteMarshal.ReadIntPtr(
         1530  +                pIndex, offset);
         1531  +
         1532  +            offset = SQLiteMarshal.NextOffsetOf(
         1533  +                offset, IntPtr.Size, sizeof(int));
         1534  +
         1535  +            int nOrderBy = SQLiteMarshal.ReadInt32(
         1536  +                pIndex, offset);
         1537  +
         1538  +            offset = SQLiteMarshal.NextOffsetOf(
         1539  +                offset, sizeof(int), IntPtr.Size);
         1540  +
         1541  +            IntPtr pOrderBy = SQLiteMarshal.ReadIntPtr(
         1542  +                pIndex, offset);
         1543  +
         1544  +            IntPtr pConstraintUsage = IntPtr.Zero;
         1545  +
         1546  +            if (includeOutput)
         1547  +            {
         1548  +                offset = SQLiteMarshal.NextOffsetOf(
         1549  +                    offset, IntPtr.Size, IntPtr.Size);
         1550  +
         1551  +                pConstraintUsage = SQLiteMarshal.ReadIntPtr(
         1552  +                    pIndex, offset);
         1553  +            }
  1287   1554   
  1288   1555               index = new SQLiteIndex(nConstraint, nOrderBy);
         1556  +            SQLiteIndexInputs inputs = index.Inputs;
  1289   1557   
  1290         -            Type indexConstraintType = typeof(
         1558  +            if (inputs == null)
         1559  +                return;
         1560  +
         1561  +            SQLiteIndexConstraint[] constraints = inputs.Constraints;
         1562  +
         1563  +            if (constraints == null)
         1564  +                return;
         1565  +
         1566  +            SQLiteIndexOrderBy[] orderBys = inputs.OrderBys;
         1567  +
         1568  +            if (orderBys == null)
         1569  +                return;
         1570  +
         1571  +            Type constraintType = typeof(
  1291   1572                   UnsafeNativeMethods.sqlite3_index_constraint);
  1292   1573   
  1293         -            int sizeOfConstraintType = Marshal.SizeOf(indexConstraintType);
         1574  +            int sizeOfConstraintType = Marshal.SizeOf(
         1575  +                constraintType);
  1294   1576   
  1295   1577               for (int iConstraint = 0; iConstraint < nConstraint; iConstraint++)
  1296   1578               {
  1297   1579                   IntPtr pOffset = SQLiteMarshal.IntPtrForOffset(
  1298   1580                       pConstraint, iConstraint * sizeOfConstraintType);
  1299   1581   
  1300   1582                   UnsafeNativeMethods.sqlite3_index_constraint constraint =
  1301   1583                       (UnsafeNativeMethods.sqlite3_index_constraint)
  1302         -                        Marshal.PtrToStructure(pOffset, indexConstraintType);
         1584  +                        Marshal.PtrToStructure(pOffset, constraintType);
  1303   1585   
  1304         -                index.Inputs.Constraints[iConstraint] =
  1305         -                    new SQLiteIndexConstraint(constraint);
         1586  +                constraints[iConstraint] = new SQLiteIndexConstraint(
         1587  +                    constraint);
  1306   1588               }
  1307   1589   
  1308         -            Type indexOrderByType = typeof(
         1590  +            Type orderByType = typeof(
  1309   1591                   UnsafeNativeMethods.sqlite3_index_orderby);
  1310   1592   
  1311         -            int sizeOfOrderByType = Marshal.SizeOf(indexOrderByType);
         1593  +            int sizeOfOrderByType = Marshal.SizeOf(orderByType);
  1312   1594   
  1313   1595               for (int iOrderBy = 0; iOrderBy < nOrderBy; iOrderBy++)
  1314   1596               {
  1315   1597                   IntPtr pOffset = SQLiteMarshal.IntPtrForOffset(
  1316   1598                       pOrderBy, iOrderBy * sizeOfOrderByType);
  1317   1599   
  1318   1600                   UnsafeNativeMethods.sqlite3_index_orderby orderBy =
  1319   1601                       (UnsafeNativeMethods.sqlite3_index_orderby)
  1320         -                        Marshal.PtrToStructure(pOffset, indexOrderByType);
         1602  +                        Marshal.PtrToStructure(pOffset, orderByType);
  1321   1603   
  1322         -                index.Inputs.OrderBys[iOrderBy] =
  1323         -                    new SQLiteIndexOrderBy(orderBy);
         1604  +                orderBys[iOrderBy] = new SQLiteIndexOrderBy(orderBy);
         1605  +            }
         1606  +
         1607  +            if (includeOutput)
         1608  +            {
         1609  +                SQLiteIndexOutputs outputs = index.Outputs;
         1610  +
         1611  +                if (outputs == null)
         1612  +                    return;
         1613  +
         1614  +                SQLiteIndexConstraintUsage[] constraintUsages =
         1615  +                    outputs.ConstraintUsages;
         1616  +
         1617  +                if (constraintUsages == null)
         1618  +                    return;
         1619  +
         1620  +                Type constraintUsageType = typeof(
         1621  +                    UnsafeNativeMethods.sqlite3_index_constraint_usage);
         1622  +
         1623  +                int sizeOfConstraintUsageType = Marshal.SizeOf(
         1624  +                    constraintUsageType);
         1625  +
         1626  +                for (int iConstraint = 0; iConstraint < nConstraint; iConstraint++)
         1627  +                {
         1628  +                    IntPtr pOffset = SQLiteMarshal.IntPtrForOffset(
         1629  +                        pConstraintUsage, iConstraint * sizeOfConstraintUsageType);
         1630  +
         1631  +                    UnsafeNativeMethods.sqlite3_index_constraint_usage constraintUsage =
         1632  +                        (UnsafeNativeMethods.sqlite3_index_constraint_usage)
         1633  +                            Marshal.PtrToStructure(pOffset, constraintUsageType);
         1634  +
         1635  +                    constraintUsages[iConstraint] = new SQLiteIndexConstraintUsage(
         1636  +                        constraintUsage);
         1637  +                }
         1638  +
         1639  +                offset = SQLiteMarshal.NextOffsetOf(
         1640  +                    offset, IntPtr.Size, sizeof(int));
         1641  +
         1642  +                outputs.IndexNumber = SQLiteMarshal.ReadInt32(
         1643  +                    pIndex, offset);
         1644  +
         1645  +                offset = SQLiteMarshal.NextOffsetOf(
         1646  +                    offset, sizeof(int), IntPtr.Size);
         1647  +
         1648  +                outputs.IndexString = SQLiteString.StringFromUtf8IntPtr(
         1649  +                    SQLiteMarshal.ReadIntPtr(pIndex, offset));
         1650  +
         1651  +                offset = SQLiteMarshal.NextOffsetOf(
         1652  +                    offset, IntPtr.Size, sizeof(int));
         1653  +
         1654  +                outputs.NeedToFreeIndexString = SQLiteMarshal.ReadInt32(
         1655  +                    pIndex, offset);
         1656  +
         1657  +                offset = SQLiteMarshal.NextOffsetOf(
         1658  +                    offset, sizeof(int), sizeof(int));
         1659  +
         1660  +                outputs.OrderByConsumed = SQLiteMarshal.ReadInt32(
         1661  +                    pIndex, offset);
         1662  +
         1663  +                offset = SQLiteMarshal.NextOffsetOf(
         1664  +                    offset, sizeof(int), sizeof(double));
         1665  +
         1666  +                outputs.EstimatedCost = SQLiteMarshal.ReadDouble(
         1667  +                    pIndex, offset);
         1668  +
         1669  +                offset = SQLiteMarshal.NextOffsetOf(
         1670  +                    offset, sizeof(double), sizeof(long));
         1671  +
         1672  +                if (outputs.CanUseEstimatedRows())
         1673  +                {
         1674  +                    outputs.EstimatedRows = SQLiteMarshal.ReadInt64(
         1675  +                        pIndex, offset);
         1676  +                }
         1677  +
         1678  +                offset = SQLiteMarshal.NextOffsetOf(
         1679  +                    offset, sizeof(long), sizeof(int));
         1680  +
         1681  +                if (outputs.CanUseIndexFlags())
         1682  +                {
         1683  +                    outputs.IndexFlags = (SQLiteIndexFlags)
         1684  +                        SQLiteMarshal.ReadInt32(pIndex, offset);
         1685  +                }
         1686  +
         1687  +                offset = SQLiteMarshal.NextOffsetOf(
         1688  +                    offset, sizeof(int), sizeof(long));
         1689  +
         1690  +                if (outputs.CanUseColumnsUsed())
         1691  +                {
         1692  +                    outputs.ColumnsUsed = SQLiteMarshal.ReadInt64(
         1693  +                        pIndex, offset);
         1694  +                }
  1324   1695               }
  1325   1696           }
  1326   1697   
  1327   1698           ///////////////////////////////////////////////////////////////////////
  1328   1699   
  1329   1700           /// <summary>
  1330   1701           /// Populates the outputs of a pre-allocated native sqlite3_index_info
................................................................................
  1335   1706           /// The existing <see cref="SQLiteIndex" /> object instance containing
  1336   1707           /// the output data to use.
  1337   1708           /// </param>
  1338   1709           /// <param name="pIndex">
  1339   1710           /// The native pointer to the pre-allocated native sqlite3_index_info
  1340   1711           /// structure.
  1341   1712           /// </param>
         1713  +        /// <param name="includeInput">
         1714  +        /// Non-zero to include fields from the inputs portion of the native
         1715  +        /// structure; otherwise, the "input" fields will not be written.
         1716  +        /// </param>
  1342   1717           internal static void ToIntPtr(
  1343   1718               SQLiteIndex index,
  1344         -            IntPtr pIndex
         1719  +            IntPtr pIndex,
         1720  +            bool includeInput
  1345   1721               )
  1346   1722           {
  1347         -            if ((index == null) || (index.Inputs == null) ||
  1348         -                (index.Inputs.Constraints == null) ||
  1349         -                (index.Outputs == null) ||
  1350         -                (index.Outputs.ConstraintUsages == null))
  1351         -            {
         1723  +            if (index == null)
         1724  +                return;
         1725  +
         1726  +            SQLiteIndexOutputs outputs = index.Outputs;
         1727  +
         1728  +            if (outputs == null)
         1729  +                return;
         1730  +
         1731  +            SQLiteIndexConstraintUsage[] constraintUsages =
         1732  +                outputs.ConstraintUsages;
         1733  +
         1734  +            if (constraintUsages == null)
  1352   1735                   return;
         1736  +
         1737  +            SQLiteIndexInputs inputs = null;
         1738  +            SQLiteIndexConstraint[] constraints = null;
         1739  +            SQLiteIndexOrderBy[] orderBys = null;
         1740  +
         1741  +            if (includeInput)
         1742  +            {
         1743  +                inputs = index.Inputs;
         1744  +
         1745  +                if (inputs == null)
         1746  +                    return;
         1747  +
         1748  +                constraints = inputs.Constraints;
         1749  +
         1750  +                if (constraints == null)
         1751  +                    return;
         1752  +
         1753  +                orderBys = inputs.OrderBys;
         1754  +
         1755  +                if (orderBys == null)
         1756  +                    return;
  1353   1757               }
  1354   1758   
  1355   1759               if (pIndex == IntPtr.Zero)
  1356   1760                   return;
  1357   1761   
  1358   1762               int offset = 0;
  1359   1763   
  1360   1764               int nConstraint = SQLiteMarshal.ReadInt32(pIndex, offset);
  1361   1765   
  1362         -            if (nConstraint != index.Inputs.Constraints.Length)
         1766  +            if (includeInput && (nConstraint != constraints.Length))
         1767  +                return;
         1768  +
         1769  +            if (nConstraint != constraintUsages.Length)
  1363   1770                   return;
  1364   1771   
  1365         -            if (nConstraint != index.Outputs.ConstraintUsages.Length)
         1772  +            offset = SQLiteMarshal.NextOffsetOf(
         1773  +                offset, sizeof(int), IntPtr.Size);
         1774  +
         1775  +            if (includeInput)
         1776  +            {
         1777  +                IntPtr pConstraint = SQLiteMarshal.ReadIntPtr(
         1778  +                    pIndex, offset);
         1779  +
         1780  +                int sizeOfConstraintType = Marshal.SizeOf(typeof(
         1781  +                    UnsafeNativeMethods.sqlite3_index_constraint));
         1782  +
         1783  +                for (int iConstraint = 0; iConstraint < nConstraint; iConstraint++)
         1784  +                {
         1785  +                    UnsafeNativeMethods.sqlite3_index_constraint constraint =
         1786  +                        new UnsafeNativeMethods.sqlite3_index_constraint(
         1787  +                            constraints[iConstraint]);
         1788  +
         1789  +                    Marshal.StructureToPtr(
         1790  +                        constraint, SQLiteMarshal.IntPtrForOffset(
         1791  +                        pConstraint, iConstraint * sizeOfConstraintType),
         1792  +                        false);
         1793  +                }
         1794  +            }
         1795  +
         1796  +            offset = SQLiteMarshal.NextOffsetOf(
         1797  +                offset, IntPtr.Size, sizeof(int));
         1798  +
         1799  +            int nOrderBy = includeInput ?
         1800  +                SQLiteMarshal.ReadInt32(pIndex, offset) : 0;
         1801  +
         1802  +            if (includeInput && (nOrderBy != orderBys.Length))
  1366   1803                   return;
  1367   1804   
  1368         -            offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(int),
  1369         -                IntPtr.Size);
         1805  +            offset = SQLiteMarshal.NextOffsetOf(
         1806  +                offset, sizeof(int), IntPtr.Size);
  1370   1807   
  1371         -            offset = SQLiteMarshal.NextOffsetOf(offset, IntPtr.Size,
  1372         -                sizeof(int));
         1808  +            if (includeInput)
         1809  +            {
         1810  +                IntPtr pOrderBy = SQLiteMarshal.ReadIntPtr(pIndex, offset);
  1373   1811   
  1374         -            offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(int),
  1375         -                IntPtr.Size);
         1812  +                int sizeOfOrderByType = Marshal.SizeOf(typeof(
         1813  +                    UnsafeNativeMethods.sqlite3_index_orderby));
  1376   1814   
  1377         -            offset = SQLiteMarshal.NextOffsetOf(offset, IntPtr.Size,
  1378         -                sizeof(int));
         1815  +                for (int iOrderBy = 0; iOrderBy < nOrderBy; iOrderBy++)
         1816  +                {
         1817  +                    UnsafeNativeMethods.sqlite3_index_orderby orderBy =
         1818  +                        new UnsafeNativeMethods.sqlite3_index_orderby(
         1819  +                            orderBys[iOrderBy]);
  1379   1820   
  1380         -            IntPtr pConstraintUsage = SQLiteMarshal.ReadIntPtr(pIndex, offset);
         1821  +                    Marshal.StructureToPtr(
         1822  +                        orderBy, SQLiteMarshal.IntPtrForOffset(
         1823  +                        pOrderBy, iOrderBy * sizeOfOrderByType),
         1824  +                        false);
         1825  +                }
         1826  +            }
         1827  +
         1828  +            offset = SQLiteMarshal.NextOffsetOf(
         1829  +                offset, IntPtr.Size, IntPtr.Size);
         1830  +
         1831  +            IntPtr pConstraintUsage = SQLiteMarshal.ReadIntPtr(
         1832  +                pIndex, offset);
  1381   1833   
  1382   1834               int sizeOfConstraintUsageType = Marshal.SizeOf(typeof(
  1383   1835                   UnsafeNativeMethods.sqlite3_index_constraint_usage));
  1384   1836   
  1385   1837               for (int iConstraint = 0; iConstraint < nConstraint; iConstraint++)
  1386   1838               {
  1387   1839                   UnsafeNativeMethods.sqlite3_index_constraint_usage constraintUsage =
  1388   1840                       new UnsafeNativeMethods.sqlite3_index_constraint_usage(
  1389         -                        index.Outputs.ConstraintUsages[iConstraint]);
         1841  +                        constraintUsages[iConstraint]);
  1390   1842   
  1391   1843                   Marshal.StructureToPtr(
  1392   1844                       constraintUsage, SQLiteMarshal.IntPtrForOffset(
  1393   1845                       pConstraintUsage, iConstraint * sizeOfConstraintUsageType),
  1394   1846                       false);
  1395   1847               }
  1396   1848   
  1397         -            offset = SQLiteMarshal.NextOffsetOf(offset, IntPtr.Size,
  1398         -                sizeof(int));
         1849  +            offset = SQLiteMarshal.NextOffsetOf(
         1850  +                offset, IntPtr.Size, sizeof(int));
  1399   1851   
  1400   1852               SQLiteMarshal.WriteInt32(pIndex, offset,
  1401         -                index.Outputs.IndexNumber);
         1853  +                outputs.IndexNumber);
  1402   1854   
  1403         -            offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(int),
  1404         -                IntPtr.Size);
         1855  +            offset = SQLiteMarshal.NextOffsetOf(
         1856  +                offset, sizeof(int), IntPtr.Size);
  1405   1857   
  1406   1858               SQLiteMarshal.WriteIntPtr(pIndex, offset,
  1407         -                SQLiteString.Utf8IntPtrFromString(index.Outputs.IndexString));
         1859  +                SQLiteString.Utf8IntPtrFromString(outputs.IndexString));
  1408   1860   
  1409         -            offset = SQLiteMarshal.NextOffsetOf(offset, IntPtr.Size,
  1410         -                sizeof(int));
         1861  +            offset = SQLiteMarshal.NextOffsetOf(
         1862  +                offset, IntPtr.Size, sizeof(int));
  1411   1863   
  1412   1864               //
  1413   1865               // NOTE: We just allocated the IndexString field; therefore, we
  1414         -            //       need to set the NeedToFreeIndexString field to non-zero.
         1866  +            //       need to set make sure the NeedToFreeIndexString field
         1867  +            //       is non-zero; however, we are not picky about the exact
         1868  +            //       value.
  1415   1869               //
  1416         -            SQLiteMarshal.WriteInt32(pIndex, offset, 1);
         1870  +            int needToFreeIndexString = outputs.NeedToFreeIndexString != 0 ?
         1871  +                outputs.NeedToFreeIndexString : 1;
  1417   1872   
  1418         -            offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(int),
  1419         -                sizeof(int));
         1873  +            SQLiteMarshal.WriteInt32(pIndex, offset,
         1874  +                needToFreeIndexString);
         1875  +
         1876  +            offset = SQLiteMarshal.NextOffsetOf(
         1877  +                offset, sizeof(int), sizeof(int));
  1420   1878   
  1421   1879               SQLiteMarshal.WriteInt32(pIndex, offset,
  1422         -                index.Outputs.OrderByConsumed);
         1880  +                outputs.OrderByConsumed);
  1423   1881   
  1424         -            offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(int),
  1425         -                sizeof(double));
         1882  +            offset = SQLiteMarshal.NextOffsetOf(
         1883  +                offset, sizeof(int), sizeof(double));
  1426   1884   
  1427         -            if (index.Outputs.EstimatedCost.HasValue)
         1885  +            if (outputs.EstimatedCost.HasValue)
  1428   1886               {
  1429   1887                   SQLiteMarshal.WriteDouble(pIndex, offset,
  1430         -                    index.Outputs.EstimatedCost.GetValueOrDefault());
         1888  +                    outputs.EstimatedCost.GetValueOrDefault());
  1431   1889               }
  1432   1890   
  1433         -            offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(double),
  1434         -                sizeof(long));
         1891  +            offset = SQLiteMarshal.NextOffsetOf(
         1892  +                offset, sizeof(double), sizeof(long));
  1435   1893   
  1436         -            if (index.Outputs.CanUseEstimatedRows() &&
  1437         -                index.Outputs.EstimatedRows.HasValue)
         1894  +            if (outputs.CanUseEstimatedRows() &&
         1895  +                outputs.EstimatedRows.HasValue)
  1438   1896               {
  1439   1897                   SQLiteMarshal.WriteInt64(pIndex, offset,
  1440         -                    index.Outputs.EstimatedRows.GetValueOrDefault());
         1898  +                    outputs.EstimatedRows.GetValueOrDefault());
  1441   1899               }
  1442   1900   
  1443         -            offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(long),
  1444         -                sizeof(int));
         1901  +            offset = SQLiteMarshal.NextOffsetOf(
         1902  +                offset, sizeof(long), sizeof(int));
  1445   1903   
  1446         -            if (index.Outputs.CanUseIdxFlags() &&
  1447         -                index.Outputs.IdxFlags.HasValue)
         1904  +            if (outputs.CanUseIndexFlags() &&
         1905  +                outputs.IndexFlags.HasValue)
  1448   1906               {
  1449   1907                   SQLiteMarshal.WriteInt32(pIndex, offset,
  1450         -                   (int)index.Outputs.IdxFlags.GetValueOrDefault());
         1908  +                   (int)outputs.IndexFlags.GetValueOrDefault());
  1451   1909               }
  1452   1910   
  1453         -            offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(int),
  1454         -                sizeof(long));
         1911  +            offset = SQLiteMarshal.NextOffsetOf(
         1912  +                offset, sizeof(int), sizeof(long));
  1455   1913   
  1456         -            if (index.Outputs.CanUseColUsed() &&
  1457         -                index.Outputs.ColUsed.HasValue)
         1914  +            if (outputs.CanUseColumnsUsed() &&
         1915  +                outputs.ColumnsUsed.HasValue)
  1458   1916               {
  1459   1917                   SQLiteMarshal.WriteInt64(pIndex, offset,
  1460         -                    index.Outputs.ColUsed.GetValueOrDefault());
         1918  +                    outputs.ColumnsUsed.GetValueOrDefault());
  1461   1919               }
  1462   1920           }
  1463   1921           #endregion
  1464   1922   
  1465   1923           ///////////////////////////////////////////////////////////////////////
  1466   1924   
  1467   1925           #region Public Properties
................................................................................
  3277   3735           {
  3278   3736   #if !PLATFORM_COMPACTFRAMEWORK
  3279   3737               return Marshal.ReadInt32(pointer, offset);
  3280   3738   #else
  3281   3739               return Marshal.ReadInt32(IntPtrForOffset(pointer, offset));
  3282   3740   #endif
  3283   3741           }
         3742  +
         3743  +        ///////////////////////////////////////////////////////////////////////
         3744  +
         3745  +        /// <summary>
         3746  +        /// Reads a <see cref="Int64" /> value from the specified memory
         3747  +        /// location.
         3748  +        /// </summary>
         3749  +        /// <param name="pointer">
         3750  +        /// The <see cref="IntPtr" /> object instance representing the base
         3751  +        /// memory location.
         3752  +        /// </param>
         3753  +        /// <param name="offset">
         3754  +        /// The integer offset from the base memory location where the
         3755  +        /// <see cref="Int64" /> value to be read is located.
         3756  +        /// </param>
         3757  +        /// <returns>
         3758  +        /// The <see cref="Int64" /> value at the specified memory location.
         3759  +        /// </returns>
         3760  +        public static long ReadInt64(
         3761  +            IntPtr pointer,
         3762  +            int offset
         3763  +            )
         3764  +        {
         3765  +#if !PLATFORM_COMPACTFRAMEWORK
         3766  +            return Marshal.ReadInt64(pointer, offset);
         3767  +#else
         3768  +            return Marshal.ReadInt64(IntPtrForOffset(pointer, offset));
         3769  +#endif
         3770  +        }
  3284   3771   
  3285   3772           ///////////////////////////////////////////////////////////////////////
  3286   3773   
  3287   3774           /// <summary>
  3288   3775           /// Reads a <see cref="Double" /> value from the specified memory
  3289   3776           /// location.
  3290   3777           /// </summary>
................................................................................
  5139   5626               try
  5140   5627               {
  5141   5628                   if (pVtab == IntPtr.Zero)
  5142   5629                       return false;
  5143   5630   
  5144   5631                   int offset = 0;
  5145   5632   
  5146         -                offset = SQLiteMarshal.NextOffsetOf(offset, IntPtr.Size,
  5147         -                    sizeof(int));
         5633  +                offset = SQLiteMarshal.NextOffsetOf(
         5634  +                    offset, IntPtr.Size, sizeof(int));
  5148   5635   
  5149         -                offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(int),
  5150         -                    IntPtr.Size);
         5636  +                offset = SQLiteMarshal.NextOffsetOf(
         5637  +                    offset, sizeof(int), IntPtr.Size);
  5151   5638   
  5152   5639                   IntPtr pOldError = SQLiteMarshal.ReadIntPtr(pVtab, offset);
  5153   5640   
  5154   5641                   if (pOldError != IntPtr.Zero)
  5155   5642                   {
  5156   5643                       SQLiteMemory.Free(pOldError); pOldError = IntPtr.Zero;
  5157   5644                       SQLiteMarshal.WriteIntPtr(pVtab, offset, pOldError);
................................................................................
  5417   5904               if (pVtab == IntPtr.Zero)
  5418   5905                   return;
  5419   5906   
  5420   5907               int offset = 0;
  5421   5908   
  5422   5909               SQLiteMarshal.WriteIntPtr(pVtab, offset, IntPtr.Zero);
  5423   5910   
  5424         -            offset = SQLiteMarshal.NextOffsetOf(offset, IntPtr.Size,
  5425         -                sizeof(int));
         5911  +            offset = SQLiteMarshal.NextOffsetOf(
         5912  +                offset, IntPtr.Size, sizeof(int));
  5426   5913   
  5427   5914               SQLiteMarshal.WriteInt32(pVtab, offset, 0);
  5428   5915   
  5429         -            offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(int),
  5430         -                IntPtr.Size);
         5916  +            offset = SQLiteMarshal.NextOffsetOf(
         5917  +                offset, sizeof(int), IntPtr.Size);
  5431   5918   
  5432   5919               SQLiteMarshal.WriteIntPtr(pVtab, offset, IntPtr.Zero);
  5433   5920           }
  5434   5921   
  5435   5922           ///////////////////////////////////////////////////////////////////////
  5436   5923   
  5437   5924           /// <summary>
................................................................................
  6079   6566           /// <summary>
  6080   6567           /// Modifies the specified <see cref="SQLiteIndex" /> object instance
  6081   6568           /// to contain the specified flags.
  6082   6569           /// </summary>
  6083   6570           /// <param name="index">
  6084   6571           /// The <see cref="SQLiteIndex" /> object instance to modify.
  6085   6572           /// </param>
  6086         -        /// <param name="idxFlags">
         6573  +        /// <param name="indexFlags">
  6087   6574           /// The index flags value to use.  Using a null value means that the
  6088   6575           /// default value provided by the SQLite core library should be used.
  6089   6576           /// </param>
  6090   6577           /// <returns>
  6091   6578           /// Non-zero upon success.
  6092   6579           /// </returns>
  6093         -        protected virtual bool SetIdxFlags(
         6580  +        protected virtual bool SetIndexFlags(
  6094   6581               SQLiteIndex index,
  6095         -            SQLiteIndexFlags? idxFlags
         6582  +            SQLiteIndexFlags? indexFlags
  6096   6583               )
  6097   6584           {
  6098   6585               if ((index == null) || (index.Outputs == null))
  6099   6586                   return false;
  6100   6587   
  6101         -            index.Outputs.IdxFlags = idxFlags;
         6588  +            index.Outputs.IndexFlags = indexFlags;
  6102   6589               return true;
  6103   6590           }
  6104   6591   
  6105   6592           ///////////////////////////////////////////////////////////////////////
  6106   6593   
  6107   6594           /// <summary>
  6108   6595           /// Modifies the specified <see cref="SQLiteIndex" /> object instance
................................................................................
  6110   6597           /// </summary>
  6111   6598           /// <param name="index">
  6112   6599           /// The <see cref="SQLiteIndex" /> object instance to modify.
  6113   6600           /// </param>
  6114   6601           /// <returns>
  6115   6602           /// Non-zero upon success.
  6116   6603           /// </returns>
  6117         -        protected virtual bool SetIdxFlags(
         6604  +        protected virtual bool SetIndexFlags(
  6118   6605               SQLiteIndex index
  6119   6606               )
  6120   6607           {
  6121         -            return SetIdxFlags(index, null);
         6608  +            return SetIndexFlags(index, null);
  6122   6609           }
  6123   6610           #endregion
  6124   6611           #endregion
  6125   6612   
  6126   6613           ///////////////////////////////////////////////////////////////////////
  6127   6614   
  6128   6615           #region Public Properties
................................................................................
  6255   6742               {
  6256   6743                   SQLiteVirtualTable table = TableFromIntPtr(pVtab);
  6257   6744   
  6258   6745                   if (table != null)
  6259   6746                   {
  6260   6747                       SQLiteIndex index = null;
  6261   6748   
  6262         -                    SQLiteIndex.FromIntPtr(pIndex, ref index);
         6749  +                    SQLiteIndex.FromIntPtr(pIndex, true, ref index);
  6263   6750   
  6264   6751                       if (BestIndex(table, index) == SQLiteErrorCode.Ok)
  6265   6752                       {
  6266         -                        SQLiteIndex.ToIntPtr(index, pIndex);
         6753  +                        SQLiteIndex.ToIntPtr(index, pIndex, true);
  6267   6754                           return SQLiteErrorCode.Ok;
  6268   6755                       }
  6269   6756                   }
  6270   6757               }
  6271   6758               catch (Exception e) /* NOTE: Must catch ALL. */
  6272   6759               {
  6273   6760                   SetTableError(pVtab, e.ToString());

Changes to System.Data.SQLite/UnsafeNativeMethods.cs.

  2851   2851   
  2852   2852       [StructLayout(LayoutKind.Sequential)]
  2853   2853       internal struct sqlite3_index_info
  2854   2854       {
  2855   2855           /* Inputs */
  2856   2856           public int nConstraint; /* Number of entries in aConstraint */
  2857   2857           public IntPtr aConstraint;
  2858         -        public int nOrderBy;
         2858  +        public int nOrderBy;    /* Number of entries in aOrderBy */
  2859   2859           public IntPtr aOrderBy;
  2860   2860           /* Outputs */
  2861   2861           public IntPtr aConstraintUsage;
  2862   2862           public int idxNum;           /* Number used to identify the index */
  2863   2863           public string idxStr;        /* String, possibly obtained from sqlite3_malloc */
  2864   2864           public int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */
  2865   2865           public int orderByConsumed;  /* True if output is already ordered */
  2866   2866           public double estimatedCost; /* Estimated cost of using this index */
         2867  +        public long estimatedRows;   /* Estimated number of rows returned */
         2868  +        public SQLiteIndexFlags idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */
         2869  +        public long colUsed;         /* Input: Mask of columns used by statement */
  2867   2870       }
  2868   2871   #endif
  2869   2872       #endregion
  2870   2873     }
  2871   2874   
  2872   2875     /////////////////////////////////////////////////////////////////////////////
  2873   2876   

Changes to Tests/vtab.eagle.

  1771   1771   
  1772   1772     unset -nocomplain result code results errors sql dataSource id fileName
  1773   1773   } -constraints {eagle command.object monoBug28 command.sql compile.DATA SQLite\
  1774   1774   System.Data.SQLite defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE\
  1775   1775   compileCSharp} -match regexp -result [string map [list \n \r\n] {^Ok\
  1776   1776   System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{-?\d+ one -?\d+ two -?\d+\
  1777   1777   three -?\d+ 4 -?\d+ 5\.0\}$}]}
         1778  +
         1779  +###############################################################################
         1780  +
         1781  +runTest {test vtab-1.12 {SQLiteIndex managed-to-native-to-managed} -setup {
         1782  +  set nConstraint 3; set nOrderBy 3
         1783  +} -body {
         1784  +  set index(1) [object create -alias -flags +NonPublic \
         1785  +      System.Data.SQLite.SQLiteIndex $nConstraint $nOrderBy]
         1786  +
         1787  +  for {set iConstraint 0} {$iConstraint < $nConstraint} {incr iConstraint} {
         1788  +    set constraint(1) [object create -alias -flags +NonPublic \
         1789  +        System.Data.SQLite.SQLiteIndexConstraint 0 0 0 0]
         1790  +
         1791  +    $index(1) Inputs.Constraints.SetValue $constraint(1) $iConstraint
         1792  +
         1793  +    $constraint(1) iColumn [expr {int(0x01234567 + $iConstraint)}]
         1794  +    $constraint(1) op [expr {0xFF - $iConstraint}]
         1795  +    $constraint(1) usable [expr {0xCC + $iConstraint}]
         1796  +    $constraint(1) iTermOffset [expr {int(0x89ABCDEF + $iConstraint)}]
         1797  +  }
         1798  +
         1799  +  for {set iOrderBy 0} {$iOrderBy < $nOrderBy} {incr iOrderBy} {
         1800  +    set orderBy(1) [object create -alias -flags +NonPublic \
         1801  +        System.Data.SQLite.SQLiteIndexOrderBy 0 0]
         1802  +
         1803  +    $index(1) Inputs.OrderBys.SetValue $orderBy(1) $iOrderBy
         1804  +
         1805  +    $orderBy(1) iColumn [expr {int(0x23016745 + $iOrderBy)}]
         1806  +    $orderBy(1) desc [expr {0xFF - $iOrderBy}]
         1807  +  }
         1808  +
         1809  +  for {set iConstraint 0} {$iConstraint < $nConstraint} {incr iConstraint} {
         1810  +    set constraintUsage(1) [object create -alias -flags +NonPublic \
         1811  +        System.Data.SQLite.SQLiteIndexConstraintUsage 0 0]
         1812  +
         1813  +    $index(1) Outputs.ConstraintUsages.SetValue $constraintUsage(1) \
         1814  +        $iConstraint
         1815  +
         1816  +    $constraintUsage(1) argvIndex [expr {int(0xAB89EFCD + $iConstraint)}]
         1817  +    $constraintUsage(1) omit [expr {0xCC + $iConstraint}]
         1818  +  }
         1819  +
         1820  +  $index(1) Outputs.IndexNumber [expr {int(0xAAAAAAAA)}]
         1821  +  $index(1) Outputs.IndexString "\x01test index string.\xFF"
         1822  +  $index(1) Outputs.NeedToFreeIndexString [expr {int(0x55555555)}]
         1823  +  $index(1) Outputs.OrderByConsumed [expr {int(0x33333333)}]
         1824  +  $index(1) Outputs.EstimatedCost 1.0
         1825  +
         1826  +  if {[$index(1) Outputs.CanUseEstimatedRows]} then {
         1827  +    $index(1) Outputs.EstimatedRows [expr {int(0xCCCCCCCC)}]
         1828  +  }
         1829  +
         1830  +  if {[$index(1) Outputs.CanUseIndexFlags]} then {
         1831  +    $index(1) Outputs.IndexFlags [expr {int(0xEEEEEEEE)}]
         1832  +  }
         1833  +
         1834  +  if {[$index(1) Outputs.CanUseColumnsUsed]} then {
         1835  +    $index(1) Outputs.ColumnsUsed [expr {wide(0xBADC0FFEE875621A)}]
         1836  +  }
         1837  +
         1838  +  set pIndex(1) [object invoke -create -flags +NonPublic \
         1839  +      System.Data.SQLite.SQLiteIndex AllocMemoryBlock \
         1840  +      $nConstraint $nOrderBy]
         1841  +
         1842  +  object invoke -flags +NonPublic \
         1843  +      System.Data.SQLite.SQLiteIndex ToIntPtr $index(1) $pIndex(1) true
         1844  +
         1845  +  set index(2) [object create -alias -flags +NonPublic \
         1846  +      System.Data.SQLite.SQLiteIndex $nConstraint $nOrderBy]
         1847  +
         1848  +  object invoke -alias -flags +NonPublic \
         1849  +      System.Data.SQLite.SQLiteIndex FromIntPtr $pIndex(1) true index(2)
         1850  +
         1851  +  for {set iConstraint 0} {$iConstraint < $nConstraint} {incr iConstraint} {
         1852  +    set constraint(1) [$index(1) \
         1853  +        -alias Inputs.Constraints.GetValue $iConstraint]
         1854  +
         1855  +    set constraint(2) [$index(2) \
         1856  +        -alias Inputs.Constraints.GetValue $iConstraint]
         1857  +
         1858  +    if {[$constraint(1) iColumn] != [$constraint(2) iColumn]} then {
         1859  +      error [appendArgs \
         1860  +          "iColumn at index " $iConstraint " does not match"]
         1861  +    }
         1862  +
         1863  +    if {[$constraint(1) op] != [$constraint(2) op]} then {
         1864  +      error [appendArgs \
         1865  +          "op at index " $iConstraint " does not match"]
         1866  +    }
         1867  +
         1868  +    if {[$constraint(1) usable] != [$constraint(2) usable]} then {
         1869  +      error [appendArgs \
         1870  +          "usable at index " $iConstraint " does not match"]
         1871  +    }
         1872  +
         1873  +    if {[$constraint(1) iTermOffset] != [$constraint(2) iTermOffset]} then {
         1874  +      error [appendArgs \
         1875  +          "iTermOffset at index " $iConstraint " does not match"]
         1876  +    }
         1877  +  }
         1878  +
         1879  +  for {set iOrderBy 0} {$iOrderBy < $nOrderBy} {incr iOrderBy} {
         1880  +    set orderBy(1) [$index(1) \
         1881  +        -alias Inputs.OrderBys.GetValue $iOrderBy]
         1882  +
         1883  +    set orderBy(2) [$index(2) \
         1884  +        -alias Inputs.OrderBys.GetValue $iOrderBy]
         1885  +
         1886  +    if {[$orderBy(1) iColumn] != [$orderBy(2) iColumn]} then {
         1887  +      error [appendArgs \
         1888  +          "iColumn at index " $iOrderBy " does not match"]
         1889  +    }
         1890  +
         1891  +    if {[$orderBy(1) desc] != [$orderBy(2) desc]} then {
         1892  +      error [appendArgs \
         1893  +          "desc at index " $iOrderBy " does not match"]
         1894  +    }
         1895  +  }
         1896  +
         1897  +  for {set iConstraint 0} {$iConstraint < $nConstraint} {incr iConstraint} {
         1898  +    set constraintUsage(1) [$index(1) \
         1899  +        -alias Outputs.ConstraintUsages.GetValue $iConstraint]
         1900  +
         1901  +    set constraintUsage(2) [$index(2) \
         1902  +        -alias Outputs.ConstraintUsages.GetValue $iConstraint]
         1903  +
         1904  +    if {[$constraintUsage(1) argvIndex] != \
         1905  +        [$constraintUsage(2) argvIndex]} then {
         1906  +      error [appendArgs \
         1907  +          "argvIndex at index " $iConstraint " does not match"]
         1908  +    }
         1909  +
         1910  +    if {[$constraintUsage(1) omit] != [$constraintUsage(2) omit]} then {
         1911  +      error [appendArgs \
         1912  +          "omit at index " $iConstraint " does not match"]
         1913  +    }
         1914  +  }
         1915  +
         1916  +  if {[$index(1) Outputs.IndexNumber] != \
         1917  +      [$index(2) Outputs.IndexNumber]} then {
         1918  +    error "IndexNumber does not match"
         1919  +  }
         1920  +
         1921  +  if {[$index(1) Outputs.IndexString] ne \
         1922  +      [$index(2) Outputs.IndexString]} then {
         1923  +    error "IndexString does not match"
         1924  +  }
         1925  +
         1926  +  if {[$index(1) Outputs.NeedToFreeIndexString] != \
         1927  +      [$index(2) Outputs.NeedToFreeIndexString]} then {
         1928  +    error "NeedToFreeIndexString does not match"
         1929  +  }
         1930  +
         1931  +  if {[$index(1) Outputs.OrderByConsumed] != \
         1932  +      [$index(2) Outputs.OrderByConsumed]} then {
         1933  +    error "OrderByConsumed does not match"
         1934  +  }
         1935  +
         1936  +  if {[$index(1) Outputs.EstimatedCost] != \
         1937  +      [$index(2) Outputs.EstimatedCost]} then {
         1938  +    error "EstimatedCost does not match"
         1939  +  }
         1940  +
         1941  +  if {[$index(1) Outputs.CanUseEstimatedRows] && \
         1942  +      [$index(2) Outputs.CanUseEstimatedRows]} then {
         1943  +    if {[$index(1) Outputs.EstimatedRows] != \
         1944  +        [$index(2) Outputs.EstimatedRows]} then {
         1945  +      error "EstimatedRows does not match"
         1946  +    }
         1947  +  }
         1948  +
         1949  +  if {[$index(1) Outputs.CanUseIndexFlags] && \
         1950  +      [$index(2) Outputs.CanUseIndexFlags]} then {
         1951  +    if {[$index(1) Outputs.IndexFlags] != \
         1952  +        [$index(2) Outputs.IndexFlags]} then {
         1953  +      error "IndexFlags does not match"
         1954  +    }
         1955  +  }
         1956  +
         1957  +  if {[$index(1) Outputs.CanUseColumnsUsed] && \
         1958  +      [$index(2) Outputs.CanUseColumnsUsed]} then {
         1959  +    if {[$index(1) Outputs.ColumnsUsed] != \
         1960  +        [$index(2) Outputs.ColumnsUsed]} then {
         1961  +      error "ColumnsUsed does not match"
         1962  +    }
         1963  +  }
         1964  +} -cleanup {
         1965  +  catch {
         1966  +    object invoke -flags +NonPublic \
         1967  +        System.Data.SQLite.SQLiteIndex FreeMemoryBlock $pIndex(1)
         1968  +  }
         1969  +
         1970  +  unset -nocomplain constraintUsage
         1971  +  unset -nocomplain orderBy nOrderBy iOrderBy
         1972  +  unset -nocomplain constraint nConstraint iConstraint
         1973  +  unset -nocomplain pIndex index
         1974  +} -constraints {eagle command.object System.Data.SQLite\
         1975  +defineConstant.System.Data.SQLite.INTEROP_VIRTUAL_TABLE} -result {}}
  1778   1976   
  1779   1977   ###############################################################################
  1780   1978   
  1781   1979   runSQLiteTestEpilogue
  1782   1980   runTestEpilogue