diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result
index 9118fa8cfed77527a19b9de3d4a966c03c102b9a..3771245bff9dd4a90a88400713f48ecef498e06f 100644
--- a/mysql-test/r/gis.result
+++ b/mysql-test/r/gis.result
@@ -7,6 +7,38 @@ CREATE TABLE mls (fid INTEGER NOT NULL PRIMARY KEY, g MULTILINESTRING);
 CREATE TABLE mp  (fid INTEGER NOT NULL PRIMARY KEY, g MULTIPOLYGON);
 CREATE TABLE gc  (fid INTEGER NOT NULL PRIMARY KEY, g GEOMETRYCOLLECTION);
 CREATE TABLE geo (fid INTEGER NOT NULL PRIMARY KEY, g GEOMETRY);
+SHOW FIELDS FROM pt;
+Field	Type	Collation	Null	Key	Default	Extra
+fid	int(11)	binary		PRI	0	
+g	point	binary	YES		NULL	
+SHOW FIELDS FROM ls;
+Field	Type	Collation	Null	Key	Default	Extra
+fid	int(11)	binary		PRI	0	
+g	linestring	binary	YES		NULL	
+SHOW FIELDS FROM p;
+Field	Type	Collation	Null	Key	Default	Extra
+fid	int(11)	binary		PRI	0	
+g	polygon	binary	YES		NULL	
+SHOW FIELDS FROM mpt;
+Field	Type	Collation	Null	Key	Default	Extra
+fid	int(11)	binary		PRI	0	
+g	multipoint	binary	YES		NULL	
+SHOW FIELDS FROM mls;
+Field	Type	Collation	Null	Key	Default	Extra
+fid	int(11)	binary		PRI	0	
+g	multilinestring	binary	YES		NULL	
+SHOW FIELDS FROM mp;
+Field	Type	Collation	Null	Key	Default	Extra
+fid	int(11)	binary		PRI	0	
+g	multipolygon	binary	YES		NULL	
+SHOW FIELDS FROM gc;
+Field	Type	Collation	Null	Key	Default	Extra
+fid	int(11)	binary		PRI	0	
+g	geometrycollection	binary	YES		NULL	
+SHOW FIELDS FROM geo;
+Field	Type	Collation	Null	Key	Default	Extra
+fid	int(11)	binary		PRI	0	
+g	geometry	binary	YES		NULL	
 INSERT INTO pt VALUES 
 (101, PointFromText('POINT(10 10)')),
 (102, PointFromText('POINT(20 10)')),
diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test
index f4b6138c86feaa641a92d59d9e14a32061b4597f..179dd12e6a3a0c23b9ab58dcf76d89a61521d11c 100644
--- a/mysql-test/t/gis.test
+++ b/mysql-test/t/gis.test
@@ -15,6 +15,16 @@ CREATE TABLE mp  (fid INTEGER NOT NULL PRIMARY KEY, g MULTIPOLYGON);
 CREATE TABLE gc  (fid INTEGER NOT NULL PRIMARY KEY, g GEOMETRYCOLLECTION);
 CREATE TABLE geo (fid INTEGER NOT NULL PRIMARY KEY, g GEOMETRY);
 
+SHOW FIELDS FROM pt;
+SHOW FIELDS FROM ls;
+SHOW FIELDS FROM p;
+SHOW FIELDS FROM mpt;
+SHOW FIELDS FROM mls;
+SHOW FIELDS FROM mp;
+SHOW FIELDS FROM gc;
+SHOW FIELDS FROM geo;
+
+
 INSERT INTO pt VALUES 
 (101, PointFromText('POINT(10 10)')),
 (102, PointFromText('POINT(20 10)')),
