2828#include < QCustomEvent>
2929#include < QTextOStream>
3030#include < QRegExp>
31+ #include < QMap>
3132
3233// for ntohl
3334#ifdef WIN32
@@ -1387,6 +1388,11 @@ void QgsPostgresProvider::findColumns(tableCols& cols)
13871388 typedef std::map<QString, TT> columnRelationsType;
13881389 columnRelationsType columnRelations;
13891390
1391+ // A structure to cache the query results that return the view
1392+ // definition.
1393+ typedef QMap<QString, QString> viewDefCache;
1394+ viewDefCache viewDefs;
1395+
13901396 PGresult* result = PQexec (connection, (const char *)(sql.utf8 ()));
13911397 // Store the results of the query for convenient access
13921398 for (int i = 0 ; i < PQntuples (result); ++i)
@@ -1407,50 +1413,57 @@ void QgsPostgresProvider::findColumns(tableCols& cols)
14071413 // using 'AS'. To fix this we need to look in the view definition and
14081414 // adjust the view column name if necessary.
14091415
1410- QString view = " SELECT definition FROM pg_views WHERE schemaname = '" + temp.view_schema + " ' AND "
1411- " viewname = '" + temp.view_name + " '" ;
1416+ QString viewQuery = " SELECT definition FROM pg_views "
1417+ " WHERE schemaname = '" + temp.view_schema + " ' AND "
1418+ " viewname = '" + temp.view_name + " '" ;
1419+
1420+ // Maintain a cache of the above SQL.
1421+ QString viewDef;
1422+ if (!viewDefs.contains (viewQuery))
1423+ {
1424+ PGresult* r = PQexec (connection, (const char *)(viewQuery.utf8 ()));
1425+ if (PQntuples (r) > 0 )
1426+ viewDef = PQgetvalue (r, 0 , 0 );
1427+ else
1428+ QgsDebugMsg (" Failed to get view definition for " + temp.view_schema + " ." + temp.view_name );
1429+ viewDefs[viewQuery] = viewDef;
1430+ }
1431+
1432+ viewDef = viewDefs.value (viewQuery);
1433+
1434+ // Now pick the view definiton apart, looking for
1435+ // temp.column_name to the left of an 'AS'.
14121436
1413- PGresult* r = PQexec (connection, (const char *)(view.utf8 ()));
1414- if (PQntuples (r) > 0 )
1437+ // This regular expression needs more testing. Since the view
1438+ // definition comes from postgresql and has been 'standardised', we
1439+ // don't need to deal with everything that the user could put in a view
1440+ // definition. Does the regexp have to deal with the schema??
1441+ if (!viewDef.isEmpty ())
14151442 {
1416- QString viewDef = PQgetvalue (r, 0 , 0 );
1417- // Now pick the view definiton apart, looking for
1418- // temp.column_name to the left of an 'AS'.
1419-
1420- // This regular expression needs more work and testing. Since the view
1421- // definition comes from postgresql and has been 'standardised', we
1422- // don't need to deal with everything that the user could put in a view
1423- // definition. Possible variations could include:
1424- // - lowercase AS
1425- // - quotes around table and column names
1426- // - inclusion of the scheam
1427- // - meaningful characters in the schema/table/column names (such as . ' " )
1428- // - anything else???
1429- QRegExp s (" .* " + temp.table_name + " \\ ." + temp.column_name + " AS (\\ w+),* .*" );
1443+ QRegExp s (" .* \" ?" + QRegExp::escape (temp.table_name ) +
1444+ " \" ?\\ .\" ?" + QRegExp::escape (temp.column_name ) +
1445+ " \" ? AS \" ?(\\ w+)\" ?,* .*" );
14301446
14311447#ifdef QGSIDEBUG
1432- std::cerr <<__FILE__<<__LINE__ << ' ' << view .toLocal8Bit ().data () << ' \n '
1433- << viewDef.toLocal8Bit ().data () << ' \n '
1434- << s.pattern ().toLocal8Bit ().data () << ' \n ' ;
1448+ std::cerr <<__FILE__<<__LINE__ << ' ' << viewQuery .toLocal8Bit ().data () << ' \n '
1449+ << viewDef.toLocal8Bit ().data () << ' \n '
1450+ << s.pattern ().toLocal8Bit ().data () << ' \n ' ;
14351451#endif
14361452
14371453 if (s.indexIn (viewDef) != -1 )
1438- {
1439- temp.view_column_name = s.cap (1 );
1440- // std::cerr<<__FILE__<<__LINE__<<' '<<temp.view_column_name.toLocal8Bit().data()<<'\n';
1441- }
1454+ {
1455+ temp.view_column_name = s.cap (1 );
1456+ // std::cerr<<__FILE__<<__LINE__<<' '<<temp.view_column_name.toLocal8Bit().data()<<'\n';
1457+ }
14421458 }
1443- else
1444- QgsDebugMsg (" Failed to get view definition for " + temp.view_schema + " ." + temp.view_name );
1445-
14461459
14471460 QgsDebugMsg (temp.view_schema + " ."
1448- + temp.view_name + " ."
1449- + temp.view_column_name + " <- "
1450- + temp.table_schema + " ."
1451- + temp.table_name + " ."
1452- + temp.column_name + " is a '"
1453- + temp.table_type + " ' of type "
1461+ + temp.view_name + " ."
1462+ + temp.view_column_name + " <- "
1463+ + temp.table_schema + " ."
1464+ + temp.table_name + " ."
1465+ + temp.column_name + " is a '"
1466+ + temp.table_type + " ' of type "
14541467 + temp.column_type );
14551468
14561469 columnRelations[temp.view_schema + ' .' +
0 commit comments