diff --git a/contrib/pg_upgrade/check.c b/contrib/pg_upgrade/check.c
new file mode 100644
index 20b117b..3be2a13
*** a/contrib/pg_upgrade/check.c
--- b/contrib/pg_upgrade/check.c
*************** check_and_dump_old_cluster(bool live_che
*** 122,127 ****
--- 122,131 ----
  				old_8_3_create_sequence_script(&old_cluster);
  	}
  
+ 	/* Pre-PG 9.4 had a different 'line' data type internal format */
+ 	if (GET_MAJOR_VERSION(old_cluster.major_version) <= 904)
+ 		old_9_3_check_for_line_data_type_usage(&old_cluster);
+ 
  	/* Pre-PG 9.0 had no large object permissions */
  	if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
  		new_9_0_populate_pg_largeobject_metadata(&old_cluster, true);
*************** check_for_reg_data_type_usage(ClusterInf
*** 914,921 ****
  		"			'pg_catalog.regconfig'::pg_catalog.regtype, "
  								"			'pg_catalog.regdictionary'::pg_catalog.regtype) AND "
  								"		c.relnamespace = n.oid AND "
! 							  "		n.nspname != 'pg_catalog' AND "
! 						 "		n.nspname != 'information_schema'");
  
  		ntups = PQntuples(res);
  		i_nspname = PQfnumber(res, "nspname");
--- 918,924 ----
  		"			'pg_catalog.regconfig'::pg_catalog.regtype, "
  								"			'pg_catalog.regdictionary'::pg_catalog.regtype) AND "
  								"		c.relnamespace = n.oid AND "
! 							  "		n.nspname NOT IN ('pg_catalog', 'information_schema')");
  
  		ntups = PQntuples(res);
  		i_nspname = PQfnumber(res, "nspname");
diff --git a/contrib/pg_upgrade/pg_upgrade.h b/contrib/pg_upgrade/pg_upgrade.h
new file mode 100644
index 33be33d..0410b02
*** a/contrib/pg_upgrade/pg_upgrade.h
--- b/contrib/pg_upgrade/pg_upgrade.h
*************** void		pg_putenv(const char *var, const c
*** 470,475 ****
--- 470,476 ----
  
  void new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster,
  										 bool check_mode);
+ void old_9_3_check_for_line_data_type_usage(ClusterInfo *cluster);
  
  /* version_old_8_3.c */
  
diff --git a/contrib/pg_upgrade/version.c b/contrib/pg_upgrade/version.c
new file mode 100644
index 294a339..e064e38
*** a/contrib/pg_upgrade/version.c
--- b/contrib/pg_upgrade/version.c
*************** new_9_0_populate_pg_largeobject_metadata
*** 87,89 ****
--- 87,178 ----
  	else
  		check_ok();
  }
+ 
+ 
+ /*
+  * old_9_3_check_for_line_data_type_usage()
+  *	9.3 -> 9.4
+  *	Fully implement the 'line' data type in 9.4, which previously returned
+  *	"not enabled" by default and was only functionally enabled with a 
+  *	compile-time switch;  9.4 "line" has different binary and text
+  *	representation formats;  checks tables and indexes.
+  */
+ void
+ old_9_3_check_for_line_data_type_usage(ClusterInfo *cluster)
+ {
+ 	int			dbnum;
+ 	FILE	   *script = NULL;
+ 	bool		found = false;
+ 	char		output_path[MAXPGPATH];
+ 
+ 	prep_status("Checking for invalid \"line\" user columns");
+ 
+ 	snprintf(output_path, sizeof(output_path), "tables_using_line.txt");
+ 
+ 	for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
+ 	{
+ 		PGresult   *res;
+ 		bool		db_used = false;
+ 		int			ntups;
+ 		int			rowno;
+ 		int			i_nspname,
+ 					i_relname,
+ 					i_attname;
+ 		DbInfo	   *active_db = &cluster->dbarr.dbs[dbnum];
+ 		PGconn	   *conn = connectToServer(cluster, active_db->db_name);
+ 
+ 		res = executeQueryOrDie(conn,
+ 								"SELECT n.nspname, c.relname, a.attname "
+ 								"FROM	pg_catalog.pg_class c, "
+ 								"		pg_catalog.pg_namespace n, "
+ 								"		pg_catalog.pg_attribute a "
+ 								"WHERE	c.oid = a.attrelid AND "
+ 								"		NOT a.attisdropped AND "
+ 								"		a.atttypid = 'pg_catalog.line'::pg_catalog.regtype AND "
+ 								"		c.relnamespace = n.oid AND "
+ 		/* exclude possible orphaned temp tables */
+ 								"		n.nspname !~ '^pg_temp_' AND "
+ 						 "		n.nspname !~ '^pg_toast_temp_' AND "
+ 								"		n.nspname NOT IN ('pg_catalog', 'information_schema')");
+ 
+ 		ntups = PQntuples(res);
+ 		i_nspname = PQfnumber(res, "nspname");
+ 		i_relname = PQfnumber(res, "relname");
+ 		i_attname = PQfnumber(res, "attname");
+ 		for (rowno = 0; rowno < ntups; rowno++)
+ 		{
+ 			found = true;
+ 			if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
+ 				pg_fatal("could not open file \"%s\": %s\n", output_path, getErrorText(errno));
+ 			if (!db_used)
+ 			{
+ 				fprintf(script, "Database: %s\n", active_db->db_name);
+ 				db_used = true;
+ 			}
+ 			fprintf(script, "  %s.%s.%s\n",
+ 					PQgetvalue(res, rowno, i_nspname),
+ 					PQgetvalue(res, rowno, i_relname),
+ 					PQgetvalue(res, rowno, i_attname));
+ 		}
+ 
+ 		PQclear(res);
+ 
+ 		PQfinish(conn);
+ 	}
+ 
+ 	if (script)
+ 		fclose(script);
+ 
+ 	if (found)
+ 	{
+ 		pg_log(PG_REPORT, "fatal\n");
+ 		pg_fatal("Your installation contains the \"line\" data type in user tables.  This\n"
+ 		"data type changed its internal and input/output format between your old\n"
+ 				 "and new clusters so this cluster cannot currently be upgraded.  You can\n"
+ 		"remove the problem tables and restart the upgrade.  A list of the problem\n"
+ 				 "columns is in the file:\n"
+ 				 "    %s\n\n", output_path);
+ 	}
+ 	else
+ 		check_ok();
+ }
diff --git a/doc/src/sgml/release-9.4.sgml b/doc/src/sgml/release-9.4.sgml
new file mode 100644
index 1be163f..3070d0b
*** a/doc/src/sgml/release-9.4.sgml
--- b/doc/src/sgml/release-9.4.sgml
***************
*** 1262,1268 ****
         <para>
          The line <emphasis>segment</> data type (<link
          linkend="datatype-lseg"><type>LSEG</></link>) has always been
!         fully supported.
         </para>
        </listitem>
  
--- 1262,1269 ----
         <para>
          The line <emphasis>segment</> data type (<link
          linkend="datatype-lseg"><type>LSEG</></link>) has always been
!         fully supported.  The previous <type>line</> data type (enabled
!         only via a compile-time option) is not binary or dump-compatible.
         </para>
        </listitem>
  