diff --git a/sql/field.cc b/sql/field.cc
index 6b403b85aae7cb2d763dcb682ba99d39d1edcaf5..7d877a02bf74c87d1c34883c7ced5ef2f974fc17 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -4775,7 +4775,33 @@ void Field_geom::set_key_image(char *buff, uint length, CHARSET_INFO *cs)
 
 void Field_geom::sql_type(String &res) const
 {
-  res.set("geometry", 8, &my_charset_latin1);
+  CHARSET_INFO *cs= &my_charset_latin1;
+  switch (geom_type)
+  {
+    case GEOM_POINT:
+     res.set("point", 5, cs);
+     break;
+    case GEOM_LINESTRING:
+     res.set("linestring", 10, cs);
+     break;
+    case GEOM_POLYGON:
+     res.set("polygon", 7, cs);
+     break;
+    case GEOM_MULTIPOINT:
+     res.set("multipoint", 10, cs);
+     break;
+    case GEOM_MULTILINESTRING:
+     res.set("multilinestring", 15, cs);
+     break;
+    case GEOM_MULTIPOLYGON:
+     res.set("multipolygon", 12, cs);
+     break;
+    case GEOM_GEOMETRYCOLLECTION:
+     res.set("geometrycollection", 18, cs);
+     break;
+    default:
+     res.set("geometry", 8, cs);
+  }
 }
 
 
@@ -5286,6 +5312,7 @@ Field *make_field(char *ptr, uint32 field_length,
 		  uint pack_flag,
 		  enum_field_types field_type,
 		  CHARSET_INFO *field_charset,
+		  Field::geometry_type geom_type,
 		  Field::utype unireg_check,
 		  TYPELIB *interval,
 		  const char *field_name,
@@ -5309,7 +5336,7 @@ Field *make_field(char *ptr, uint32 field_length,
     if (f_is_geom(pack_flag))
       return new Field_geom(ptr,null_pos,null_bit,
 			    unireg_check, field_name, table,
-			    pack_length);
+			    pack_length, geom_type);
     if (f_is_blob(pack_flag))
       return new Field_blob(ptr,null_pos,null_bit,
 			    unireg_check, field_name, table,
diff --git a/sql/field.h b/sql/field.h
index aad135083234a20683300d22e1b85e0c9e8af35b..1b7906f9fb5b7562d5eeee8529f5a862baab448a 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -50,7 +50,12 @@ class Field
   enum utype  { NONE,DATE,SHIELD,NOEMPTY,CASEUP,PNR,BGNR,PGNR,YES,NO,REL,
 		CHECK,EMPTY,UNKNOWN_FIELD,CASEDN,NEXT_NUMBER,INTERVAL_FIELD,
 		BIT_FIELD, TIMESTAMP_FIELD,CAPITALIZE,BLOB_FIELD};
-
+  enum geometry_type
+  {
+    GEOM_GEOMETRY = 0, GEOM_POINT = 1, GEOM_LINESTRING = 2, GEOM_POLYGON = 3,
+    GEOM_MULTIPOINT = 4, GEOM_MULTILINESTRING = 5, GEOM_MULTIPOLYGON = 6,
+    GEOM_GEOMETRYCOLLECTION = 7
+  };
   enum imagetype { itRAW, itMBR};
   
   utype		unireg_check;
@@ -931,15 +936,20 @@ class Field_blob :public Field_str {
 
 class Field_geom :public Field_blob {
 public:
+  enum geometry_type geom_type;
+  
   Field_geom(char *ptr_arg, uchar *null_ptr_arg, uint null_bit_arg,
 	     enum utype unireg_check_arg, const char *field_name_arg,
-	     struct st_table *table_arg,uint blob_pack_length)
+	     struct st_table *table_arg,uint blob_pack_length,
+	     enum geometry_type geom_type_arg)
      :Field_blob(ptr_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, 
-                 field_name_arg, table_arg, blob_pack_length,&my_charset_bin) {}
+                 field_name_arg, table_arg, blob_pack_length,&my_charset_bin)
+  { geom_type= geom_type_arg; }
   Field_geom(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
-	     struct st_table *table_arg)
+	     struct st_table *table_arg, enum geometry_type geom_type_arg)
      :Field_blob(len_arg, maybe_null_arg, field_name_arg,
-                 table_arg, &my_charset_bin) {}
+                 table_arg, &my_charset_bin)
+  { geom_type= geom_type_arg; }
   enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY; }
   enum_field_types type() const { return FIELD_TYPE_GEOMETRY; }
   void sql_type(String &str) const;
