Fix for HASH for index lookups in ODBC.

This commit is contained in:
Bruce Momjian 2001-05-16 17:47:27 +00:00
parent 014f98dd36
commit 5abaa779c4
3 changed files with 164 additions and 20 deletions
src/interfaces
jdbc/org/postgresql
odbc

@ -1688,16 +1688,16 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
String relKind;
switch (r.getBytes(3)[0]) {
case 'r':
case (byte) 'r':
relKind = "TABLE";
break;
case 'i':
case (byte) 'i':
relKind = "INDEX";
break;
case 'S':
case (byte) 'S':
relKind = "SEQUENCE";
break;
case 'v':
case (byte) 'v':
relKind = "VIEW";
break;
default:
@ -2623,11 +2623,10 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
* @return ResultSet each row is an index column description
*/
// 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];
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
f[0] = new Field(connection, "TABLE_CAT", iVarcharOid, 32);
@ -2644,6 +2643,60 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
f[11] = new Field(connection, "PAGES", iInt4Oid, 4);
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);
}
}

@ -1688,16 +1688,16 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
String relKind;
switch (r.getBytes(3)[0]) {
case 'r':
case (byte) 'r':
relKind = "TABLE";
break;
case 'i':
case (byte) 'i':
relKind = "INDEX";
break;
case 'S':
case (byte) 'S':
relKind = "SEQUENCE";
break;
case 'v':
case (byte) 'v':
relKind = "VIEW";
break;
default:
@ -2622,11 +2622,10 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
* @return ResultSet each row is an index column description
*/
// 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];
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
f[0] = new Field(connection, "TABLE_CAT", iVarcharOid, 32);
@ -2643,6 +2642,59 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
f[11] = new Field(connection, "PAGES", iInt4Oid, 4);
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);
}

@ -2009,7 +2009,9 @@ SQLStatistics(
char *table_name;
char index_name[MAX_INFO_STRING];
short fields_vector[16];
char isunique[10];
char isunique[10],
isclustered[10],
ishash[MAX_INFO_STRING];
SDWORD index_name_len,
fields_vector_len;
TupleNode *row;
@ -2169,10 +2171,13 @@ SQLStatistics(
indx_stmt = (StatementClass *) hindx_stmt;
sprintf(index_query, "select c.relname, i.indkey, i.indisunique"
", c.relhasrules"
" from pg_index i, pg_class c, pg_class d"
" where c.oid = i.indexrelid and d.relname = '%s'"
" and d.oid = i.indrelid", table_name);
", x.indisclustered, a.amname, i.relhasrules"
" from pg_index x, pg_class i, pg_class c, pg_am a"
" where c.relname = '%s'"
" 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));
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
@ -2224,7 +2229,33 @@ SQLStatistics(
goto SEEYA;
}
/* bind the "is clustered" column */
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);
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
{
@ -2255,6 +2286,9 @@ SQLStatistics(
sprintf(buf, "%s_idx_fake_oid", table_name);
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[7], (Int2) 1);
@ -2297,7 +2331,12 @@ SQLStatistics(
set_tuplefield_string(&row->tuple[4], "");
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));
if (fields_vector[i] == OID_ATTNUM)