@@ -247,6 +247,7 @@ typedef struct ms_MSSQL2008_layer_info_t {
247
247
char * user_srid ; /* zero length = calculate, non-zero means using this value! */
248
248
char * index_name ; /* hopefully this isn't necessary - but if the optimizer ain't cuttin' it... */
249
249
char * sort_spec ; /* the sort by specification which should be applied to the generated select statement */
250
+ int mssqlversion_major ; /* the sql server major version number */
250
251
SQLSMALLINT * itemtypes ; /* storing the sql field types for further reference */
251
252
252
253
msODBCconn * conn ; /* Connection to db */
@@ -973,6 +974,7 @@ int msMSSQL2008LayerOpen(layerObj *layer)
973
974
layerinfo -> sort_spec = NULL ;
974
975
layerinfo -> conn = NULL ;
975
976
layerinfo -> itemtypes = NULL ;
977
+ layerinfo -> mssqlversion_major = 0 ;
976
978
977
979
layerinfo -> conn = (msODBCconn * ) msConnPoolRequest (layer );
978
980
@@ -1102,26 +1104,162 @@ int msMSSQL2008LayerInitItemInfo(layerObj *layer)
1102
1104
return MS_SUCCESS ;
1103
1105
}
1104
1106
1107
+ static int getMSSQLMajorVersion (layerObj * layer )
1108
+ {
1109
+ msMSSQL2008LayerInfo * layerinfo = getMSSQL2008LayerInfo (layer );
1110
+ if (layerinfo == NULL )
1111
+ return 0 ;
1112
+
1113
+ if (layerinfo -> mssqlversion_major == 0 ) {
1114
+ char * mssqlversion_major = msLayerGetProcessingKey (layer , "MSSQL_VERSION_MAJOR" );
1115
+ if (mssqlversion_major != NULL ) {
1116
+ layerinfo -> mssqlversion_major = atoi (mssqlversion_major );
1117
+ }
1118
+ else {
1119
+ /* need to query from database */
1120
+ if (executeSQL (layerinfo -> conn , "SELECT SERVERPROPERTY('ProductVersion')" )) {
1121
+ SQLRETURN rc = SQLFetch (layerinfo -> conn -> hstmt );
1122
+ if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO ) {
1123
+ /* process results */
1124
+ char result_data [256 ];
1125
+ SQLLEN retLen = 0 ;
1126
+
1127
+ rc = SQLGetData (layerinfo -> conn -> hstmt , 1 , SQL_C_CHAR , result_data , sizeof (result_data ), & retLen );
1128
+
1129
+ if (rc != SQL_ERROR ) {
1130
+ result_data [retLen ] = 0 ;
1131
+ layerinfo -> mssqlversion_major = atoi (result_data );
1132
+ }
1133
+ }
1134
+ }
1135
+ }
1136
+ }
1137
+
1138
+ return layerinfo -> mssqlversion_major ;
1139
+ }
1140
+
1105
1141
/* Get the layer extent as specified in the mapfile or a largest area */
1106
1142
/* covering all features */
1107
1143
int msMSSQL2008LayerGetExtent (layerObj * layer , rectObj * extent )
1108
1144
{
1109
- if (layer -> debug ) {
1110
- msDebug ("msMSSQL2008LayerGetExtent called\n" );
1111
- }
1145
+ msMSSQL2008LayerInfo * layerinfo ;
1146
+ char * query = 0 ;
1147
+ char result_data [256 ];
1148
+ SQLLEN retLen ;
1149
+ SQLRETURN rc ;
1150
+
1151
+ if (layer -> debug ) {
1152
+ msDebug ("msMSSQL2008LayerGetExtent called\n" );
1153
+ }
1112
1154
1113
- if (layer -> extent .minx == -1.0 && layer -> extent .miny == -1.0 &&
1114
- layer -> extent .maxx == -1.0 && layer -> extent .maxy == -1.0 ) {
1115
- extent -> minx = extent -> miny = -1.0 * FLT_MAX ;
1116
- extent -> maxx = extent -> maxy = FLT_MAX ;
1117
- } else {
1118
- extent -> minx = layer -> extent .minx ;
1119
- extent -> miny = layer -> extent .miny ;
1120
- extent -> maxx = layer -> extent .maxx ;
1121
- extent -> maxy = layer -> extent .maxy ;
1122
- }
1155
+ if (!(layer -> extent .minx == -1.0 && layer -> extent .miny == -1.0 &&
1156
+ layer -> extent .maxx == -1.0 && layer -> extent .maxy == -1.0 )) {
1157
+ /* extent was already set */
1158
+ extent -> minx = layer -> extent .minx ;
1159
+ extent -> miny = layer -> extent .miny ;
1160
+ extent -> maxx = layer -> extent .maxx ;
1161
+ extent -> maxy = layer -> extent .maxy ;
1162
+ }
1123
1163
1124
- return MS_SUCCESS ;
1164
+ layerinfo = getMSSQL2008LayerInfo (layer );
1165
+
1166
+ if (!layerinfo ) {
1167
+ msSetError (MS_QUERYERR , "GetExtent called with layerinfo = NULL" , "msMSSQL2008LayerGetExtent()" );
1168
+ return MS_FAILURE ;
1169
+ }
1170
+
1171
+ /* set up statement */
1172
+ if (getMSSQLMajorVersion (layer ) >= 11 ) {
1173
+ if (strcasecmp (layerinfo -> geom_column_type , "geography" ) == 0 ) {
1174
+ query = msStringConcatenate (query , "WITH extent(extentcol) AS (SELECT geometry::EnvelopeAggregate(geometry::STGeomFromWKB(" );
1175
+ query = msStringConcatenate (query , layerinfo -> geom_column );
1176
+ query = msStringConcatenate (query , ".STAsBinary(), " );
1177
+ query = msStringConcatenate (query , layerinfo -> geom_column );
1178
+ query = msStringConcatenate (query , ".STSrid)" );
1179
+ }
1180
+ else {
1181
+ query = msStringConcatenate (query , "WITH extent(extentcol) AS (SELECT geometry::EnvelopeAggregate(" );
1182
+ query = msStringConcatenate (query , layerinfo -> geom_column );
1183
+ }
1184
+ query = msStringConcatenate (query , ".MakeValid()) AS extentcol FROM " );
1185
+ query = msStringConcatenate (query , layerinfo -> geom_table );
1186
+ query = msStringConcatenate (query , ") SELECT extentcol.STPointN(1).STX, extentcol.STPointN(1).STY, extentcol.STPointN(3).STX, extentcol.STPointN(3).STY FROM extent" );
1187
+ }
1188
+ else {
1189
+ if (strcasecmp (layerinfo -> geom_column_type , "geography" ) == 0 ) {
1190
+ query = msStringConcatenate (query , "WITH ENVELOPE as (SELECT geometry::STGeomFromWKB(" );
1191
+ query = msStringConcatenate (query , layerinfo -> geom_column );
1192
+ query = msStringConcatenate (query , ".STAsBinary(), " );
1193
+ query = msStringConcatenate (query , layerinfo -> geom_column );
1194
+ query = msStringConcatenate (query , ".STSrid)" );
1195
+ }
1196
+ else {
1197
+ query = msStringConcatenate (query , "WITH ENVELOPE as (SELECT " );
1198
+ query = msStringConcatenate (query , layerinfo -> geom_column );
1199
+ }
1200
+ query = msStringConcatenate (query , ".MakeValid().STEnvelope() as envelope from " );
1201
+ query = msStringConcatenate (query , layerinfo -> geom_table );
1202
+ query = msStringConcatenate (query , "), CORNERS as (SELECT envelope.STPointN(1) as point from ENVELOPE UNION ALL select envelope.STPointN(3) from ENVELOPE) SELECT MIN(point.STX), MIN(point.STY), MAX(point.STX), MAX(point.STY) FROM CORNERS" );
1203
+ }
1204
+
1205
+ if (!executeSQL (layerinfo -> conn , query )) {
1206
+ msFree (query );
1207
+ return MS_FAILURE ;
1208
+ }
1209
+
1210
+ msFree (query );
1211
+
1212
+ /* process results */
1213
+ rc = SQLFetch (layerinfo -> conn -> hstmt );
1214
+
1215
+ if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO ) {
1216
+ if (layer -> debug ) {
1217
+ msDebug ("msMSSQL2008LayerGetExtent: No results found.\n" );
1218
+ }
1219
+ return MS_FAILURE ;
1220
+ }
1221
+
1222
+ rc = SQLGetData (layerinfo -> conn -> hstmt , 1 , SQL_C_CHAR , result_data , sizeof (result_data ), & retLen );
1223
+ if (rc == SQL_ERROR ) {
1224
+ msSetError (MS_QUERYERR , "Failed to get MinX value" , "msMSSQL2008LayerGetExtent()" );
1225
+ return MS_FAILURE ;
1226
+ }
1227
+
1228
+ result_data [retLen ] = 0 ;
1229
+
1230
+ extent -> minx = atof (result_data );
1231
+
1232
+ rc = SQLGetData (layerinfo -> conn -> hstmt , 2 , SQL_C_CHAR , result_data , sizeof (result_data ), & retLen );
1233
+ if (rc == SQL_ERROR ) {
1234
+ msSetError (MS_QUERYERR , "Failed to get MinY value" , "msMSSQL2008LayerGetExtent()" );
1235
+ return MS_FAILURE ;
1236
+ }
1237
+
1238
+ result_data [retLen ] = 0 ;
1239
+
1240
+ extent -> miny = atof (result_data );
1241
+
1242
+ rc = SQLGetData (layerinfo -> conn -> hstmt , 3 , SQL_C_CHAR , result_data , sizeof (result_data ), & retLen );
1243
+ if (rc == SQL_ERROR ) {
1244
+ msSetError (MS_QUERYERR , "Failed to get MaxX value" , "msMSSQL2008LayerGetExtent()" );
1245
+ return MS_FAILURE ;
1246
+ }
1247
+
1248
+ result_data [retLen ] = 0 ;
1249
+
1250
+ extent -> maxx = atof (result_data );
1251
+
1252
+ rc = SQLGetData (layerinfo -> conn -> hstmt , 4 , SQL_C_CHAR , result_data , sizeof (result_data ), & retLen );
1253
+ if (rc == SQL_ERROR ) {
1254
+ msSetError (MS_QUERYERR , "Failed to get MaxY value" , "msMSSQL2008LayerGetExtent()" );
1255
+ return MS_FAILURE ;
1256
+ }
1257
+
1258
+ result_data [retLen ] = 0 ;
1259
+
1260
+ extent -> maxy = atof (result_data );
1261
+
1262
+ return MS_SUCCESS ;
1125
1263
}
1126
1264
1127
1265
/* Get the layer feature count */
@@ -1358,19 +1496,15 @@ static int prepare_database(layerObj *layer, rectObj rect, char **query_string)
1358
1496
}
1359
1497
1360
1498
/* adding spatial filter */
1361
- msMSSQL2008LayerGetExtent (layer , & extent );
1362
- if (rect .minx > extent .minx || rect .miny > extent .miny ||
1363
- rect .maxx < extent .maxx || rect .maxy < extent .maxy ) {
1364
- if (hasFilter == MS_FALSE )
1365
- query = msStringConcatenate (query , " WHERE " );
1366
- else
1367
- query = msStringConcatenate (query , " AND " );
1499
+ if (hasFilter == MS_FALSE )
1500
+ query = msStringConcatenate (query , " WHERE " );
1501
+ else
1502
+ query = msStringConcatenate (query , " AND " );
1368
1503
1369
- query = msStringConcatenate (query , layerinfo -> geom_column );
1370
- query = msStringConcatenate (query , ".STIntersects(" );
1371
- query = msStringConcatenate (query , box3d );
1372
- query = msStringConcatenate (query , ") = 1 " );
1373
- }
1504
+ query = msStringConcatenate (query , layerinfo -> geom_column );
1505
+ query = msStringConcatenate (query , ".MakeValid().STIntersects(" );
1506
+ query = msStringConcatenate (query , box3d );
1507
+ query = msStringConcatenate (query , ") = 1 " );
1374
1508
1375
1509
if (layerinfo -> sort_spec )
1376
1510
query = msStringConcatenate (query , layerinfo -> sort_spec );
0 commit comments