Skip to content
Permalink
Browse files

[OGR] Fix support for Spatialite views

  • Loading branch information
rouault committed Jul 26, 2016
1 parent b39fd15 commit 58ce9c453b67eb2fb73e32dcfb0bb5c025ab0458
@@ -1660,7 +1660,9 @@ static int msOGRFileWhichShapes(layerObj *layer, rectObj rect, msOGRFileInfo *ps
}

char *select = NULL;
char* pszTableName = NULL;
char* pszSpatialFilterTableName = NULL;
char* pszMainTableName = NULL;
char* pszRowId = NULL;
bool bIsOKForSQLCompose = true;

// In the case of a SQLite DB, check that we can identify the
@@ -1685,13 +1687,14 @@ static int msOGRFileWhichShapes(layerObj *layer, rectObj rect, msOGRFileInfo *ps
strstr(pszIter, " order by ") == NULL && strstr(pszIter, " ORDER BY ") == NULL)
{
bIsOKForSQLCompose = true;
pszTableName = msStrdup(pszBeginningOfTable);
pszTableName[pszIter - pszBeginningOfTable] = '\0';
pszMainTableName = msStrdup(pszBeginningOfTable);
pszMainTableName[pszIter - pszBeginningOfTable] = '\0';
pszSpatialFilterTableName = msStrdup(pszMainTableName);

char* pszRequest = NULL;
pszRequest = msStringConcatenate(pszRequest,
"SELECT * FROM sqlite_master WHERE type = 'table' AND name = lower('");
pszRequest = msStringConcatenate(pszRequest, pszTableName);
pszRequest = msStringConcatenate(pszRequest, pszMainTableName);
pszRequest = msStringConcatenate(pszRequest, "')");
OGRLayerH hLayer = OGR_DS_ExecuteSQL( psInfo->hDS, pszRequest, NULL, NULL );
msFree(pszRequest);
@@ -1708,6 +1711,32 @@ static int msOGRFileWhichShapes(layerObj *layer, rectObj rect, msOGRFileInfo *ps
{
select = msStrdup(psInfo->pszLayerDef);
}
else
{
// Test if it is a spatial view
pszRequest = msStringConcatenate(NULL,
"SELECT f_table_name, view_rowid FROM views_geometry_columns WHERE view_name = lower('");
pszRequest = msStringConcatenate(pszRequest, pszMainTableName);
pszRequest = msStringConcatenate(pszRequest, "')");
CPLPushErrorHandler(CPLQuietErrorHandler);
OGRLayerH hLayer = OGR_DS_ExecuteSQL( psInfo->hDS, pszRequest, NULL, NULL );
CPLPopErrorHandler();
msFree(pszRequest);

if( hLayer )
{
OGRFeatureH hFeature = OGR_L_GetNextFeature(hLayer);
bIsOKForSQLCompose = (hFeature != NULL);
if( hFeature )
{
msFree(pszSpatialFilterTableName);
pszSpatialFilterTableName = msStrdup( OGR_F_GetFieldAsString( hFeature, 0 ) );
pszRowId = msStrdup( OGR_F_GetFieldAsString( hFeature, 1 ) );
OGR_F_Destroy(hFeature);
}
OGR_DS_ReleaseResultSet( psInfo->hDS, hLayer );
}
}
}
}
}
@@ -1732,7 +1761,46 @@ static int msOGRFileWhichShapes(layerObj *layer, rectObj rect, msOGRFileInfo *ps
OGR_DS_ReleaseResultSet( psInfo->hDS, hLayer );
}
if( bIsOKForSQLCompose )
pszTableName = msStrdup(OGR_FD_GetName(OGR_L_GetLayerDefn(psInfo->hLayer)));
{
pszMainTableName = msStrdup(OGR_FD_GetName(OGR_L_GetLayerDefn(psInfo->hLayer)));
pszSpatialFilterTableName = msStrdup(pszMainTableName);
}
else
{
// Test if it is a spatial view
pszRequest = msStringConcatenate(NULL,
"SELECT f_table_name, view_rowid FROM views_geometry_columns WHERE view_name = lower('");
pszRequest = msStringConcatenate(pszRequest, OGR_FD_GetName(OGR_L_GetLayerDefn(psInfo->hLayer)));
pszRequest = msStringConcatenate(pszRequest, "')");
CPLPushErrorHandler(CPLQuietErrorHandler);
OGRLayerH hLayer = OGR_DS_ExecuteSQL( psInfo->hDS, pszRequest, NULL, NULL );
CPLPopErrorHandler();
msFree(pszRequest);

if( hLayer )
{
OGRFeatureH hFeature = OGR_L_GetNextFeature(hLayer);
bIsOKForSQLCompose = (hFeature != NULL);
if( hFeature )
{
pszMainTableName = msStrdup(OGR_FD_GetName(OGR_L_GetLayerDefn(psInfo->hLayer)));
pszSpatialFilterTableName = msStrdup( OGR_F_GetFieldAsString( hFeature, 0 ) );
pszRowId = msStrdup( OGR_F_GetFieldAsString( hFeature, 1 ) );
OGR_F_Destroy(hFeature);
}
OGR_DS_ReleaseResultSet( psInfo->hDS, hLayer );
}
}
}

