@@ -784,8 +784,9 @@ exec_command(const char *cmd,
784784 }
785785
786786
787- /* \i is include file */
788- else if (strcmp (cmd , "i" ) == 0 || strcmp (cmd , "include" ) == 0 )
787+ /* \i and \ir include files */
788+ else if (strcmp (cmd , "i" ) == 0 || strcmp (cmd , "include" ) == 0
789+ || strcmp (cmd , "ir" ) == 0 || strcmp (cmd , "include_relative" ) == 0 )
789790 {
790791 char * fname = psql_scan_slash_option (scan_state ,
791792 OT_NORMAL , NULL , true);
@@ -797,8 +798,12 @@ exec_command(const char *cmd,
797798 }
798799 else
799800 {
801+ bool include_relative ;
802+
803+ include_relative = (strcmp (cmd , "ir" ) == 0
804+ || strcmp (cmd , "include_relative" ) == 0 );
800805 expand_tilde (& fname );
801- success = (process_file (fname , false) == EXIT_SUCCESS );
806+ success = (process_file (fname , false, include_relative ) == EXIT_SUCCESS );
802807 free (fname );
803808 }
804809 }
@@ -1969,15 +1974,19 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf,
19691974 * process_file
19701975 *
19711976 * Read commands from filename and then them to the main processing loop
1972- * Handler for \i, but can be used for other things as well. Returns
1977+ * Handler for \i and \ir , but can be used for other things as well. Returns
19731978 * MainLoop() error code.
1979+ *
1980+ * If use_relative_path is true and filename is not an absolute path, then open
1981+ * the file from where the currently processed file (if any) is located.
19741982 */
19751983int
1976- process_file (char * filename , bool single_txn )
1984+ process_file (char * filename , bool single_txn , bool use_relative_path )
19771985{
19781986 FILE * fd ;
19791987 int result ;
19801988 char * oldfilename ;
1989+ char relpath [MAXPGPATH ];
19811990 PGresult * res ;
19821991
19831992 if (!filename )
@@ -1986,6 +1995,24 @@ process_file(char *filename, bool single_txn)
19861995 if (strcmp (filename , "-" ) != 0 )
19871996 {
19881997 canonicalize_path (filename );
1998+
1999+ /*
2000+ * If we were asked to resolve the pathname relative to the location
2001+ * of the currently executing script, and there is one, and this is
2002+ * a relative pathname, then prepend all but the last pathname
2003+ * component of the current script to this pathname.
2004+ */
2005+ if (use_relative_path && pset .inputfile && !is_absolute_path (filename )
2006+ && !has_drive_prefix (filename ))
2007+ {
2008+ snprintf (relpath , MAXPGPATH , "%s" , pset .inputfile );
2009+ get_parent_directory (relpath );
2010+ join_path_components (relpath , relpath , filename );
2011+ canonicalize_path (relpath );
2012+
2013+ filename = relpath ;
2014+ }
2015+
19892016 fd = fopen (filename , PG_BINARY_R );
19902017 }
19912018 else
0 commit comments