@@ -1033,6 +1043,7 @@ class create_field :public Sql_alloc {
   Field::utype unireg_check;
   TYPELIB *interval;			// Which interval to use
   CHARSET_INFO *charset;
+  Field::geometry_type geom_type;
   Field *field;				// For alter table
 
   uint8 row,col,sc_length,interval_id;	// For rea_create_table
@@ -1086,6 +1097,7 @@ Field *make_field(char *ptr, uint32 field_length,
 		  uchar *null_pos, uchar null_bit,
 		  uint pack_flag, enum_field_types field_type,
 		  CHARSET_INFO *cs,
+		  Field::geometry_type geom_type,
 		  Field::utype unireg_check,
 		  TYPELIB *interval, const char *field_name,
 		  struct st_table *table);
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 4ad1335d080e44025d198a2c064e37e6f31ad657..678af8f881d43bd1d6e416007601cabff9f4b2cc 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -565,7 +565,8 @@ bool add_field_to_list(THD *thd, char *field_name, enum enum_field_types type,
 		       char *length, char *decimal,
 		       uint type_modifier,
 		       Item *default_value, Item *comment,
-		       char *change, TYPELIB *interval,CHARSET_INFO *cs);
+		       char *change, TYPELIB *interval,CHARSET_INFO *cs,
+		       uint uint_geom_type);
 void store_position_for_column(const char *name);
 bool add_to_list(THD *thd, SQL_LIST &list,Item *group,bool asc=0);
 void add_join_on(TABLE_LIST *b,Item *expr);
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 0d284d5f6197ce877bf7903413a45acafeef9cb7..6abcd5e8feab2dc53b7b7789ee725b7d09758954 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -449,6 +449,7 @@ typedef struct st_lex
   create_field	      *last_field;
   Item *default_value, *comment;
   CHARSET_INFO *thd_charset;
+  uint uint_geom_type;
   LEX_USER *grant_user;
   gptr yacc_yyss,yacc_yyvs;
   THD *thd;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index d08e6b70634344ca58372d7b1b21ef332734d0cb..3169d2235f50f458452b77c0f8d80cbca80067b1 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3391,7 +3391,8 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
 		       char *length, char *decimals,
 		       uint type_modifier,
 		       Item *default_value, Item *comment,
-		       char *change, TYPELIB *interval, CHARSET_INFO *cs)
+		       char *change, TYPELIB *interval, CHARSET_INFO *cs,
+		       uint uint_geom_type)
 {
   register create_field *new_field;
   LEX  *lex= &thd->lex;
@@ -3445,6 +3446,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
   new_field->interval=0;
   new_field->pack_length=0;
   new_field->charset=cs;
+  new_field->geom_type= (Field::geometry_type) uint_geom_type;
 
   if (!comment)
   {
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 84c68d37c91ad837c461301282065ac4a7375f67..1d9a3f2df10912ce6f324be2f98e8f97081e5112 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1114,7 +1114,8 @@ field_spec:
 				(enum enum_field_types) $3,
 				lex->length,lex->dec,lex->type,
 				lex->default_value, lex->comment,
-				lex->change,lex->interval,lex->charset))
+				lex->change,lex->interval,lex->charset,
+				lex->uint_geom_type))
 	    YYABORT;
 	};
 
@@ -1167,20 +1168,28 @@ type:
 	| BLOB_SYM opt_len		{ Lex->charset=&my_charset_bin;
 					  $$=FIELD_TYPE_BLOB; }
 	| GEOMETRY_SYM			{ Lex->charset=&my_charset_bin;
+					  Lex->uint_geom_type= Field::GEOM_GEOMETRY;
 					  $$=FIELD_TYPE_GEOMETRY; }
 	| GEOMETRYCOLLECTION		{ Lex->charset=&my_charset_bin;
+					  Lex->uint_geom_type= Field::GEOM_GEOMETRYCOLLECTION;
 					  $$=FIELD_TYPE_GEOMETRY; }
 	| POINT_SYM			{ Lex->charset=&my_charset_bin;
+					  Lex->uint_geom_type= Field::GEOM_POINT;
 					  $$=FIELD_TYPE_GEOMETRY; }
 	| MULTIPOINT			{ Lex->charset=&my_charset_bin;
+					  Lex->uint_geom_type= Field::GEOM_MULTIPOINT;
 					  $$=FIELD_TYPE_GEOMETRY; }
 	| LINESTRING			{ Lex->charset=&my_charset_bin;
+					  Lex->uint_geom_type= Field::GEOM_LINESTRING;
 					  $$=FIELD_TYPE_GEOMETRY; }
 	| MULTILINESTRING		{ Lex->charset=&my_charset_bin;
+					  Lex->uint_geom_type= Field::GEOM_MULTILINESTRING;
 					  $$=FIELD_TYPE_GEOMETRY; }
 	| POLYGON			{ Lex->charset=&my_charset_bin;
+					  Lex->uint_geom_type= Field::GEOM_POLYGON;
 					  $$=FIELD_TYPE_GEOMETRY; }
 	| MULTIPOLYGON			{ Lex->charset=&my_charset_bin;
+					  Lex->uint_geom_type= Field::GEOM_MULTIPOLYGON;
 					  $$=FIELD_TYPE_GEOMETRY; }
 	| MEDIUMBLOB			{ Lex->charset=&my_charset_bin;
 					  $$=FIELD_TYPE_MEDIUM_BLOB; }
