diff --git a/libraries/common.lib.php b/libraries/common.lib.php index 88ea11fa04..21a2030b09 100644 --- a/libraries/common.lib.php +++ b/libraries/common.lib.php @@ -3005,7 +3005,7 @@ function PMA_unsupportedDatatypes() { return $no_support_types; } -function PMA_getGISDatatypes() { +function PMA_getGISDatatypes($upper_case = false) { $gis_data_types = array('geometry', 'point', 'linestring', @@ -3015,9 +3015,112 @@ function PMA_getGISDatatypes() { 'multipolygon', 'geometrycollection' ); + if ($upper_case) { + for ($i = 0; $i < count($gis_data_types); $i++) { + $gis_data_types[$i] = strtoupper($gis_data_types[$i]); + } + } return $gis_data_types; } + +/** + * Returns the names and details of the functions + * that can be applied on geometry data typess. + * + * @param string $geom_type if provided the output is limited to the functions + * that are applicable to the provided geometry type. + * @param bool $binary if set to false functions that take two geometries + * as arguments will not be included. + * @param bool $display if set to true seperators will be added to the + * output array. + * + * @return array names and details of the functions that can be applied on + * geometry data typess. + */ +function PMA_getGISFunctions($geom_type = null, $binary = true, $display = false) { + // Unary functions common to all geomety types + $funcs = array(); + if ($display) { + $funcs[] = array('name' => ' '); + } + + $funcs[] = array('name' => 'Dimension', 'params' => 1, 'type' => 'int'); + //$funcs[] = array('name' => 'Envelope', 'params' => 1, 'type' => 'Polygon'); + $funcs[] = array('name' => 'GeometryType', 'params' => 1, 'type' => 'text'); + $funcs[] = array('name' => 'SRID', 'params' => 1, 'type' => 'int'); + $funcs[] = array('name' => 'IsEmpty', 'params' => 1, 'type' => 'int'); + $funcs[] = array('name' => 'IsSimple', 'params' => 1, 'type' => 'int'); + + $geom_type = trim(strtolower($geom_type)); + if ($display && $geom_type != 'geometry' && $geom_type != 'multipoint') { + $funcs[] = array('name' => '--------'); + } + + if ($geom_type == 'point') { + $funcs[] = array('name' => 'X', 'params' => 1, 'type' => 'float'); + $funcs[] = array('name' => 'Y', 'params' => 1, 'type' => 'float'); + } elseif ($geom_type == 'multipoint') { + // no fucntions here + } elseif ($geom_type == 'linestring') { + //$funcs[] = array('name' => 'EndPoint', 'params' => 1, 'type' => 'Point'); + $funcs[] = array('name' => 'GLength', 'params' => 1, 'type' => 'float'); + $funcs[] = array('name' => 'NumPoints', 'params' => 1, 'type' => 'int'); + //$funcs[] = array('name' => 'StartPoint', 'params' => 1, 'type' => 'Point'); + $funcs[] = array('name' => 'IsRing', 'params' => 1, 'type' => 'int'); + } elseif ($geom_type == 'multilinestring') { + $funcs[] = array('name' => 'GLength', 'params' => 1, 'type' => 'float'); + $funcs[] = array('name' => 'IsClosed', 'params' => 1, 'type' => 'int'); + } elseif ($geom_type == 'polygon') { + $funcs[] = array('name' => 'Area', 'params' => 1, 'type' => 'float'); + //$funcs[] = array('name' => 'ExteriorRing', 'params' => 1, 'type' => 'Linestring'); + $funcs[] = array('name' => 'NumInteriorRings', 'params' => 1, 'type' => 'int'); + } elseif ($geom_type == 'multipolygon') { + $funcs[] = array('name' => 'Area', 'params' => 1, 'type' => 'float'); + //$funcs[] = array('name' => 'Centroid', 'params' => 1, 'type' => 'Point'); + // Not yet implemented in MySQL + //$funcs[] = array('name' => 'PointOnSurface', 'params' => 1, 'type' => 'Point'); + } elseif ($geom_type == 'geometrycollection') { + $funcs[] = array('name' => 'NumGeometries', 'params' => 1, 'type' => 'int'); + } + + // If we are asked for binary functions as well + if ($binary) { + if ($display) { + $funcs[] = array('name' => '--------'); + } + $binary = array( + array('name' => 'Crosses', 'params' => 2, 'type' => 'int'), + array('name' => 'Contains', 'params' => 2, 'type' => 'int'), + array('name' => 'Disjoint', 'params' => 2, 'type' => 'int'), + array('name' => 'Equals', 'params' => 2, 'type' => 'int'), + array('name' => 'Intersects', 'params' => 2, 'type' => 'int'), + array('name' => 'Overlaps', 'params' => 2, 'type' => 'int'), + array('name' => 'Touches', 'params' => 2, 'type' => 'int'), + array('name' => 'Within', 'params' => 2, 'type' => 'int'), + ); + + // If MySQl version is greaeter than or equal 5.6.1, use the ST_ prefix. + if (PMA_MYSQL_INT_VERSION >= 50601) { + for ($i = 0; $i < count($binary); $i++) { + $binary[$i]['name'] = 'ST_' . $binary[$i]['name']; + } + } + $funcs = array_merge($funcs, $binary); + if ($display) { + $funcs[] = array('name' => '--------'); + } + $funcs[] = array('name' => 'MBRContains', 'params' => 2, 'type' => 'int'); + $funcs[] = array('name' => 'MBRDisjoint', 'params' => 2, 'type' => 'int'); + $funcs[] = array('name' => 'MBREquals', 'params' => 2, 'type' => 'int'); + $funcs[] = array('name' => 'MBRIntersects', 'params' => 2, 'type' => 'int'); + $funcs[] = array('name' => 'MBROverlaps', 'params' => 2, 'type' => 'int'); + $funcs[] = array('name' => 'MBRTouches', 'params' => 2, 'type' => 'int'); + $funcs[] = array('name' => 'MBRWithin', 'params' => 2, 'type' => 'int'); + } + return $funcs; +} + /** * Creates a dropdown box with MySQL functions for a particular column. * diff --git a/tbl_select.php b/tbl_select.php index c6b0a35332..eb19a7d285 100644 --- a/tbl_select.php +++ b/tbl_select.php @@ -35,6 +35,7 @@ if ($GLOBALS['cfg']['PropertiesIconic'] == true) { $titles['Browse'] = __('Browse foreign values'); } +$geom_types = PMA_getGISDatatypes(); /** * Not selection yet required -> displays the selection form */ @@ -64,9 +65,14 @@ if (! isset($param) || $param[0] == '') { $result = PMA_DBI_query('SHOW FULL FIELDS FROM ' . PMA_backquote($table) . ' FROM ' . PMA_backquote($db) . ';', null, PMA_DBI_QUERY_STORE); $fields_cnt = PMA_DBI_num_rows($result); $fields_list = $fields_null = $fields_type = $fields_collation = array(); + $geom_column_present = false; while ($row = PMA_DBI_fetch_assoc($result)) { $fields_list[] = $row['Field']; $type = $row['Type']; + // check whether table contains geometric columns + if (in_array($type, $geom_types)) { + $geom_column_present = true; + } // reformat mysql query output if (strncasecmp($type, 'set', 3) == 0 || strncasecmp($type, 'enum', 4) == 0) { @@ -111,7 +117,13 @@ if (! isset($param) || $param[0] == '') { - + '); echo __('Function'); echo(''); + } + ?> + @@ -125,6 +137,27 @@ if (! isset($param) || $param[0] == '') { for ($i = 0; $i < $fields_cnt; $i++) { ?> + '); + // if a geometry column + if (in_array($fields_type[$i], $geom_types)) { + echo(''); + } else { + echo(' '); + } + echo(''); + } + ?> @@ -360,13 +393,31 @@ else { "= ''" => 1, "!= ''" => 1 ); + $geom_unary_operators = array( + 'IsEmpty' => 1, + 'IsSimple' => 1, + 'IsRing' => 1, + 'IsClosed' => 1, + ); $cnt_func = count($func); reset($func); while (list($i, $func_type) = each($func)) { + // If geometry funciton is set apply it to the field name + if (isset($geom_func[$i]) && trim($geom_func[$i]) != '') { + $backquoted_name = $geom_func[$i] . '(' . PMA_backquote($names[$i]) . ')'; + // If the intended where clause is something like 'IsEmpty(`spatial_col_name`)' + if (isset($geom_unary_operators[$geom_func[$i]]) && trim($fields[$i]) == '') { + $w[] = $backquoted_name; + continue; + } + } else { + $backquoted_name = PMA_backquote($names[$i]); + } + list($charsets[$i]) = explode('_', $collations[$i]); if (isset($unary_operators[$func_type])) { $fields[$i] = ''; - $w[] = PMA_backquote($names[$i]) . ' ' . $func_type; + $w[] = $backquoted_name . ' ' . $func_type; } elseif (strncasecmp($types[$i], 'enum', 4) == 0) { if (!empty($fields[$i])) { @@ -393,7 +444,7 @@ else { $enum_where .= ', \'' . PMA_sqlAddSlashes($fields[$i][$e]) . '\''; } - $w[] = PMA_backquote($names[$i]) . ' ' . $func_type . ' ' . $parens_open . $enum_where . $parens_close; + $w[] = $backquoted_name . ' ' . $func_type . ' ' . $parens_open . $enum_where . $parens_close; } } elseif ($fields[$i] != '') { @@ -425,12 +476,12 @@ else { $value = $quot . PMA_sqlAddSlashes(trim($value)) . $quot; if ($func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN') - $w[] = PMA_backquote($names[$i]) . ' ' . $func_type . ' ' . (isset($values[0]) ? $values[0] : '') . ' AND ' . (isset($values[1]) ? $values[1] : ''); + $w[] = $backquoted_name . ' ' . $func_type . ' ' . (isset($values[0]) ? $values[0] : '') . ' AND ' . (isset($values[1]) ? $values[1] : ''); else - $w[] = PMA_backquote($names[$i]) . ' ' . $func_type . ' (' . implode(',', $values) . ')'; + $w[] = $backquoted_name . ' ' . $func_type . ' (' . implode(',', $values) . ')'; } else { - $w[] = PMA_backquote($names[$i]) . ' ' . $func_type . ' ' . $quot . PMA_sqlAddSlashes($fields[$i]) . $quot;; + $w[] = $backquoted_name . ' ' . $func_type . ' ' . $quot . PMA_sqlAddSlashes($fields[$i]) . $quot;; } } // end if