Index: SQLite.Designer/Design/Index.cs
==================================================================
--- SQLite.Designer/Design/Index.cs
+++ SQLite.Designer/Design/Index.cs
@@ -391,11 +391,15 @@
internal IndexColumn(Index parent, DataRow row)
{
_parent = parent;
if (row != null)
{
- _column = row["COLUMN_NAME"].ToString();
+ if (!row.IsNull("COLUMN_NAME"))
+ _column = row["COLUMN_NAME"].ToString();
+ else
+ _column = null;
+
if (row.IsNull("SORT_MODE") == false && (string)row["SORT_MODE"] != "ASC")
_mode = ColumnSortMode.Descending;
if (row.IsNull("COLLATION_NAME") == false)
_collate = row["COLLATION_NAME"].ToString().ToUpperInvariant();
Index: Setup/data/verify.lst
==================================================================
--- Setup/data/verify.lst
+++ Setup/data/verify.lst
@@ -790,10 +790,11 @@
Tests/tkt-448d663d11.eagle
Tests/tkt-47c6fa04d3.eagle
Tests/tkt-47f4bac575.eagle
Tests/tkt-48a6b8e4ca.eagle
Tests/tkt-4a791e70ab.eagle
+ Tests/tkt-5251bd0878.eagle
Tests/tkt-544dba0a2f.eagle
Tests/tkt-56b42d99c1.eagle
Tests/tkt-58ed318f2f.eagle
Tests/tkt-59edc1018b.eagle
Tests/tkt-6434e23a0f.eagle
Index: System.Data.SQLite/SQLiteConnection.cs
==================================================================
--- System.Data.SQLite/SQLiteConnection.cs
+++ System.Data.SQLite/SQLiteConnection.cs
@@ -4755,33 +4755,37 @@
using (SQLiteCommand cmdIndex = new SQLiteCommand(UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "PRAGMA [{0}].index_info([{1}])", strCatalog, rdIndexes.GetString(1)), this))
using (SQLiteDataReader rdIndex = cmdIndex.ExecuteReader())
{
while (rdIndex.Read())
{
+ string columnName = rdIndex.IsDBNull(2) ? null : rdIndex.GetString(2);
+
row = tbl.NewRow();
row["CONSTRAINT_CATALOG"] = strCatalog;
row["CONSTRAINT_NAME"] = rdIndexes.GetString(1);
row["TABLE_CATALOG"] = strCatalog;
row["TABLE_NAME"] = rdIndexes.GetString(2);
- row["COLUMN_NAME"] = rdIndex.GetString(2);
+ row["COLUMN_NAME"] = columnName;
row["INDEX_NAME"] = rdIndexes.GetString(1);
row["ORDINAL_POSITION"] = ordinal; // rdIndex.GetInt32(1);
string collationSequence = null;
int sortMode = 0;
int onError = 0;
- _sql.GetIndexColumnExtendedInfo(strCatalog, rdIndexes.GetString(1), rdIndex.GetString(2), ref sortMode, ref onError, ref collationSequence);
+
+ if (columnName != null)
+ _sql.GetIndexColumnExtendedInfo(strCatalog, rdIndexes.GetString(1), columnName, ref sortMode, ref onError, ref collationSequence);
if (String.IsNullOrEmpty(collationSequence) == false)
row["COLLATION_NAME"] = collationSequence;
row["SORT_MODE"] = (sortMode == 0) ? "ASC" : "DESC";
row["CONFLICT_OPTION"] = onError;
ordinal++;
- if (String.IsNullOrEmpty(strColumn) || String.Compare(strColumn, row["COLUMN_NAME"].ToString(), StringComparison.OrdinalIgnoreCase) == 0)
+ if ((strColumn == null) || String.Compare(strColumn, columnName, StringComparison.OrdinalIgnoreCase) == 0)
tbl.Rows.Add(row);
}
}
}
catch (SQLiteException)
Index: System.Data.SQLite/SQLiteConvert.cs
==================================================================
--- System.Data.SQLite/SQLiteConvert.cs
+++ System.Data.SQLite/SQLiteConvert.cs
@@ -1828,10 +1828,40 @@
{
if (!found && (connection != null))
connection.SetCachedSetting(name, value);
}
}
+
+ ///
+ /// Converts the object value, which is assumed to have originated
+ /// from a , to a string value.
+ ///
+ ///
+ /// The value to be converted to a string.
+ ///
+ ///
+ /// A null value will be returned if the original value is null -OR-
+ /// the original value is . Otherwise,
+ /// the original value will be converted to a string, using its
+ /// (possibly overridden) method and
+ /// then returned.
+ ///
+ public static string GetStringOrNull(
+ object value
+ )
+ {
+ if (value == null)
+ return null;
+
+ if (value is string)
+ return (string)value;
+
+ if (value == DBNull.Value)
+ return null;
+
+ return value.ToString();
+ }
///
/// Determines if the specified textual value appears to be a
/// value.
///
Index: System.Data.SQLite/SQLiteDataReader.cs
==================================================================
--- System.Data.SQLite/SQLiteDataReader.cs
+++ System.Data.SQLite/SQLiteDataReader.cs
@@ -1170,11 +1170,11 @@
(string)rowIndexes["INDEX_NAME"],
null
});
foreach (DataRow rowColumnIndex in tblIndexColumns.Rows)
{
- if (String.Compare((string)rowColumnIndex["COLUMN_NAME"], strColumn, StringComparison.OrdinalIgnoreCase) == 0)
+ if (String.Compare(SQLiteConvert.GetStringOrNull(rowColumnIndex["COLUMN_NAME"]), strColumn, StringComparison.OrdinalIgnoreCase) == 0)
{
//
// BUGFIX: Make sure that we only flag this column as "unique"
// if we are not processing of some kind of multi-table
// construct (i.e. a join) because in that case we must
Index: System.Data.SQLite/SQLiteKeyReader.cs
==================================================================
--- System.Data.SQLite/SQLiteKeyReader.cs
+++ System.Data.SQLite/SQLiteKeyReader.cs
@@ -241,18 +241,21 @@
KeyQuery query = null;
List cols = new List();
for (int x = 0; x < indexColumns.Rows.Count; x++)
{
+ string columnName = SQLiteConvert.GetStringOrNull(
+ indexColumns.Rows[x]["COLUMN_NAME"]);
+
bool addKey = true;
// If the column in the index already appears in the query, skip it
foreach (DataRow row in schema.Rows)
{
if (row.IsNull(SchemaTableColumn.BaseColumnName))
continue;
- if ((string)row[SchemaTableColumn.BaseColumnName] == (string)indexColumns.Rows[x]["COLUMN_NAME"] &&
+ if ((string)row[SchemaTableColumn.BaseColumnName] == columnName &&
(string)row[SchemaTableColumn.BaseTableName] == table &&
(string)row[SchemaTableOptionalColumn.BaseCatalogName] == pair.Key)
{
indexColumns.Rows.RemoveAt(x);
x--;
@@ -259,11 +262,11 @@
addKey = false;
break;
}
}
if (addKey == true)
- cols.Add((string)indexColumns.Rows[x]["COLUMN_NAME"]);
+ cols.Add(columnName);
}
// If the index is not a rowid alias, record all the columns
// needed to make up the unique index and construct a SQL query for it
if ((string)preferredRow["INDEX_NAME"] != "sqlite_master_PK_" + table)
@@ -279,11 +282,11 @@
}
// Create a KeyInfo struct for each column of the index
for (int x = 0; x < indexColumns.Rows.Count; x++)
{
- string columnName = (string)indexColumns.Rows[x]["COLUMN_NAME"];
+ string columnName = SQLiteConvert.GetStringOrNull(indexColumns.Rows[x]["COLUMN_NAME"]);
KeyInfo key = new KeyInfo();
key.rootPage = rootPage;
key.cursor = cursor;
key.database = database;
ADDED Tests/tkt-5251bd0878.eagle
Index: Tests/tkt-5251bd0878.eagle
==================================================================
--- /dev/null
+++ Tests/tkt-5251bd0878.eagle
@@ -0,0 +1,78 @@
+###############################################################################
+#
+# tkt-5251bd0878.eagle --
+#
+# Written by Joe Mistachkin.
+# Released to the public domain, use at your own risk!
+#
+###############################################################################
+
+package require Eagle
+package require Eagle.Library
+package require Eagle.Test
+
+runTestPrologue
+
+###############################################################################
+
+package require System.Data.SQLite.Test
+runSQLiteTestPrologue
+
+###############################################################################
+
+runTest {test tkt-5251bd0878-1.1 {indexed expressions schema} -setup {
+ setupDb [set fileName tkt-5251bd0878-1.1.db]
+} -body {
+ set connection [getDbConnection]
+
+ sql execute $db {
+ CREATE TABLE t1(x INTEGER PRIMARY KEY, y INTEGER);
+ INSERT INTO t1 (y) VALUES (-2000);
+ INSERT INTO t1 (y) VALUES (-1000);
+ INSERT INTO t1 (y) VALUES (-200);
+ INSERT INTO t1 (y) VALUES (-100);
+ INSERT INTO t1 (y) VALUES (-20);
+ INSERT INTO t1 (y) VALUES (-10);
+ INSERT INTO t1 (y) VALUES (0);
+ INSERT INTO t1 (y) VALUES (10);
+ INSERT INTO t1 (y) VALUES (20);
+ INSERT INTO t1 (y) VALUES (100);
+ INSERT INTO t1 (y) VALUES (200);
+ INSERT INTO t1 (y) VALUES (1000);
+ INSERT INTO t1 (y) VALUES (2000);
+ INSERT INTO t1 (y) VALUES (10000);
+ INSERT INTO t1 (y) VALUES (20000);
+ CREATE INDEX i1 ON t1(x, abs(y));
+ }
+
+ set dataReader [sql execute -execute reader -format datareader \
+ -alias $db "SELECT x, y FROM t1;"]
+
+ set dataTable [$dataReader -alias GetSchemaTable]
+ set result [list]
+
+ foreach row [getRowsFromDataTable $dataTable] {
+ foreach column $row {
+ if {[lindex $column 0] in [list ColumnName IsKey]} then {
+ lappend result $column
+ }
+ }
+ }
+
+ set result
+} -cleanup {
+ unset -nocomplain dataTable dataReader
+
+ cleanupDb $fileName
+
+ freeDbConnection
+
+ unset -nocomplain column row result connection db fileName
+} -constraints {eagle command.object monoBug28 command.sql compile.DATA SQLite\
+System.Data.SQLite} -result {{ColumnName x} {IsKey True} {ColumnName y} {IsKey\
+False}}}
+
+###############################################################################
+
+runSQLiteTestEpilogue
+runTestEpilogue