// in the case we cannot handle the native string, go back to the client
// side evaluation by unsetting it.
if( !bIsOKForSQLCompose && dialect != NULL && layer->filter.native_string )
{
msDebug("msOGRFileWhichShapes(): unsetting native_string\n");
msFree( layer->filter.native_string );
layer->filter.native_string = NULL;
dialect = NULL;
}

// we'll go strictly two possible ways:
@@ -1841,9 +1909,17 @@ static int msOGRFileWhichShapes(layerObj *layer, rectObj rect, msOGRFileInfo *ps
} else if (strncmp(dialect, "SQLite", 6) == 0) {
if (filter) filter = msStringConcatenate(filter, " AND");
filter = msStringConcatenate(filter, " ");
filter = msStringConcatenate(filter, pszTableName);
filter = msStringConcatenate(filter, ".ROWID IN (SELECT ROWID FROM SpatialIndex WHERE f_table_name = '");
filter = msStringConcatenate(filter, pszTableName);
filter = msStringConcatenate(filter, pszMainTableName);
filter = msStringConcatenate(filter, ".");
const char* pszFIDColumn = OGR_L_GetFIDColumn(psInfo->hLayer);
if( pszRowId )
filter = msStringConcatenate(filter, pszRowId);
else if( pszFIDColumn != NULL && pszFIDColumn[0] != '\0' )
filter = msStringConcatenate(filter, pszFIDColumn);
else
filter = msStringConcatenate(filter, "ROWID");
filter = msStringConcatenate(filter, " IN (SELECT ROWID FROM SpatialIndex WHERE f_table_name = '");
filter = msStringConcatenate(filter, pszSpatialFilterTableName);
filter = msStringConcatenate(filter, "' ");
const char* pszGeometryColumn = OGR_L_GetGeometryColumn(psInfo->hLayer);
if( pszGeometryColumn != NULL && pszGeometryColumn[0] != '\0' ) {
@@ -1906,7 +1982,9 @@ static int msOGRFileWhichShapes(layerObj *layer, rectObj rect, msOGRFileInfo *ps
RELEASE_OGR_LOCK;
msSetError(MS_OGRERR, "ExecuteSQL(%s) failed.\n%s", "msOGRFileWhichShapes()", select, CPLGetLastErrorMsg());
msFree(select);
msFree(pszTableName);
msFree(pszMainTableName);
msFree(pszSpatialFilterTableName);
msFree(pszRowId);
return MS_FAILURE;
}

@@ -1973,7 +2051,9 @@ static int msOGRFileWhichShapes(layerObj *layer, rectObj rect, msOGRFileInfo *ps
msSetError(MS_OGRERR, "SetAttributeFilter(%s) failed on layer %s.\n%s", "msOGRFileWhichShapes()", layer->filter.string+6, layer->name?layer->name:"(null)", CPLGetLastErrorMsg() );
RELEASE_OGR_LOCK;
msFree(pszOGRFilter);
msFree(pszTableName);
msFree(pszMainTableName);
msFree(pszSpatialFilterTableName);
msFree(pszRowId);
msFree(select);
return MS_FAILURE;
}
@@ -1983,7 +2063,9 @@ static int msOGRFileWhichShapes(layerObj *layer, rectObj rect, msOGRFileInfo *ps

}

msFree(pszTableName);
msFree(pszMainTableName);
msFree(pszSpatialFilterTableName);
msFree(pszRowId);
msFree(select);

/* ------------------------------------------------------------------
BIN +0 Bytes (100%) msautotest/wxs/data/db.sqlite
Binary file not shown.
@@ -0,0 +1,38 @@
Content-Type: text/xml; charset=UTF-8

<?xml version='1.0' encoding="UTF-8" ?>
<wfs:FeatureCollection
xmlns:ms="http://mapserver.gis.umn.edu/mapserver"
xmlns:wfs="http://www.opengis.net/wfs"
xmlns:gml="http://www.opengis.net/gml"
xmlns:ogc="http://www.opengis.net/ogc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-basic.xsd
http://mapserver.gis.umn.edu/mapserver http://localhost/path/to/wfs_simple?SERVICE=WFS&amp;VERSION=1.0.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=myview&amp;OUTPUTFORMAT=XMLSCHEMA">
<gml:boundedBy>
<gml:Box srsName="EPSG:32632">
<gml:coordinates>643513.360000,4896928.190000 643513.360000,4896928.190000</gml:coordinates>
</gml:Box>
</gml:boundedBy>
<!-- WARNING: FeatureId item 'ID' not found in typename 'myview'. -->
<gml:featureMember>
<ms:myview>
<gml:boundedBy>
<gml:Box srsName="EPSG:32632">
<gml:coordinates>643513.360000,4896928.190000 643513.360000,4896928.190000</gml:coordinates>
</gml:Box>
</gml:boundedBy>
<ms:msGeometry>
<gml:Point srsName="EPSG:32632">
<gml:coordinates>643513.360000,4896928.190000</gml:coordinates>
</gml:Point>
</ms:msGeometry>
<ms:name>Fanano</ms:name>
<ms:peoples>2910</ms:peoples>
<ms:localcounc>1</ms:localcounc>
<ms:county>0</ms:county>
<ms:region>0</ms:region>
</ms:myview>
</gml:featureMember>
</wfs:FeatureCollection>

@@ -61,6 +61,9 @@
# RUN_PARMS: wfs_ogr_native_sql_30.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=towns&OUTPUTFORMAT=GML2&FILTER=<Filter><Equals><PropertyName>Geometry</PropertyName><Point srsName="EPSG:32632"><pos>662773 4891987.41</pos></Point></Equals></Filter>" > [RESULT]
# RUN_PARMS: wfs_ogr_native_sql_31.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=towns&OUTPUTFORMAT=GML2&FILTER=<Filter><Beyond><Distance unit="m">20000</Distance><PropertyName>Geometry</PropertyName><Polygon><exterior><LinearRing><posList>653627 4881103 653174 4890443 663148 4887813 663330 4879471 653627 4881103</posList></LinearRing></exterior></Polygon></Beyond></Filter>" > [RESULT]
# RUN_PARMS: wfs_ogr_native_sql_32.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=towns&OUTPUTFORMAT=GML2&FILTER=<Filter><DWithin><Distance unit="m">1000</Distance><PropertyName>Geometry</PropertyName><Polygon><exterior><LinearRing><posList>653627 4881103 653174 4890443 663148 4887813 663330 4879471 653627 4881103</posList></LinearRing></exterior></Polygon></DWithin></Filter>" > [RESULT]
#
# Same as wfs_ogr_native_sql_02 on a view
# RUN_PARMS: wfs_ogr_native_sql_33.xml [MAPSERV] QUERY_STRING="map=[MAPFILE]&SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=myview&OUTPUTFORMAT=GML2&FILTER=<Filter><AND><BBOX><PropertyName>Geometry</PropertyName><Box srsName='EPSG:32632'><coordinates>643159,4877386 696879,4898059</coordinates></Box></BBOX><PropertyIsEqualTo><PropertyName>name</PropertyName><Literal>Fanano</Literal></PropertyIsEqualTo></AND></Filter>" > [RESULT]

MAP

@@ -118,4 +121,26 @@ LAYER
TEMPLATE "wfs_ogr_native_sql.map"
END # Layer

LAYER
NAME myview
DATA myview
CONNECTIONTYPE OGR
CONNECTION "./data/db.sqlite"
PROCESSING "NATIVE_SQL=YES"
METADATA
"ows_title" "myview"
"wfs_featureid" "ID"
"gml_include_items" "all"
"gml_types" "auto"
"wfs_getfeature_formatlist" "ogrgml"
END
TYPE POINT
STATUS ON
PROJECTION
"init=epsg:32632"
END

TEMPLATE "wfs_ogr_native_sql.map"
END # Layer

END # Map File

1 comment on commit 58ce9c4

@ruhri

This comment has been minimized.

Copy link

@ruhri ruhri commented on 58ce9c4 Jul 28, 2016

Hi @rouault ,
I'm not sure whether you read my last three posts in #5218.
If not, pleease could you have a look at them - I think my experiences relate to your changes.

Thank You

Please sign in to comment.
You can’t perform that action at this time.