1
package org.postgresql.jdbc1;
4
import org.postgresql.core.Field;
5
import org.postgresql.util.PSQLException;
6
import org.postgresql.util.PSQLState;
7
import java.sql.SQLException;
9
import java.util.Vector;
11
public abstract class AbstractJdbc1ResultSetMetaData
14
protected Vector rows;
15
protected Field[] fields;
18
* Initialise for a result with a tuple set and
19
* a field descriptor set
21
* @param rows the Vector of rows returned by the ResultSet
22
* @param fields the array of field descriptors
24
public AbstractJdbc1ResultSetMetaData(Vector rows, Field[] fields)
31
* Whats the number of columns in the ResultSet?
34
* @exception SQLException if a database access error occurs
36
public int getColumnCount() throws SQLException
42
* Is the column automatically numbered (and thus read-only)
43
* I believe that PostgreSQL does not support this feature.
45
* @param column the first column is 1, the second is 2...
47
* @exception SQLException if a database access error occurs
49
public boolean isAutoIncrement(int column) throws SQLException
55
* Does a column's case matter? ASSUMPTION: Any field that is
56
* not obviously case insensitive is assumed to be case sensitive
58
* @param column the first column is 1, the second is 2...
60
* @exception SQLException if a database access error occurs
62
public boolean isCaseSensitive(int column) throws SQLException
64
int sql_type = getField(column).getSQLType();
83
* Can the column be used in a WHERE clause? Basically for
84
* this, I split the functions into two types: recognised
85
* types (which are always useable), and OTHER types (which
86
* may or may not be useable). The OTHER types, for now, I
87
* will assume they are useable. We should really query the
88
* catalog to see if they are useable.
90
* @param column the first column is 1, the second is 2...
91
* @return true if they can be used in a WHERE clause
92
* @exception SQLException if a database access error occurs
94
public boolean isSearchable(int column) throws SQLException
96
int sql_type = getField(column).getSQLType();
98
// This switch is pointless, I know - but it is a set-up
99
// for further expansion.
110
* Is the column a cash value? 6.1 introduced the cash/money
111
* type, which haven't been incorporated as of 970414, so I
112
* just check the type name for both 'cash' and 'money'
114
* @param column the first column is 1, the second is 2...
115
* @return true if its a cash column
116
* @exception SQLException if a database access error occurs
118
public boolean isCurrency(int column) throws SQLException
120
String type_name = getField(column).getPGType();
122
return type_name.equals("cash") || type_name.equals("money");
126
* Indicates the nullability of values in the designated column.
128
* @param column the first column is 1, the second is 2...
129
* @return one of the columnNullable values
130
* @exception SQLException if a database access error occurs
132
public int isNullable(int column) throws SQLException
135
* TODO This needs a real implementation, taking into account columns
136
* defined with NOT NULL or PRIMARY KEY, CHECK constraints, views,
139
return java.sql.ResultSetMetaData.columnNullableUnknown;
143
* Is the column a signed number? In PostgreSQL, all numbers
144
* are signed, so this is trivial. However, strings are not
147
* @param column the first column is 1, the second is 2...
149
* @exception SQLException if a database access error occurs
151
public boolean isSigned(int column) throws SQLException
153
int sql_type = getField(column).getSQLType();
165
case Types.TIMESTAMP:
166
return false; // I don't know about these?
173
* What is the column's normal maximum width in characters?
175
* @param column the first column is 1, the second is 2, etc.
176
* @return the maximum width
177
* @exception SQLException if a database access error occurs
179
public int getColumnDisplaySize(int column) throws SQLException
181
Field f = getField(column);
182
String type_name = f.getPGType();
183
int typmod = f.getMod();
185
// I looked at other JDBC implementations and couldn't find a consistent
186
// interpretation of the "display size" for numeric values, so this is our's
187
// FIXME: currently, only types with a SQL92 or SQL3 pendant are implemented - jens@jens.de
189
// fixed length data types
190
if (type_name.equals( "int2" ))
191
return 6; // -32768 to +32768 (5 digits and a sign)
192
if (type_name.equals( "int4" )
193
|| type_name.equals( "oid" ))
194
return 11; // -2147483648 to +2147483647
195
if (type_name.equals( "int8" ))
196
return 20; // -9223372036854775808 to +9223372036854775807
197
if (type_name.equals( "money" ))
198
return 12; // MONEY = DECIMAL(9,2)
199
if (type_name.equals( "float4" ))
200
return 11; // i checked it out ans wasn't able to produce more than 11 digits
201
if (type_name.equals( "float8" ))
202
return 20; // dito, 20
203
if (type_name.equals( "char" ))
205
if (type_name.equals( "bool" ))
207
if (type_name.equals( "date" ))
208
return 14; // "01/01/4713 BC" - "31/12/32767 AD"
209
if (type_name.equals( "time" ))
210
return 8; // 00:00:00-23:59:59
211
if (type_name.equals( "timestamp" ))
212
return 22; // hhmmm ... the output looks like this: 1999-08-03 22:22:08+02
214
// variable length fields
216
if (type_name.equals( "bpchar" )
217
|| type_name.equals( "varchar" ))
218
return typmod; // VARHDRSZ=sizeof(int32)=4
219
if (type_name.equals( "numeric" ))
220
return ( (typmod >> 16) & 0xffff )
221
+ 1 + ( typmod & 0xffff ); // DECIMAL(p,s) = (p digits).(s digits)
223
// if we don't know better
224
return f.getLength();
228
* What is the suggested column title for use in printouts and
229
* displays? We suggest the ColumnName!
231
* @param column the first column is 1, the second is 2, etc.
232
* @return the column label
233
* @exception SQLException if a database access error occurs
235
public String getColumnLabel(int column) throws SQLException
237
return getColumnName(column);
241
* What's a column's name?
243
* @param column the first column is 1, the second is 2, etc.
244
* @return the column name
245
* @exception SQLException if a database access error occurs
247
public String getColumnName(int column) throws SQLException
249
Field f = getField(column);
252
return "field" + column;
256
* What is a column's table's schema? This relies on us knowing
257
* the table name....which I don't know how to do as yet. The
258
* JDBC specification allows us to return "" if this is not
261
* @param column the first column is 1, the second is 2...
263
* @exception SQLException if a database access error occurs
265
public String getSchemaName(int column) throws SQLException
271
* What is a column's number of decimal digits.
273
* @param column the first column is 1, the second is 2...
274
* @return the precision
275
* @exception SQLException if a database access error occurs
277
public int getPrecision(int column) throws SQLException
279
int sql_type = getField(column).getSQLType();
296
Field f = getField(column);
298
return ((0xFFFF0000)&f.getMod()) >> 16;
307
* What is a column's number of digits to the right of the
310
* @param column the first column is 1, the second is 2...
312
* @exception SQLException if a database access error occurs
314
public int getScale(int column) throws SQLException
316
int sql_type = getField(column).getSQLType();
333
Field f = getField(column);
335
return (((0x0000FFFF)&f.getMod()) - 4);
344
* Whats a column's table's name? How do I find this out? Both
345
* getSchemaName() and getCatalogName() rely on knowing the table
346
* Name, so we need this before we can work on them.
348
* @param column the first column is 1, the second is 2...
349
* @return column name, or "" if not applicable
350
* @exception SQLException if a database access error occurs
352
public String getTableName(int column) throws SQLException
358
* What's a column's table's catalog name? As with getSchemaName(),
359
* we can say that if getTableName() returns n/a, then we can too -
360
* otherwise, we need to work on it.
362
* @param column the first column is 1, the second is 2...
363
* @return catalog name, or "" if not applicable
364
* @exception SQLException if a database access error occurs
366
public String getCatalogName(int column) throws SQLException
372
* What is a column's SQL Type? (java.sql.Type int)
374
* @param column the first column is 1, the second is 2, etc.
375
* @return the java.sql.Type value
376
* @exception SQLException if a database access error occurs
377
* @see org.postgresql.Field#getSQLType
378
* @see java.sql.Types
380
public int getColumnType(int column) throws SQLException
382
return getField(column).getSQLType();
386
* Whats is the column's data source specific type name?
388
* @param column the first column is 1, the second is 2, etc.
389
* @return the type name
390
* @exception SQLException if a database access error occurs
392
public String getColumnTypeName(int column) throws SQLException
394
return getField(column).getPGType();
398
* Is the column definitely not writable? In reality, we would
399
* have to check the GRANT/REVOKE stuff for this to be effective,
400
* and I haven't really looked into that yet, so this will get
403
* @param column the first column is 1, the second is 2, etc.
405
* @exception SQLException if a database access error occurs
407
public boolean isReadOnly(int column) throws SQLException
413
* Is it possible for a write on the column to succeed? Again, we
414
* would in reality have to check the GRANT/REVOKE stuff, which
415
* I haven't worked with as yet. However, if it isn't ReadOnly, then
416
* it is obviously writable.
418
* @param column the first column is 1, the second is 2, etc.
420
* @exception SQLException if a database access error occurs
422
public boolean isWritable(int column) throws SQLException
424
return !isReadOnly(column);
428
* Will a write on this column definately succeed? Hmmm...this
429
* is a bad one, since the two preceding functions have not been
430
* really defined. I cannot tell is the short answer. I thus
431
* return isWritable() just to give us an idea.
433
* @param column the first column is 1, the second is 2, etc..
435
* @exception SQLException if a database access error occurs
437
public boolean isDefinitelyWritable(int column) throws SQLException
442
// ********************************************************
443
// END OF PUBLIC INTERFACE
444
// ********************************************************
447
* For several routines in this package, we need to convert
448
* a columnIndex into a Field[] descriptor. Rather than do
449
* the same code several times, here it is.
451
* @param columnIndex the first column is 1, the second is 2...
452
* @return the Field description
453
* @exception SQLException if a database access error occurs
455
private Field getField(int columnIndex) throws SQLException
457
if (columnIndex < 1 || columnIndex > fields.length)
458
throw new PSQLException("postgresql.res.colrange", PSQLState.INVALID_PARAMETER_VALUE);
459
return fields[columnIndex - 1];