Marek,
did a simple patch. Can you tell me if it resolves your issue?
function TZPostgreSQLDatabaseMetadata.UncachedGetColumns(const Catalog: string;
const SchemaPattern: string; const TableNamePattern: string;
const ColumnNamePattern: string): IZResultSet;
const
nspname_index = {$IFDEF GENERIC_INDEX}0{$ELSE}1{$ENDIF};
relname_index = {$IFDEF GENERIC_INDEX}1{$ELSE}2{$ENDIF};
attname_index = {$IFDEF GENERIC_INDEX}2{$ELSE}3{$ENDIF};
atttypid_index = {$IFDEF GENERIC_INDEX}3{$ELSE}4{$ENDIF};
attnotnull_index = {$IFDEF GENERIC_INDEX}4{$ELSE}5{$ENDIF};
atttypmod_index = {$IFDEF GENERIC_INDEX}5{$ELSE}6{$ENDIF};
attlen_index = {$IFDEF GENERIC_INDEX}6{$ELSE}7{$ENDIF};
attnum_index = {$IFDEF GENERIC_INDEX}7{$ELSE}8{$ENDIF};
adsrc_index = {$IFDEF GENERIC_INDEX}8{$ELSE}9{$ENDIF};
description_index = {$IFDEF GENERIC_INDEX}9{$ELSE}10{$ENDIF};
var
TypeOid, AttTypMod: Integer;
SQL, PgType: string;
SQLType: TZSQLType;
CheckVisibility: Boolean;
ColumnNameCondition, TableNameCondition, SchemaCondition: string;
label CheckColumnsAgain;
begin
CheckVisibility := False;
SchemaCondition := ConstructNameCondition(SchemaPattern,'n.nspname');
TableNameCondition := ConstructNameCondition(TableNamePattern,'c.relname');
ColumnNameCondition := ConstructNameCondition(ColumnNamePattern,'a.attname');
Result:=inherited UncachedGetColumns(Catalog, SchemaPattern, TableNamePattern, ColumnNamePattern);
if (GetDatabaseInfo as IZPostgreDBInfo).HasMinimumServerVersion(7, 3) then
begin
CheckColumnsAgain: //
http://zeoslib.sourceforge.net/viewtopi ... 40&t=11174
SQL := 'SELECT n.nspname,' {nspname_index}
+ 'c.relname,' {relname_index}
+ 'a.attname,' {attname_index}
+ 'a.atttypid,' {atttypid_index}
+ 'a.attnotnull,' {attnotnull_index}
+ 'a.atttypmod,' {atttypmod_index}
+ 'a.attlen,' {attlen_index}
+ 'a.attnum,' {attnum_index}
+ 'pg_get_expr(def.adbin, def.adrelid) as adsrc,' {adsrc_index}
+ 'dsc.description ' {description_index}
+ ' FROM pg_catalog.pg_namespace n '
+ ' JOIN pg_catalog.pg_class c ON (c.relnamespace = n.oid) '
+ ' JOIN pg_catalog.pg_attribute a ON (a.attrelid=c.oid) '
+ ' LEFT JOIN pg_catalog.pg_attrdef def ON (a.attrelid=def.adrelid'
+ ' AND a.attnum = def.adnum) LEFT JOIN pg_catalog.pg_description dsc'
+ ' ON (c.oid=dsc.objoid AND a.attnum = dsc.objsubid) '
+ ' LEFT JOIN pg_catalog.pg_class dc ON (dc.oid=dsc.classoid'
+ ' AND dc.relname=''pg_class'') LEFT JOIN pg_catalog.pg_namespace dn'
+ ' ON (dc.relnamespace=dn.oid AND dn.nspname=''pg_catalog'') '
+ ' WHERE a.attnum > 0 AND NOT a.attisdropped';
if SchemaPattern <> '' then
SQL := SQL + ' AND ' + SchemaCondition
else
//not by default: because of Speed decrease:
http://http://zeoslib.sourceforge.net/v ... 46&sid=130
if CheckVisibility then
SQL := SQL + ' AND pg_table_is_visible (c.oid) ';
end
else
begin
SQL := 'SELECT NULL::text AS nspname,' {nspname_index}
+ 'c.relname,' {relname_index}
+ 'a.attname,' {attname_index}
+ 'a.atttypid,' {atttypid_index}
+ 'a.attnotnull,' {attnotnull_index}
+ 'a.atttypmod,' {atttypmod_index}
+ 'a.attlen,' {attlen_index}
+ 'a.attnum,' {attnum_index}
+ 'NULL AS adsrc,' {adsrc_index}
+ 'NULL AS description' {description_index}
+ 'FROM pg_class c, pg_attribute a '
+ ' WHERE a.attrelid=c.oid AND a.attnum > 0 ';
end;
If TableNameCondition <> '' then
SQL := SQL + ' AND ' + TableNameCondition;
If ColumnNameCondition <> '' then
SQL := SQL+ ' AND ' + ColumnNameCondition;
SQL := SQL+ ' ORDER BY nspname,relname,attnum';
with GetConnection.CreateStatement.ExecuteQuery(SQL) do
begin
if Next then
repeat
AttTypMod := GetInt(atttypmod_index);
TypeOid := GetInt(atttypid_index);
PgType := GetPostgreSQLType(TypeOid);
Result.MoveToInsertRow;
//Result.UpdateNull(CatalogNameIndex);
Result.UpdateAnsiRec(SchemaNameIndex, GetAnsiRec(nspname_index));
Result.UpdateAnsiRec(TableNameIndex, GetAnsiRec(relname_index));
Result.UpdateAnsiRec(ColumnNameIndex, GetAnsiRec(attname_index));
SQLType := GetSQLTypeByOid(TypeOid);
Result.UpdateInt(TableColColumnTypeIndex, Ord(SQLType));
Result.UpdateString(TableColColumnTypeNameIndex, PgType);
Result.UpdateInt(TableColColumnBufLengthIndex, 0);
if (PgType = 'bpchar') or (PgType = 'varchar') or (PgType = 'enum') then
begin
if AttTypMod <> -1 then
Result.UpdateInt(TableColColumnSizeIndex, GetFieldSize(SQLType, ConSettings, (AttTypMod - 4),
ConSettings.ClientCodePage.CharWidth))
else
if (PgType = 'varchar') then
if ( (GetConnection as IZPostgreSQLConnection).GetUndefinedVarcharAsStringLength = 0 ) then
begin
Result.UpdateInt(TableColColumnTypeIndex, Ord(GetSQLTypeByOid(25))); //Assume text-lob instead
Result.UpdateInt(TableColColumnSizeIndex, 0); // need no size for streams
end
else //keep the string type but with user defined count of chars
Result.UpdateInt(TableColColumnSizeIndex, (GetConnection as IZPostgreSQLConnection).GetUndefinedVarcharAsStringLength )
else
Result.UpdateInt(TableColColumnSizeIndex, 0);
end
else if (PgType = 'numeric') or (PgType = 'decimal') then
begin
Result.UpdateInt(TableColColumnSizeIndex, ((AttTypMod - 4) div 65536)); //precision
Result.UpdateInt(TableColColumnDecimalDigitsIndex, ((AttTypMod -4) mod 65536)); //scale
Result.UpdateInt(TableColColumnNumPrecRadixIndex, 10); //base? ten as default
end
else if (PgType = 'bit') or (PgType = 'varbit') then
begin
Result.UpdateInt(TableColColumnSizeIndex, AttTypMod);
Result.UpdateInt(TableColColumnNumPrecRadixIndex, 2);
end
else
begin
Result.UpdateInt(TableColColumnSizeIndex, GetInt(attlen_index));
Result.UpdateInt(TableColColumnNumPrecRadixIndex, 2);
end;
//Result.UpdateNull(TableColColumnBufLengthIndex);
if GetBoolean(attnotnull_index) then
begin
Result.UpdateString(TableColColumnIsNullableIndex, 'NO');
Result.UpdateInt(TableColColumnNullableIndex, Ord(ntNoNulls));
end
else
begin
Result.UpdateString(TableColColumnIsNullableIndex, 'YES');
Result.UpdateInt(TableColColumnNullableIndex, Ord(ntNullable));
end;
Result.UpdateAnsiRec(TableColColumnRemarksIndex, GetAnsiRec(description_index {description}));
Result.UpdateAnsiRec(TableColColumnColDefIndex, GetAnsiRec(adsrc_index {adsrc}));
//Result.UpdateNull(TableColColumnSQLDataTypeIndex);
//Result.UpdateNull(TableColColumnSQLDateTimeSubIndex);
Result.UpdateInt(TableColColumnCharOctetLengthIndex, Result.GetInt(attlen_index));
Result.UpdateInt(TableColColumnOrdPosIndex, GetInt(attnum_index));
//Result.UpdateNull(TableColColumnAutoIncIndex);
Result.UpdateBoolean(TableColColumnCaseSensitiveIndex, IC.IsCaseSensitive(GetString(attname_index)));
Result.UpdateBoolean(TableColColumnSearchableIndex, True);
Result.UpdateBoolean(TableColColumnWritableIndex, True);
Result.UpdateBoolean(TableColColumnDefinitelyWritableIndex, True);
Result.UpdateBoolean(TableColColumnReadonlyIndex, False);
Result.InsertRow;
until not Next
else //nothing found let's repeat with checking temporary session depended table too.
// notes
http://zeoslib.sourceforge.net/viewtopi ... 40&t=11174
if (not CheckVisibility) and (SchemaPattern = '') and (GetDatabaseInfo as IZPostgreDBInfo).HasMinimumServerVersion(7, 3) then
begin
CheckVisibility := True;
Close; //clean up
goto CheckColumnsAgain; //Lest's start the second approach
end;
Close;
end;
end;