@@ -1549,7 +1558,8 @@ alter_list_item:
                                   (enum enum_field_types) $5,
                                   lex->length,lex->dec,lex->type,
                                   lex->default_value, lex->comment,
-				  $3.str, lex->interval, lex->charset))
+				  $3.str, lex->interval, lex->charset,
+				  lex->uint_geom_type))
 	       YYABORT;
           }
           opt_place
diff --git a/sql/table.cc b/sql/table.cc
index 17bb15d3033bc59a4a8be874bab1a0469303b82e..9bea4a09b05a950408fd564e392a12e955f80281 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -371,6 +371,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
     uint pack_flag, interval_nr, unireg_type, recpos, field_length;
     enum_field_types field_type;
     CHARSET_INFO *charset=NULL;
+    Field::geometry_type geom_type= Field::GEOM_GEOMETRY;
     LEX_STRING comment;
 
     if (new_frm_ver == 3)
@@ -384,9 +385,19 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
 
       uint comment_length=uint2korr(strpos+15);
       field_type=(enum_field_types) (uint) strpos[13];
-      if (!(charset=get_charset((uint) strpos[14], MYF(0))))
-	charset= (outparam->table_charset ? outparam->table_charset: 
+
+      // charset and geometry_type share the same byte in frm
+      if (field_type == FIELD_TYPE_GEOMETRY)
+      {
+	geom_type= (Field::geometry_type) strpos[14];
+	charset= &my_charset_bin;
+      }
+      else
+      {
+        if (!(charset=get_charset((uint) strpos[14], MYF(0))))
+	  charset= (outparam->table_charset ? outparam->table_charset: 
 		  default_charset_info);
+      }
       if (!comment_length)
       {
 	comment.str= (char*) "";
@@ -420,6 +431,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
 		 pack_flag,
 		 field_type,
 		 charset,
+		 geom_type,
 		 (Field::utype) MTYP_TYPENR(unireg_type),
 		 (interval_nr ?
 		  outparam->intervals+interval_nr-1 :
diff --git a/sql/unireg.cc b/sql/unireg.cc
index fa843fe5d1ec779e920845235bad3b6f51c9f39d..5e723281d3f095e443e4a6434df7bc1730ea1f0b 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -458,7 +458,10 @@ static bool pack_fields(File file,List<create_field> &create_fields)
     int2store(buff+10,field->unireg_check);
     buff[12]= (uchar) field->interval_id;
     buff[13]= (uchar) field->sql_type; 
-    buff[14]= (uchar) field->charset->number;
+    if (field->sql_type == FIELD_TYPE_GEOMETRY)
+      buff[14]= (uchar) field->geom_type;
+    else
+      buff[14]= (uchar) field->charset->number;
     int2store(buff+15, field->comment.length);
     comment_length+= field->comment.length;
     set_if_bigger(int_count,field->interval_id);
@@ -573,6 +576,7 @@ static bool make_empty_rec(File file,enum db_type table_type,
 			       field->pack_flag,
 			       field->sql_type,
 			       field->charset,
+			       field->geom_type,
 			       field->unireg_check,
 			       field->interval,
 			       field->field_name,