@@ -718,6 +718,7 @@ bool QgsPostgresProvider::loadFields()
718718
719719 QMap<int , QMap<int , QString> > fmtFieldTypeMap, descrMap, defValMap;
720720 QMap<int , QMap<int , int > > attTypeIdMap;
721+ QMap<int , QMap<int , bool > > notNullMap, uniqueMap;
721722 if ( result.PQnfields () > 0 )
722723 {
723724 // Collect table oids
@@ -742,9 +743,13 @@ bool QgsPostgresProvider::loadFields()
742743 QString tableoidsFilter = ' (' + tableoidsList.join ( QStringLiteral ( " ," ) ) + ' )' ;
743744
744745 // Collect formatted field types
745- sql = " SELECT attrelid, attnum, pg_catalog.format_type(atttypid,atttypmod), pg_catalog.col_description(attrelid,attnum), pg_catalog.pg_get_expr(adbin,adrelid), atttypid"
746+ sql = " SELECT attrelid, attnum, pg_catalog.format_type(atttypid,atttypmod), pg_catalog.col_description(attrelid,attnum), pg_catalog.pg_get_expr(adbin,adrelid), atttypid, attnotnull::int, indisunique::int "
746747 " FROM pg_attribute"
747748 " LEFT OUTER JOIN pg_attrdef ON attrelid=adrelid AND attnum=adnum"
749+
750+ // find unique constraints if present. Text cast required to handle int2vector comparison. Distinct required as multiple unique constraints may exist
751+ " LEFT OUTER JOIN ( SELECT DISTINCT indrelid, indkey, indisunique FROM pg_index WHERE indisunique ) uniq ON attrelid=indrelid AND attnum::text=indkey::text "
752+
748753 " WHERE attrelid IN " + tableoidsFilter;
749754 QgsPostgresResult fmtFieldTypeResult ( connectionRO ()->PQexec ( sql ) );
750755 for ( int i = 0 ; i < fmtFieldTypeResult.PQntuples (); ++i )
@@ -755,10 +760,14 @@ bool QgsPostgresProvider::loadFields()
755760 QString descr = fmtFieldTypeResult.PQgetvalue ( i, 3 );
756761 QString defVal = fmtFieldTypeResult.PQgetvalue ( i, 4 );
757762 int attType = fmtFieldTypeResult.PQgetvalue ( i, 5 ).toInt ();
763+ bool attNotNull = fmtFieldTypeResult.PQgetvalue ( i, 6 ).toInt ();
764+ bool uniqueConstraint = fmtFieldTypeResult.PQgetvalue ( i, 7 ).toInt ();
758765 fmtFieldTypeMap[attrelid][attnum] = formatType;
759766 descrMap[attrelid][attnum] = descr;
760767 defValMap[attrelid][attnum] = defVal;
761768 attTypeIdMap[attrelid][attnum] = attType;
769+ notNullMap[attrelid][attnum] = attNotNull;
770+ uniqueMap[attrelid][attnum] = uniqueConstraint;
762771 }
763772 }
764773 }
@@ -988,6 +997,14 @@ bool QgsPostgresProvider::loadFields()
988997
989998 mAttrPalIndexName .insert ( i, fieldName );
990999 mDefaultValues .insert ( mAttributeFields .size (), defValMap[tableoid][attnum] );
1000+
1001+ Constraints constraints = 0 ;
1002+ if ( notNullMap[tableoid][attnum] )
1003+ constraints |= ConstraintNotNull;
1004+ if ( uniqueMap[tableoid][attnum] )
1005+ constraints |= ConstraintUnique;
1006+ mFieldConstraints .insert ( mAttributeFields .size (), constraints );
1007+
9911008 mAttributeFields .append ( QgsField ( fieldName, fieldType, fieldTypeName, fieldSize, fieldPrec, fieldComment, fieldSubType ) );
9921009 }
9931010
@@ -1719,6 +1736,11 @@ QVariant QgsPostgresProvider::defaultValue( int fieldId ) const
17191736 return defVal;
17201737}
17211738
1739+ QgsVectorDataProvider::Constraints QgsPostgresProvider::fieldConstraints ( int fieldIndex ) const
1740+ {
1741+ return mFieldConstraints .value ( fieldIndex, 0 );
1742+ }
1743+
17221744QString QgsPostgresProvider::paramValue ( const QString& fieldValue, const QString &defaultValue ) const
17231745{
17241746 if ( fieldValue.isNull () )
0 commit comments