summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <jan@hundin.mysql.fi>2004-10-22 07:58:04 +0300
committerunknown <jan@hundin.mysql.fi>2004-10-22 07:58:04 +0300
commitac8c655bd8cf77ff4ec5e062d0dda2878710dde7 (patch)
treec0e34fafdf5c692066e6a9f54b70fc59ab673021
parentd2bfd6766f9d8af284deb48852758eefefe4f9da (diff)
parentbcf7b58318e9eba2ac24561f93fb454f8ed0df62 (diff)
downloadmariadb-git-ac8c655bd8cf77ff4ec5e062d0dda2878710dde7.tar.gz
Merge jlindstrom@bk-internal.mysql.com:/home/bk/mysql-4.1
into hundin.mysql.fi:/home/jan/talle/mysql-4.1
-rw-r--r--innobase/include/os0file.h23
-rw-r--r--innobase/os/os0file.c77
-rw-r--r--sql/ha_innodb.cc32
3 files changed, 124 insertions, 8 deletions
diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h
index f1647c47bce..d1439faf29f 100644
--- a/innobase/include/os0file.h
+++ b/innobase/include/os0file.h
@@ -14,6 +14,7 @@ Created 10/21/1995 Heikki Tuuri
#ifndef __WIN__
#include <dirent.h>
#include <sys/stat.h>
+#include <time.h>
#endif
extern ibool os_do_not_call_flush_at_each_write;
@@ -142,12 +143,15 @@ bigger than 4000 bytes */
#define OS_FILE_MAX_PATH 4000
/* Struct used in fetching information of a file in a directory */
-typedef struct os_file_stat_struct os_file_stat_t;
struct os_file_stat_struct{
- char name[OS_FILE_MAX_PATH]; /* path to a file */
- os_file_type_t type; /* file type */
- ib_longlong size; /* file size */
+ char name[OS_FILE_MAX_PATH]; /* path to a file */
+ os_file_type_t type; /* file type */
+ ib_longlong size; /* file size */
+ time_t ctime; /* creation time */
+ time_t mtime; /* modification time */
+ time_t atime; /* access time */
};
+typedef struct os_file_stat_struct os_file_stat_t;
#ifdef __WIN__
typedef HANDLE os_file_dir_t; /* directory stream */
@@ -686,5 +690,14 @@ no pending io operations. */
ibool
os_aio_all_slots_free(void);
/*=======================*/
- /* out: TRUE if all free */
+
+/***********************************************************************
+This function returns information about the specified file */
+ibool
+os_file_get_status(
+/*===============*/
+ /* out: TRUE if stat information found */
+ const char* path, /* in: pathname of the file */
+ os_file_stat_t* stat_info); /* information of a file in a directory */
+
#endif
diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c
index 6b734bba965..3276aaddca2 100644
--- a/innobase/os/os0file.c
+++ b/innobase/os/os0file.c
@@ -2359,6 +2359,83 @@ os_file_status(
#endif
}
+/***********************************************************************
+This function returns information about the specified file */
+
+ibool
+os_file_get_status(
+/*===========*/
+ /* out: TRUE if stat information found */
+ const char* path, /* in: pathname of the file */
+ os_file_stat_t* stat_info) /* information of a file in a directory */
+{
+#ifdef __WIN__
+ int ret;
+ struct _stat statinfo;
+
+ ret = _stat(path, &statinfo);
+ if (ret && (errno == ENOENT || errno == ENOTDIR)) {
+ /* file does not exist */
+
+ return(FALSE);
+ } else if (ret) {
+ /* file exists, but stat call failed */
+
+ os_file_handle_error_no_exit(0, path, "stat");
+
+ return(FALSE);
+ }
+ if (_S_IFDIR & statinfo.st_mode) {
+ stat_info->type = OS_FILE_TYPE_DIR;
+ } else if (_S_IFREG & statinfo.st_mode) {
+ stat_info->type = OS_FILE_TYPE_FILE;
+ } else {
+ stat_info_>type = OS_FILE_TYPE_UNKNOWN;
+ }
+
+ stat_info->ctime = statinfo.st_ctime;
+ stat_info->atime = statinfo.st_atime;
+ stat_info->mtime = statinfo.st_mtime;
+ stat_info->size = statinfo.st_size;
+
+ return(TRUE);
+#else
+ int ret;
+ struct stat statinfo;
+
+ ret = stat(path, &statinfo);
+
+ if (ret && (errno == ENOENT || errno == ENOTDIR)) {
+ /* file does not exist */
+
+ return(FALSE);
+ } else if (ret) {
+ /* file exists, but stat call failed */
+
+ os_file_handle_error_no_exit(0, path, "stat");
+
+ return(FALSE);
+ }
+
+ if (S_ISDIR(statinfo.st_mode)) {
+ stat_info->type = OS_FILE_TYPE_DIR;
+ } else if (S_ISLNK(statinfo.st_mode)) {
+ stat_info->type = OS_FILE_TYPE_LINK;
+ } else if (S_ISREG(statinfo.st_mode)) {
+ stat_info->type = OS_FILE_TYPE_FILE;
+ } else {
+ stat_info->type = OS_FILE_TYPE_UNKNOWN;
+ }
+
+ stat_info->ctime = statinfo.st_ctime;
+ stat_info->atime = statinfo.st_atime;
+ stat_info->mtime = statinfo.st_mtime;
+ stat_info->size = statinfo.st_size;
+
+ return(TRUE);
+#endif
+}
+
/* path name separator character */
#ifdef __WIN__
# define OS_FILE_PATH_SEPARATOR '\\'
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 04a1c6a9014..8d9ecb95fc0 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -2461,9 +2461,10 @@ ha_innobase::write_row(
/* If the insert did not succeed we restore the value of
the auto-inc counter we used; note that this behavior was
introduced only in version 4.0.4.
- NOTE that a REPLACE command handles a duplicate key error
+ NOTE that a REPLACE command and LOAD DATA INFILE REPLACE
+ handles a duplicate key error
itself, and we must not decrement the autoinc counter
- if we are performing a REPLACE statement.
+ if we are performing a those statements.
NOTE 2: if there was an error, for example a deadlock,
which caused InnoDB to roll back the whole transaction
already in the call of row_insert_for_mysql(), we may no
@@ -2475,7 +2476,9 @@ ha_innobase::write_row(
if (error == DB_DUPLICATE_KEY
&& (user_thd->lex->sql_command == SQLCOM_REPLACE
|| user_thd->lex->sql_command
- == SQLCOM_REPLACE_SELECT)) {
+ == SQLCOM_REPLACE_SELECT
+ || (user_thd->lex->sql_command == SQLCOM_LOAD
+ && user_thd->lex->duplicates == DUP_REPLACE))) {
skip_auto_inc_decr= TRUE;
}
@@ -4334,6 +4337,8 @@ ha_innobase::info(
ha_rows rec_per_key;
ulong j;
ulong i;
+ char path[FN_REFLEN];
+ os_file_stat_t stat_info;
DBUG_ENTER("info");
@@ -4371,6 +4376,26 @@ ha_innobase::info(
prebuilt->trx->op_info = (char*)
"returning various info to MySQL";
+
+ if (ib_table->space != 0) {
+ my_snprintf(path, sizeof(path), "%s/%s%s",
+ mysql_data_home, ib_table->name,
+ ".ibd");
+ unpack_filename(path,path);
+ } else {
+ my_snprintf(path, sizeof(path), "%s/%s%s",
+ mysql_data_home, ib_table->name,
+ reg_ext);
+
+ unpack_filename(path,path);
+ }
+
+ /* Note that we do not know the access time of the table,
+ nor the CHECK TABLE time, nor the UPDATE or INSERT time. */
+
+ if (os_file_get_status(path,&stat_info)) {
+ create_time = stat_info.ctime;
+ }
}
if (flag & HA_STATUS_VARIABLE) {
@@ -5501,6 +5526,7 @@ innobase_query_is_replace(void)
thd = (THD *)innobase_current_thd();
if ( thd->lex->sql_command == SQLCOM_REPLACE ||
+ thd->lex->sql_command == SQLCOM_REPLACE_SELECT ||
( thd->lex->sql_command == SQLCOM_LOAD &&
thd->lex->duplicates == DUP_REPLACE )) {
return true;