@@ -658,8 +658,64 @@ bool QgsPostgresProvider::loadFields()
658
658
659
659
QSet<QString> fields;
660
660
661
- // The queries inside this loop could possibly be combined into one
662
- // single query - this would make the code run faster.
661
+ /* Collect type info */
662
+ sql = " SELECT oid, typname,typtype,typelem,typlen FROM pg_type" ;
663
+ QgsPostgresResult typeResult = connectionRO ()->PQexec ( sql );
664
+ QMap<int , PGTypeInfo> typeMap;
665
+ for ( int i = 0 ; i < typeResult.PQntuples (); ++i )
666
+ {
667
+ PGTypeInfo typeInfo =
668
+ {
669
+ /* typeName = */ typeResult.PQgetvalue ( i, 1 ),
670
+ /* typeType = */ typeResult.PQgetvalue ( i, 2 ),
671
+ /* typeElem = */ typeResult.PQgetvalue ( i, 3 ),
672
+ /* typeLen = */ typeResult.PQgetvalue ( i, 4 ).toInt ()
673
+ };
674
+ typeMap.insert ( typeResult.PQgetvalue ( i, 0 ).toInt (), typeInfo );
675
+ }
676
+
677
+ /* Collect table oids */
678
+ QSet<int > tableoids;
679
+ for ( int i = 0 ; i < result.PQnfields (); i++ )
680
+ {
681
+ int tableoid = result.PQftable ( i );
682
+ if ( tableoid > 0 )
683
+ {
684
+ tableoids.insert ( tableoid );
685
+ }
686
+ }
687
+ QStringList tableoidsList;
688
+ foreach ( int tableoid, tableoids )
689
+ {
690
+ tableoidsList.append ( QString::number ( tableoid ) );
691
+ }
692
+
693
+ QString tableoidsFilter = " (" + tableoidsList.join ( " ," ) + " )" ;
694
+
695
+ /* Collect formatted field types */
696
+ sql = " SELECT attrelid, attnum, pg_catalog.format_type(atttypid,atttypmod) FROM pg_attribute WHERE attrelid IN " + tableoidsFilter;
697
+ QgsPostgresResult fmtFieldTypeResult = connectionRO ()->PQexec ( sql );
698
+ QMap<int , QMap<int , QString> > fmtFieldTypeMap;
699
+ for ( int i = 0 ; i < fmtFieldTypeResult.PQntuples (); ++i )
700
+ {
701
+ int attrelid = fmtFieldTypeResult.PQgetvalue ( i, 0 ).toInt ();
702
+ int attnum = fmtFieldTypeResult.PQgetvalue ( i, 1 ).toInt ();
703
+ QString formatType = fmtFieldTypeResult.PQgetvalue ( i, 2 );
704
+ fmtFieldTypeMap[attrelid][attnum] = formatType;
705
+ }
706
+
707
+ /* Collect descriptions */
708
+ sql = " SELECT objoid, objsubid, description FROM pg_description WHERE objoid IN " + tableoidsFilter;
709
+ QgsPostgresResult descrResult = connectionRO ()->PQexec ( sql );
710
+ QMap<int , QMap<int , QString> > descrMap;
711
+ for ( int i = 0 ; i < descrResult.PQntuples (); ++i )
712
+ {
713
+ int objoid = descrResult.PQgetvalue ( i, 0 ).toInt ();
714
+ int objsubid = descrResult.PQgetvalue ( i, 1 ).toInt ();
715
+ QString descr = descrResult.PQgetvalue ( i, 2 );
716
+ descrMap[objoid][objsubid] = descr;
717
+ }
718
+
663
719
mAttributeFields .clear ();
664
720
for ( int i = 0 ; i < result.PQnfields (); i++ )
665
721
{
@@ -668,40 +724,17 @@ bool QgsPostgresProvider::loadFields()
668
724
continue ;
669
725
670
726
int fldtyp = result.PQftype ( i );
671
- QString typOid = QString ().setNum ( fldtyp );
672
727
int fieldPrec = -1 ;
673
- QString fieldComment ( " " );
674
728
int tableoid = result.PQftable ( i );
675
729
int attnum = result.PQftablecol ( i );
676
730
677
- sql = QString ( " SELECT typname,typtype,typelem,typlen FROM pg_type WHERE oid=%1" ).arg ( typOid );
678
- // just oid; needs more work to support array type
679
- // "oid = (SELECT Distinct typelem FROM pg_type WHERE " //needs DISTINCT to guard against 2 or more rows on int2
680
- // "typelem = " + typOid + " AND typlen = -1)";
681
-
682
- QgsPostgresResult oidResult = connectionRO ()->PQexec ( sql );
683
- QString fieldTypeName = oidResult.PQgetvalue ( 0 , 0 );
684
- QString fieldTType = oidResult.PQgetvalue ( 0 , 1 );
685
- QString fieldElem = oidResult.PQgetvalue ( 0 , 2 );
686
- int fieldSize = oidResult.PQgetvalue ( 0 , 3 ).toInt ();
687
-
688
- QString formattedFieldType;
689
- if ( tableoid > 0 )
690
- {
691
- sql = QString ( " SELECT pg_catalog.format_type(atttypid,atttypmod) FROM pg_attribute WHERE attrelid=%1 AND attnum=%2" )
692
- .arg ( tableoid ).arg ( quotedValue ( attnum ) );
693
-
694
- QgsPostgresResult tresult = connectionRO ()->PQexec ( sql );
695
- if ( tresult.PQntuples () > 0 )
696
- formattedFieldType = tresult.PQgetvalue ( 0 , 0 );
697
-
698
- sql = QString ( " SELECT description FROM pg_description WHERE objoid=%1 AND objsubid=%2" )
699
- .arg ( tableoid ).arg ( attnum );
731
+ const PGTypeInfo& typeInfo = typeMap.value ( fldtyp );
732
+ QString fieldTypeName = typeInfo.typeName ;
733
+ QString fieldTType = typeInfo.typeType ;
734
+ int fieldSize = typeInfo.typeLen ;
700
735
701
- tresult = connectionRO ()->PQexec ( sql );
702
- if ( tresult.PQntuples () > 0 )
703
- fieldComment = tresult.PQgetvalue ( 0 , 0 );
704
- }
736
+ QString formattedFieldType = fmtFieldTypeMap[tableoid][attnum];
737
+ QString fieldComment = descrMap[tableoid][attnum];
705
738
706
739
QVariant::Type fieldType;
707
740
@@ -1919,6 +1952,7 @@ bool QgsPostgresProvider::addAttributes( const QList<QgsField> &attributes )
1919
1952
{
1920
1953
conn->begin ();
1921
1954
1955
+ QString sql = QString ( " ALTER TABLE %1 " ).arg ( mQuery );
1922
1956
for ( QList<QgsField>::const_iterator iter = attributes.begin (); iter != attributes.end (); ++iter )
1923
1957
{
1924
1958
QString type = iter->typeName ();
@@ -1932,18 +1966,19 @@ bool QgsPostgresProvider::addAttributes( const QList<QgsField> &attributes )
1932
1966
if ( iter->length () > 0 && iter->precision () >= 0 )
1933
1967
type = QString ( " %1(%2,%3)" ).arg ( type ).arg ( iter->length () ).arg ( iter->precision () );
1934
1968
}
1969
+ sql.append ( QString ( " ADD COLUMN %1 %2, " ).arg ( quotedIdentifier ( iter->name () ) ).arg ( type ) );
1970
+ }
1971
+ sql.chop ( 2 ); /* ", " */
1972
+ sql.append ( " ;" );
1973
+ QgsDebugMsg ( sql );
1935
1974
1936
- QString sql = QString ( " ALTER TABLE %1 ADD COLUMN %2 %3" )
1937
- .arg ( mQuery )
1938
- .arg ( quotedIdentifier ( iter->name () ) )
1939
- .arg ( type );
1940
- QgsDebugMsg ( sql );
1941
-
1942
- // send sql statement and do error handling
1943
- QgsPostgresResult result = conn->PQexec ( sql );
1944
- if ( result.PQresultStatus () != PGRES_COMMAND_OK )
1945
- throw PGException ( result );
1975
+ // send sql statement and do error handling
1976
+ QgsPostgresResult result = conn->PQexec ( sql );
1977
+ if ( result.PQresultStatus () != PGRES_COMMAND_OK )
1978
+ throw PGException ( result );
1946
1979
1980
+ for ( QList<QgsField>::const_iterator iter = attributes.begin (); iter != attributes.end (); ++iter )
1981
+ {
1947
1982
if ( !iter->comment ().isEmpty () )
1948
1983
{
1949
1984
sql = QString ( " COMMENT ON COLUMN %1.%2 IS %3" )
0 commit comments