Commit 5abaa779 authored by Bruce Momjian's avatar Bruce Momjian

Fix for HASH for index lookups in ODBC.

parent 014f98dd
...@@ -1688,16 +1688,16 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData ...@@ -1688,16 +1688,16 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
String relKind; String relKind;
switch (r.getBytes(3)[0]) { switch (r.getBytes(3)[0]) {
case 'r': case (byte) 'r':
relKind = "TABLE"; relKind = "TABLE";
break; break;
case 'i': case (byte) 'i':
relKind = "INDEX"; relKind = "INDEX";
break; break;
case 'S': case (byte) 'S':
relKind = "SEQUENCE"; relKind = "SEQUENCE";
break; break;
case 'v': case (byte) 'v':
relKind = "VIEW"; relKind = "VIEW";
break; break;
default: default:
...@@ -2623,11 +2623,10 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData ...@@ -2623,11 +2623,10 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
* @return ResultSet each row is an index column description * @return ResultSet each row is an index column description
*/ */
// Implementation note: This is required for Borland's JBuilder to work // Implementation note: This is required for Borland's JBuilder to work
public java.sql.ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate) throws SQLException public java.sql.ResultSet getIndexInfo(String catalog, String schema, String tableName, boolean unique, boolean approximate) throws SQLException
{ {
// for now, this returns an empty result set.
Field f[] = new Field[13]; Field f[] = new Field[13];
ResultSet r; // ResultSet for the SQL query that we need to do java.sql.ResultSet r; // ResultSet for the SQL query that we need to do
Vector v = new Vector(); // The new ResultSet tuple stuff Vector v = new Vector(); // The new ResultSet tuple stuff
f[0] = new Field(connection, "TABLE_CAT", iVarcharOid, 32); f[0] = new Field(connection, "TABLE_CAT", iVarcharOid, 32);
...@@ -2644,6 +2643,60 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData ...@@ -2644,6 +2643,60 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
f[11] = new Field(connection, "PAGES", iInt4Oid, 4); f[11] = new Field(connection, "PAGES", iInt4Oid, 4);
f[12] = new Field(connection, "FILTER_CONDITION", iVarcharOid, 32); f[12] = new Field(connection, "FILTER_CONDITION", iVarcharOid, 32);
r = connection.ExecSQL("select " +
"c.relname, " +
"x.indisunique, " +
"i.relname, " +
"x.indisclustered, " +
"a.amname, " +
"x.indkey, " +
"c.reltuples, " +
"c.relpages " +
"FROM pg_index x, pg_class c, pg_class i, pg_am a " +
"WHERE ((c.relname = '" + tableName.toLowerCase() + "') " +
" AND (c.oid = x.indrelid) " +
" AND (i.oid = x.indexrelid) " +
" AND (c.relam = a.oid)) " +
"ORDER BY x.indisunique DESC, " +
" x.indisclustered, a.amname, i.relname");
while (r.next()) {
// indkey is an array of column ordinals (integers). In the JDBC
// interface, this has to be separated out into a separate
// tuple for each indexed column. Also, getArray() is not yet
// implemented for Postgres JDBC, so we parse by hand.
String columnOrdinalString = r.getString(6);
StringTokenizer stok = new StringTokenizer(columnOrdinalString);
int [] columnOrdinals = new int[stok.countTokens()];
int o = 0;
while (stok.hasMoreTokens()) {
columnOrdinals[o++] = Integer.parseInt(stok.nextToken());
}
for (int i = 0; i < columnOrdinals.length; i++) {
byte [] [] tuple = new byte [13] [];
tuple[0] = "".getBytes();
tuple[1] = "".getBytes();
tuple[2] = r.getBytes(1);
tuple[3] = r.getBoolean(2) ? "f".getBytes() : "t".getBytes();
tuple[4] = null;
tuple[5] = r.getBytes(3);
tuple[6] = r.getBoolean(4) ?
Integer.toString(tableIndexClustered).getBytes() :
r.getString(5).equals("hash") ?
Integer.toString(tableIndexHashed).getBytes() :
Integer.toString(tableIndexOther).getBytes();
tuple[7] = Integer.toString(i + 1).getBytes();
java.sql.ResultSet columnNameRS = connection.ExecSQL("select a.attname FROM pg_attribute a, pg_class c WHERE (a.attnum = " + columnOrdinals[i] + ") AND (a.attrelid = " + r.getInt(8) + ")");
columnNameRS.next();
tuple[8] = columnNameRS.getBytes(1);
tuple[9] = null; // sort sequence ???
tuple[10] = r.getBytes(7); // inexact
tuple[11] = r.getBytes(8);
tuple[12] = null;
v.addElement(tuple);
}
}
return new ResultSet(connection, f, v, "OK", 1); return new ResultSet(connection, f, v, "OK", 1);
} }
} }
......
...@@ -1688,16 +1688,16 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData ...@@ -1688,16 +1688,16 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
String relKind; String relKind;
switch (r.getBytes(3)[0]) { switch (r.getBytes(3)[0]) {
case 'r': case (byte) 'r':
relKind = "TABLE"; relKind = "TABLE";
break; break;
case 'i': case (byte) 'i':
relKind = "INDEX"; relKind = "INDEX";
break; break;
case 'S': case (byte) 'S':
relKind = "SEQUENCE"; relKind = "SEQUENCE";
break; break;
case 'v': case (byte) 'v':
relKind = "VIEW"; relKind = "VIEW";
break; break;
default: default:
...@@ -2622,11 +2622,10 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData ...@@ -2622,11 +2622,10 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
* @return ResultSet each row is an index column description * @return ResultSet each row is an index column description
*/ */
// Implementation note: This is required for Borland's JBuilder to work // Implementation note: This is required for Borland's JBuilder to work
public java.sql.ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate) throws SQLException public java.sql.ResultSet getIndexInfo(String catalog, String schema, String tableName, boolean unique, boolean approximate) throws SQLException
{ {
// for now, this returns an empty result set.
Field f[] = new Field[13]; Field f[] = new Field[13];
ResultSet r; // ResultSet for the SQL query that we need to do java.sql.ResultSet r; // ResultSet for the SQL query that we need to do
Vector v = new Vector(); // The new ResultSet tuple stuff Vector v = new Vector(); // The new ResultSet tuple stuff
f[0] = new Field(connection, "TABLE_CAT", iVarcharOid, 32); f[0] = new Field(connection, "TABLE_CAT", iVarcharOid, 32);
...@@ -2643,6 +2642,59 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData ...@@ -2643,6 +2642,59 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
f[11] = new Field(connection, "PAGES", iInt4Oid, 4); f[11] = new Field(connection, "PAGES", iInt4Oid, 4);
f[12] = new Field(connection, "FILTER_CONDITION", iVarcharOid, 32); f[12] = new Field(connection, "FILTER_CONDITION", iVarcharOid, 32);
r = connection.ExecSQL("select " +
"c.relname, " +
"x.indisunique, " +
"i.relname, " +
"x.indisclustered, " +
"a.amname, " +
"x.indkey, " +
"c.reltuples, " +
"c.relpages " +
"FROM pg_index x, pg_class c, pg_class i, pg_am a " +
"WHERE ((c.relname = '" + tableName.toLowerCase() + "') " +
" AND (c.oid = x.indrelid) " +
" AND (i.oid = x.indexrelid) " +
" AND (c.relam = a.oid)) " +
"ORDER BY x.indisunique DESC, " +
" x.indisclustered, a.amname, i.relname");
while (r.next()) {
// indkey is an array of column ordinals (integers). In the JDBC
// interface, this has to be separated out into a separate
// tuple for each indexed column. Also, getArray() is not yet
// implemented for Postgres JDBC, so we parse by hand.
String columnOrdinalString = r.getString(6);
StringTokenizer stok = new StringTokenizer(columnOrdinalString);
int [] columnOrdinals = new int[stok.countTokens()];
int o = 0;
while (stok.hasMoreTokens()) {
columnOrdinals[o++] = Integer.parseInt(stok.nextToken());
}
for (int i = 0; i < columnOrdinals.length; i++) {
byte [] [] tuple = new byte [13] [];
tuple[0] = "".getBytes();
tuple[1] = "".getBytes();
tuple[2] = r.getBytes(1);
tuple[3] = r.getBoolean(2) ? "f".getBytes() : "t".getBytes();
tuple[4] = null;
tuple[5] = r.getBytes(3);
tuple[6] = r.getBoolean(4) ?
Integer.toString(tableIndexClustered).getBytes() :
r.getString(5).equals("hash") ?
Integer.toString(tableIndexHashed).getBytes() :
Integer.toString(tableIndexOther).getBytes();
tuple[7] = Integer.toString(i + 1).getBytes();
java.sql.ResultSet columnNameRS = connection.ExecSQL("select a.attname FROM pg_attribute a, pg_class c WHERE (a.attnum = " + columnOrdinals[i] + ") AND (a.attrelid = " + r.getInt(8) + ")");
columnNameRS.next();
tuple[8] = columnNameRS.getBytes(1);
tuple[9] = null; // sort sequence ???
tuple[10] = r.getBytes(7); // inexact
tuple[11] = r.getBytes(8);
tuple[12] = null;
v.addElement(tuple);
}
}
return new ResultSet(connection, f, v, "OK", 1); return new ResultSet(connection, f, v, "OK", 1);
} }
......
...@@ -2009,7 +2009,9 @@ SQLStatistics( ...@@ -2009,7 +2009,9 @@ SQLStatistics(
char *table_name; char *table_name;
char index_name[MAX_INFO_STRING]; char index_name[MAX_INFO_STRING];
short fields_vector[16]; short fields_vector[16];
char isunique[10]; char isunique[10],
isclustered[10],
ishash[MAX_INFO_STRING];
SDWORD index_name_len, SDWORD index_name_len,
fields_vector_len; fields_vector_len;
TupleNode *row; TupleNode *row;
...@@ -2169,10 +2171,13 @@ SQLStatistics( ...@@ -2169,10 +2171,13 @@ SQLStatistics(
indx_stmt = (StatementClass *) hindx_stmt; indx_stmt = (StatementClass *) hindx_stmt;
sprintf(index_query, "select c.relname, i.indkey, i.indisunique" sprintf(index_query, "select c.relname, i.indkey, i.indisunique"
", c.relhasrules" ", x.indisclustered, a.amname, i.relhasrules"
" from pg_index i, pg_class c, pg_class d" " from pg_index x, pg_class i, pg_class c, pg_am a"
" where c.oid = i.indexrelid and d.relname = '%s'" " where c.relname = '%s'"
" and d.oid = i.indrelid", table_name); " and c.oid = x.indrelid"
" and x.indexrelid = i.oid"
" and i.relam = a.oid"
, table_name);
result = SQLExecDirect(hindx_stmt, index_query, strlen(index_query)); result = SQLExecDirect(hindx_stmt, index_query, strlen(index_query));
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
...@@ -2224,7 +2229,33 @@ SQLStatistics( ...@@ -2224,7 +2229,33 @@ SQLStatistics(
goto SEEYA; goto SEEYA;
} }
/* bind the "is clustered" column */
result = SQLBindCol(hindx_stmt, 4, SQL_C_CHAR, result = SQLBindCol(hindx_stmt, 4, SQL_C_CHAR,
isclustered, sizeof(isclustered), NULL);
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
{
stmt->errormsg = indx_stmt->errormsg; /* "Couldn't bind column
* in SQLStatistics."; */
stmt->errornumber = indx_stmt->errornumber;
SQLFreeStmt(hindx_stmt, SQL_DROP);
goto SEEYA;
}
/* bind the "is hash" column */
result = SQLBindCol(hindx_stmt, 5, SQL_C_CHAR,
ishash, sizeof(ishash), NULL);
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
{
stmt->errormsg = indx_stmt->errormsg; /* "Couldn't bind column
* in SQLStatistics."; */
stmt->errornumber = indx_stmt->errornumber;
SQLFreeStmt(hindx_stmt, SQL_DROP);
goto SEEYA;
}
result = SQLBindCol(hindx_stmt, 6, SQL_C_CHAR,
relhasrules, MAX_INFO_STRING, NULL); relhasrules, MAX_INFO_STRING, NULL);
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
{ {
...@@ -2255,6 +2286,9 @@ SQLStatistics( ...@@ -2255,6 +2286,9 @@ SQLStatistics(
sprintf(buf, "%s_idx_fake_oid", table_name); sprintf(buf, "%s_idx_fake_oid", table_name);
set_tuplefield_string(&row->tuple[5], buf); set_tuplefield_string(&row->tuple[5], buf);
/*
* Clustered/HASH index?
*/
set_tuplefield_int2(&row->tuple[6], (Int2) SQL_INDEX_OTHER); set_tuplefield_int2(&row->tuple[6], (Int2) SQL_INDEX_OTHER);
set_tuplefield_int2(&row->tuple[7], (Int2) 1); set_tuplefield_int2(&row->tuple[7], (Int2) 1);
...@@ -2297,7 +2331,12 @@ SQLStatistics( ...@@ -2297,7 +2331,12 @@ SQLStatistics(
set_tuplefield_string(&row->tuple[4], ""); set_tuplefield_string(&row->tuple[4], "");
set_tuplefield_string(&row->tuple[5], index_name); set_tuplefield_string(&row->tuple[5], index_name);
set_tuplefield_int2(&row->tuple[6], (Int2) SQL_INDEX_OTHER); /*
* Clustered/HASH index?
*/
set_tuplefield_int2(&row->tuple[6], (Int2)
(atoi(isclustered) ? SQL_INDEX_CLUSTERED :
(!strncmp(ishash, "hash", 4)) ? SQL_INDEX_HASHED : SQL_INDEX_OTHER);
set_tuplefield_int2(&row->tuple[7], (Int2) (i + 1)); set_tuplefield_int2(&row->tuple[7], (Int2) (i + 1));
if (fields_vector[i] == OID_ATTNUM) if (fields_vector[i] == OID_ATTNUM)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment