#include <ctype.h>
 #include <time.h>
 #include <pwd.h>
+#include <utime.h>
 #ifndef WIN32
 #include <sys/stat.h>          /* for stat() */
 #include <fcntl.h>             /* open() flags */
    const char *fname;
    bool        error = false;
    int         fd;
-
    struct stat before,
                after;
 
                         !ret ? strerror(errno) : "");
            return false;
        }
+#endif
 
        /*
         * No canonicalize_path() here. EDIT.EXE run from CMD.EXE prepends the
         * current directory to the supplied path unless we use only
         * backslashes, so we do that.
         */
-#endif
 #ifndef WIN32
        snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir,
                 "/", (int) getpid());
                    pg_log_error("%s: %m", fname);
                error = true;
            }
+           else
+           {
+               struct utimbuf ut;
+
+               /*
+                * Try to set the file modification time of the temporary file
+                * a few seconds in the past.  Otherwise, the low granularity
+                * (one second, or even worse on some filesystems) that we can
+                * portably measure with stat(2) could lead us to not
+                * recognize a modification, if the user typed very quickly.
+                *
+                * This is a rather unlikely race condition, so don't error
+                * out if the utime(2) call fails --- that would make the cure
+                * worse than the disease.
+                */
+               ut.modtime = ut.actime = time(NULL) - 2;
+               (void) utime(fname, &ut);
+           }
        }
    }
 
        error = true;
    }
 
-   if (!error && before.st_mtime != after.st_mtime)
+   /* file was edited if the size or modification time has changed */
+   if (!error &&
+       (before.st_size != after.st_size ||
+        before.st_mtime != after.st_mtime))
    {
        stream = fopen(fname, PG_BINARY_R);
        if (!stream)