Commit ddbbf976 authored by Marko Mäkelä's avatar Marko Mäkelä

Merge 10.4 into 10.5

parents d1851b30 ed355f59
......@@ -2271,3 +2271,113 @@ a
5
DROP TABLE t1;
SET GLOBAL innodb_stats_persistent= @stats.save;
#
# MDEV-20056: index to build range filter should not be
# the same as table access index
#
SET @stats.save= @@innodb_stats_persistent;
SET GLOBAL innodb_stats_persistent= ON;
CREATE TABLE t1 (ch varchar(1), id int, id2 int) ENGINE=InnoDB;
INSERT INTO t1 VALUES
('l',3,2), ('e',NULL,NULL), ('r',7,3), ('h',NULL,2), (NULL,4,4), ('c',4,NULL),
('k',NULL,NULL), ('h',NULL,NULL), ('b',9,NULL), ('f',6,NULL);
CREATE TABLE t2 (
pk int NOT NULL, col_date_key date, ch2 varchar(1), id2 int,
PRIMARY KEY (pk), KEY (col_date_key), KEY (ch2), KEY (id2)
) ENGINE=InnoDB;
INSERT INTO t2 VALUES
(1,'2034-04-21','g',9), (2,'2006-09-08','y',1), (3,NULL,'h',2),
(4,'1987-03-02','s',2), (5,'2019-07-02','u',NULL),(6,'2012-12-18','z',1),
(7,NULL,'w',4), (8,'2005-03-10','o',8), (9,'1987-02-12','d',4);
CREATE TABLE t3 (id int) ENGINE=InnoDB;
INSERT INTO t3 VALUES (6);
ANALYZE TABLE t1,t2,t3;
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze status OK
test.t2 analyze status Engine-independent statistics collected
test.t2 analyze status OK
test.t3 analyze status Engine-independent statistics collected
test.t3 analyze status OK
EXPLAIN EXTENDED SELECT 1 FROM t3
WHERE EXISTS ( SELECT 1 FROM t1
WHERE t3.id IN ( SELECT bt1.id FROM t2, t1 AS bt1
WHERE bt1.id = t2.pk AND
t2.ch2 <= 'g' ) OR
t1.id2 = t1.id);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 1 100.00 Using where
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 10 100.00 Using where
3 MATERIALIZED t2 range PRIMARY,col_date_key,ch2,id2 ch2 4 NULL 2 100.00 Using where; Using index
3 MATERIALIZED bt1 ALL NULL NULL NULL NULL 10 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1276 Field or reference 'test.t3.id' of SELECT #2 was resolved in SELECT #1
Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t3` where <in_optimizer>(1,<expr_cache><`test`.`t3`.`id`>(exists(/* select#2 */ select 1 from `test`.`t1` where <expr_cache><`test`.`t3`.`id`>(<in_optimizer>(`test`.`t3`.`id`,`test`.`t3`.`id` in ( <materialize> (/* select#3 */ select `test`.`bt1`.`id` from `test`.`t2` join `test`.`t1` `bt1` where `test`.`bt1`.`id` = `test`.`t2`.`pk` and `test`.`t2`.`ch2` <= 'g' ), <primary_index_lookup>(`test`.`t3`.`id` in <temporary table> on distinct_key where `test`.`t3`.`id` = `<subquery3>`.`id`)))) or `test`.`t1`.`id2` = `test`.`t1`.`id` limit 1)))
SELECT 1 FROM t3
WHERE EXISTS ( SELECT 1 FROM t1
WHERE t3.id IN ( SELECT bt1.id FROM t2, t1 AS bt1
WHERE bt1.id = t2.pk AND
t2.ch2 <= 'g' ) OR
t1.id2 = t1.id);
1
1
EXPLAIN EXTENDED SELECT 1 FROM t3
WHERE EXISTS ( SELECT 1 FROM t1
WHERE t3.id IN ( SELECT bt1.id FROM t2, t1 AS bt1
WHERE bt1.ch = t2.ch2 AND
bt1.id = t2.pk AND
t2.ch2 <= 'g' ) OR
t1.id2 = t1.id);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 1 100.00 Using where
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 10 100.00 Using where
3 MATERIALIZED t2 range PRIMARY,col_date_key,ch2,id2 ch2 4 NULL 2 100.00 Using where; Using index
3 MATERIALIZED bt1 ALL NULL NULL NULL NULL 10 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1276 Field or reference 'test.t3.id' of SELECT #2 was resolved in SELECT #1
Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t3` where <in_optimizer>(1,<expr_cache><`test`.`t3`.`id`>(exists(/* select#2 */ select 1 from `test`.`t1` where <expr_cache><`test`.`t3`.`id`>(<in_optimizer>(`test`.`t3`.`id`,`test`.`t3`.`id` in ( <materialize> (/* select#3 */ select `test`.`bt1`.`id` from `test`.`t2` join `test`.`t1` `bt1` where `test`.`bt1`.`ch` = `test`.`t2`.`ch2` and `test`.`bt1`.`id` = `test`.`t2`.`pk` and `test`.`t2`.`ch2` <= 'g' ), <primary_index_lookup>(`test`.`t3`.`id` in <temporary table> on distinct_key where `test`.`t3`.`id` = `<subquery3>`.`id`)))) or `test`.`t1`.`id2` = `test`.`t1`.`id` limit 1)))
SELECT 1 FROM t3
WHERE EXISTS ( SELECT 1 FROM t1
WHERE t3.id IN ( SELECT bt1.id FROM t2, t1 AS bt1
WHERE bt1.ch = t2.ch2 AND
bt1.id = t2.pk AND
t2.ch2 <= 'g' ) OR
t1.id2 = t1.id);
1
1
DROP TABLE t1, t2, t3;
SET GLOBAL innodb_stats_persistent= @stats.save;
#
# MDEV-20407: usage of range filter is not supported when
# the joined table is accessed by a full text index
#
set @stats.save= @@innodb_stats_persistent;
set global innodb_stats_persistent=on;
create table t1(id int, s text, key (id), fulltext key (s)) engine=innodb;
insert into t1 values
(1119,'t'),(1134,'t'),(1134,'t'),(1143,'t'),(1143,'t'),(1187,'t'),(1187,'t'),
(1187,'t'),(1187,'t'),(1187,'t'),(1187,'t'),(1187,'t'),(1187,'t'),(1187,'t'),
(1187,'t'),(1210,'t'),(1210,'t'),(1210,'t'),(1210,'t'),(1210,'t'),(1210,'t'),
(1214,'t'),(1214,'t'),(1215,'t'),(1215,'t'),(1215,'t'),(1216,'t'),(1218,'t'),
(1220,'t'),(1220,'t'),(1220,'t'),(1222,'t'),(1223,'t'),(1223,'t'),(1224,'t'),
(1225,'t'),(1225,'t'),(1226,'t'),(1226,'t'),(1227,'t'),(1227,'t'),(1228,'t'),
(1229,'t'),(1230,'t'),(1230,'t'),(1231,'t'),(1231,'t'),(1232,'t'),(1232,'t'),
(1232,'t'),(1232,'t'),(1233,'t'),(1241,'t'),(1245,'t'),(1247,'t'),(1247,'t'),
(1247,'t'),(1247,'t'),(1247,'t'),(1247,'t'),(1248,'like fttest');
analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze Warning Engine-independent statistics are not collected for column 's'
test.t1 analyze status OK
explain extended select count(0) from t1
where id=15066 and (match s against ('+"fttest"' in boolean mode));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 fulltext id,s s 0 1 1.64 Using where
Warnings:
Note 1003 select count(0) AS `count(0)` from `test`.`t1` where `test`.`t1`.`id` = 15066 and (match `test`.`t1`.`s` against ('+"fttest"' in boolean mode))
select count(0) from t1
where id=15066 and (match s against ('+"fttest"' in boolean mode));
count(0)
0
drop table t1;
set global innodb_stats_persistent= @stats.save;
......@@ -129,3 +129,89 @@ SELECT a FROM t1 WHERE c < 'k' AND b > 't' ORDER BY a;
DROP TABLE t1;
SET GLOBAL innodb_stats_persistent= @stats.save;
--echo #
--echo # MDEV-20056: index to build range filter should not be
--echo # the same as table access index
--echo #
SET @stats.save= @@innodb_stats_persistent;
SET GLOBAL innodb_stats_persistent= ON;
CREATE TABLE t1 (ch varchar(1), id int, id2 int) ENGINE=InnoDB;
INSERT INTO t1 VALUES
('l',3,2), ('e',NULL,NULL), ('r',7,3), ('h',NULL,2), (NULL,4,4), ('c',4,NULL),
('k',NULL,NULL), ('h',NULL,NULL), ('b',9,NULL), ('f',6,NULL);
CREATE TABLE t2 (
pk int NOT NULL, col_date_key date, ch2 varchar(1), id2 int,
PRIMARY KEY (pk), KEY (col_date_key), KEY (ch2), KEY (id2)
) ENGINE=InnoDB;
INSERT INTO t2 VALUES
(1,'2034-04-21','g',9), (2,'2006-09-08','y',1), (3,NULL,'h',2),
(4,'1987-03-02','s',2), (5,'2019-07-02','u',NULL),(6,'2012-12-18','z',1),
(7,NULL,'w',4), (8,'2005-03-10','o',8), (9,'1987-02-12','d',4);
CREATE TABLE t3 (id int) ENGINE=InnoDB;
INSERT INTO t3 VALUES (6);
ANALYZE TABLE t1,t2,t3;
let $q1=
SELECT 1 FROM t3
WHERE EXISTS ( SELECT 1 FROM t1
WHERE t3.id IN ( SELECT bt1.id FROM t2, t1 AS bt1
WHERE bt1.id = t2.pk AND
t2.ch2 <= 'g' ) OR
t1.id2 = t1.id);
eval EXPLAIN EXTENDED $q1;
eval $q1;
let $q2=
SELECT 1 FROM t3
WHERE EXISTS ( SELECT 1 FROM t1
WHERE t3.id IN ( SELECT bt1.id FROM t2, t1 AS bt1
WHERE bt1.ch = t2.ch2 AND
bt1.id = t2.pk AND
t2.ch2 <= 'g' ) OR
t1.id2 = t1.id);
eval EXPLAIN EXTENDED $q2;
eval $q2;
DROP TABLE t1, t2, t3;
SET GLOBAL innodb_stats_persistent= @stats.save;
--echo #
--echo # MDEV-20407: usage of range filter is not supported when
--echo # the joined table is accessed by a full text index
--echo #
set @stats.save= @@innodb_stats_persistent;
set global innodb_stats_persistent=on;
create table t1(id int, s text, key (id), fulltext key (s)) engine=innodb;
insert into t1 values
(1119,'t'),(1134,'t'),(1134,'t'),(1143,'t'),(1143,'t'),(1187,'t'),(1187,'t'),
(1187,'t'),(1187,'t'),(1187,'t'),(1187,'t'),(1187,'t'),(1187,'t'),(1187,'t'),
(1187,'t'),(1210,'t'),(1210,'t'),(1210,'t'),(1210,'t'),(1210,'t'),(1210,'t'),
(1214,'t'),(1214,'t'),(1215,'t'),(1215,'t'),(1215,'t'),(1216,'t'),(1218,'t'),
(1220,'t'),(1220,'t'),(1220,'t'),(1222,'t'),(1223,'t'),(1223,'t'),(1224,'t'),
(1225,'t'),(1225,'t'),(1226,'t'),(1226,'t'),(1227,'t'),(1227,'t'),(1228,'t'),
(1229,'t'),(1230,'t'),(1230,'t'),(1231,'t'),(1231,'t'),(1232,'t'),(1232,'t'),
(1232,'t'),(1232,'t'),(1233,'t'),(1241,'t'),(1245,'t'),(1247,'t'),(1247,'t'),
(1247,'t'),(1247,'t'),(1247,'t'),(1247,'t'),(1248,'like fttest');
analyze table t1;
let $q=
select count(0) from t1
where id=15066 and (match s against ('+"fttest"' in boolean mode));
eval explain extended $q;
eval $q;
drop table t1;
set global innodb_stats_persistent= @stats.save;
......@@ -318,8 +318,8 @@
FROM information_schema.global_status
WHERE variable_name = 'innodb_instant_alter_column';
instants
-187
+189
-193
+195
SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency;
#
# MDEV-18266: Changing an index comment unnecessarily rebuilds index
......@@ -912,6 +912,19 @@ SELECT * FROM t1;
b a vb
NULL barf NULL
DROP TABLE t1;
CREATE TABLE t1 (a INT, b TEXT, PRIMARY KEY(b(9))) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
ALTER TABLE t1 ADD COLUMN c TEXT FIRST;
ALTER TABLE t1 ADD COLUMN d TEXT GENERATED ALWAYS AS (SUBSTR(b,1,499)) FIRST;
DROP TABLE t1;
CREATE TABLE t1(a CHAR(5), b INT, c CHAR(1), d CHAR(1), PRIMARY KEY(a,b))
DEFAULT CHARACTER SET utf8 ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
INSERT INTO t1 SET a='fubar',b=42;
ALTER TABLE t1 DROP c, DROP d, ALGORITHM=INSTANT;
ALTER TABLE t1 ADD vb INT AS (b);
SELECT * FROM t1;
a b vb
fubar 42 42
DROP TABLE t1;
CREATE TABLE t1
(id INT PRIMARY KEY, c2 INT UNIQUE,
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
......@@ -1769,6 +1782,19 @@ SELECT * FROM t1;
b a vb
NULL barf NULL
DROP TABLE t1;
CREATE TABLE t1 (a INT, b TEXT, PRIMARY KEY(b(9))) ENGINE=InnoDB ROW_FORMAT=COMPACT;
ALTER TABLE t1 ADD COLUMN c TEXT FIRST;
ALTER TABLE t1 ADD COLUMN d TEXT GENERATED ALWAYS AS (SUBSTR(b,1,499)) FIRST;
DROP TABLE t1;
CREATE TABLE t1(a CHAR(5), b INT, c CHAR(1), d CHAR(1), PRIMARY KEY(a,b))
DEFAULT CHARACTER SET utf8 ENGINE=InnoDB ROW_FORMAT=COMPACT;
INSERT INTO t1 SET a='fubar',b=42;
ALTER TABLE t1 DROP c, DROP d, ALGORITHM=INSTANT;
ALTER TABLE t1 ADD vb INT AS (b);
SELECT * FROM t1;
a b vb
fubar 42 42
DROP TABLE t1;
CREATE TABLE t1
(id INT PRIMARY KEY, c2 INT UNIQUE,
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
......@@ -2626,12 +2652,25 @@ SELECT * FROM t1;
b a vb
NULL barf NULL
DROP TABLE t1;
CREATE TABLE t1 (a INT, b TEXT, PRIMARY KEY(b(9))) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
ALTER TABLE t1 ADD COLUMN c TEXT FIRST;
ALTER TABLE t1 ADD COLUMN d TEXT GENERATED ALWAYS AS (SUBSTR(b,1,499)) FIRST;
DROP TABLE t1;
CREATE TABLE t1(a CHAR(5), b INT, c CHAR(1), d CHAR(1), PRIMARY KEY(a,b))
DEFAULT CHARACTER SET utf8 ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
INSERT INTO t1 SET a='fubar',b=42;
ALTER TABLE t1 DROP c, DROP d, ALGORITHM=INSTANT;
ALTER TABLE t1 ADD vb INT AS (b);
SELECT * FROM t1;
a b vb
fubar 42 42
DROP TABLE t1;
disconnect analyze;
SELECT variable_value-@old_instant instants
FROM information_schema.global_status
WHERE variable_name = 'innodb_instant_alter_column';
instants
187
193
SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency;
#
# MDEV-18266: Changing an index comment unnecessarily rebuilds index
......
......@@ -799,6 +799,21 @@ ALTER TABLE t1 ADD vb INT AS (b);
SELECT * FROM t1;
DROP TABLE t1;
# MDEV-21148 Assertion failure index->n_core_fields + n_add >= index->n_fields
eval CREATE TABLE t1 (a INT, b TEXT, PRIMARY KEY(b(9))) $engine;
ALTER TABLE t1 ADD COLUMN c TEXT FIRST;
ALTER TABLE t1 ADD COLUMN d TEXT GENERATED ALWAYS AS (SUBSTR(b,1,499)) FIRST;
DROP TABLE t1;
eval CREATE TABLE t1(a CHAR(5), b INT, c CHAR(1), d CHAR(1), PRIMARY KEY(a,b))
DEFAULT CHARACTER SET utf8 $engine;
INSERT INTO t1 SET a='fubar',b=42;
ALTER TABLE t1 DROP c, DROP d, ALGORITHM=INSTANT;
# this evicts and reloads the table definition until MDEV-17468 is fixed
ALTER TABLE t1 ADD vb INT AS (b);
SELECT * FROM t1;
DROP TABLE t1;
dec $format;
let $redundant_4k= 0;
}
......
......@@ -1644,6 +1644,12 @@ bool JOIN::make_range_rowid_filters()
{
if (!tab->range_rowid_filter_info)
continue;
DBUG_ASSERT(!(tab->ref.key >= 0 &&
tab->ref.key == (int) tab->range_rowid_filter_info->key_no));
DBUG_ASSERT(!(tab->ref.key == -1 && tab->quick &&
tab->quick->index == tab->range_rowid_filter_info->key_no));
int err;
SQL_SELECT *sel= NULL;
Rowid_filter_container *filter_container= NULL;
......@@ -7704,7 +7710,8 @@ best_access_path(JOIN *join,
found_ref);
} /* not ft_key */
if (records < DBL_MAX)
if (records < DBL_MAX &&
(found_part & 1)) // start_key->key can be used for index access
{
double rows= record_count * records;
double access_cost_factor= MY_MIN(tmp / rows, 1.0);
......
......@@ -499,28 +499,32 @@ static dberr_t btr_cur_instant_init_low(dict_index_t* index, mtr_t* mtr)
we must duplicate some logic here. */
if (trx_id_offset) {
} else if (index->table->not_redundant()) {
/* PRIMARY KEY columns can never be NULL.
We can skip the null flag bitmap. */
const byte* lens = rec - (REC_N_NEW_EXTRA_BYTES + 1)
- index->n_core_null_bytes;
unsigned n_add = rec_get_n_add_field(lens);
ut_ad(index->n_core_fields + n_add >= index->n_fields);
lens -= n_add;
/* The PRIMARY KEY contains variable-length columns.
For the metadata record, variable-length columns are
always written with zero length. The DB_TRX_ID will
start right after any fixed-length columns. */
/* OK, before MDEV-21088 was fixed, for
variable-length encoded PRIMARY KEY column of
type CHAR, we wrote more than zero bytes. In
order to allow affected tables to be accessed,
it would be nice to determine the actual
length of each PRIMARY KEY column. However, to
be able to do that, we should determine the
size of the null-bit bitmap in the metadata
record. And we cannot know that before reading
the metadata BLOB, whose starting point we are
trying to find here. (Although the PRIMARY KEY
columns cannot be NULL, we would have to know
where the lengths of variable-length PRIMARY KEY
columns start.)
So, unfortunately we cannot help users who
were affected by MDEV-21088 on a ROW_FORMAT=COMPACT
or ROW_FORMAT=DYNAMIC table. */
for (uint i = index->n_uniq; i--; ) {
const dict_field_t& f = index->fields[i];
unsigned len = f.fixed_len;
if (!len) {
len = *lens--;
if ((len & 0x80)
&& DATA_BIG_COL(f.col)) {
/* 1exxxxxxx xxxxxxxx */
len &= 0x3f;
len <<= 8;
len |= *lens--;
}
}
trx_id_offset += len;
trx_id_offset += index->fields[i].fixed_len;
}
} else if (rec_get_1byte_offs_flag(rec)) {
trx_id_offset = rec_1_get_field_end_info(
......
......@@ -21,8 +21,6 @@ IF(MSVC_VERSION LESS 1600)
RETURN()
ENDIF()
SET(MANUFACTURER "MariaDB Corporation Ab")
SET(WIX_BIN_PATHS)
FOREACH(WIX_VER 3.9 3.10 3.11)
......
......@@ -32,6 +32,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
#include <shellapi.h>
#include <stdlib.h>
#include <winservice.h>
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <map>
using namespace std;
#define ONE_MB 1048576
UINT ExecRemoveDataDirectory(wchar_t *dir)
......@@ -467,6 +475,7 @@ extern "C" UINT CheckDBInUse(MSIHANDLE hInstall)
WcaGetProperty(L"SERVICENAME", &servicename);
WcaGetProperty(L"DATADIR", &datadir);
WcaGetFormattedString(L"[INSTALLDIR]bin\\", &bindir);
WcaLog(LOGMSG_STANDARD,"SERVICENAME=%S, DATADIR=%S, bindir=%S",
servicename, datadir, bindir);
......@@ -1003,3 +1012,305 @@ extern "C" BOOL WINAPI DllMain(
return TRUE;
}
// check if file exists
inline bool checkIfFileExists (wstring& name) {
string sLog = "checkIfFileExists, ";
string sName(name.begin(), name.end() );
ifstream f(sName);
sLog.append(sName);
sLog.append(", result: ");
bool fileExists = f.good();
if (f.good())
sLog.append("true");
else
sLog.append("false");
WcaLog(LOGMSG_STANDARD, sLog.c_str());
return f.good();
}
// string to wstring
std::wstring s2ws(const std::string& s)
{
int len;
int slength = (int)s.length() + 1;
len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
wchar_t* buf = new wchar_t[len];
MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
std::wstring r(buf);
delete[] buf;
return r;
}
/* MDEV-19781 MariaDB symlinks on Windows */
extern "C" UINT __stdcall CreateSymlinks(MSIHANDLE hInstall)
{
HRESULT hr = S_OK;
UINT er = ERROR_SUCCESS;
wchar_t customActionData[10000];
wchar_t installDir[MAX_PATH];
DWORD len = 10000;
wchar_t installerVersion[MAX_VERSION_PROPERTY_SIZE];
DWORD size = MAX_VERSION_PROPERTY_SIZE;
wchar_t binDir[MAX_PATH];
size_t blen = NULL;
hr = WcaInitialize(hInstall, __FUNCTION__);
WcaLog(LOGMSG_STANDARD, "Initialized.");
if (MsiGetPropertyW(hInstall, L"CustomActionData", customActionData, &len) != ERROR_SUCCESS)
{
hr = HRESULT_FROM_WIN32(GetLastError());
MsiProcessMessage(hInstall, INSTALLMESSAGE_INFO, hr);
}
if (MsiGetPropertyW(hInstall, L"ProductVersion", installerVersion, &size) != ERROR_SUCCESS)
{
hr = HRESULT_FROM_WIN32(GetLastError());
MsiProcessMessage(hInstall, INSTALLMESSAGE_INFO, hr);
}
MsiProcessMessage(hInstall, INSTALLMESSAGE_INFO, hr);
wstring wsCustomActionData(customActionData);
string sCustomActionData(wsCustomActionData.begin(), wsCustomActionData.end());
WcaLog(LOGMSG_STANDARD, sCustomActionData.c_str());
stringstream ss;
ss << sCustomActionData;
vector<string> vCustomActionData;
while( ss.good() )
{
string substr;
getline( ss, substr, '|' );
WcaLog(LOGMSG_STANDARD, substr.c_str());
vCustomActionData.push_back( substr );
}
int i = 0;
string sBinPath = "";
string sPathFrom = "";
string sPathTo = "";
for(auto const& value: vCustomActionData) {
if (i == 0) {
sBinPath = value;
sBinPath.append("bin\\");
} else if (i == 1) {
sPathFrom = value;
} else if (i == 2) {
sPathTo = value;
}
WcaLog(LOGMSG_STANDARD, value.c_str());
i++;
}
WcaLog(LOGMSG_STANDARD, sBinPath.c_str());
WcaLog(LOGMSG_STANDARD, sPathFrom.c_str());
WcaLog(LOGMSG_STANDARD, sPathTo.c_str());
stringstream ssPathFrom, ssPathTo;
ssPathFrom << sPathFrom;
ssPathTo << sPathTo;
vector<string> vPathFrom;
vector<string> vPathTo;
while(ssPathFrom.good()) {
string substr = "";
getline(ssPathFrom, substr, ';');
substr = substr.insert(0, sBinPath);
WcaLog(LOGMSG_STANDARD, substr.c_str());
vPathFrom.push_back(substr);
}
while(ssPathTo.good()) {
string substr = "";
getline(ssPathTo, substr, ';');
substr = substr.insert(0, sBinPath);
WcaLog(LOGMSG_STANDARD, substr.c_str());
vPathTo.push_back(substr);
}
i = 0;
for(auto const& value: vPathTo) {
string &sTmpPathFrom = vPathFrom[i];
string &sTmpPathTo = vPathTo[i];
sTmpPathFrom.append(".exe");
sTmpPathTo.append(".exe");
wstring wsPathFrom = s2ws(sTmpPathFrom);
LPCWSTR lPathFrom = wsPathFrom.c_str();
wstring wsPathTo = s2ws(sTmpPathTo);
LPCWSTR lPathTo = wsPathTo.c_str();
int createdSymlink = -1;
if (checkIfFileExists(wsPathFrom))
createdSymlink = CreateSymbolicLinkW(wsPathTo.c_str(), wsPathFrom.c_str(), 0);
string created = "Created symlink: ";
created.append(sTmpPathTo);
created.append(" --> ");
created.append(sTmpPathFrom);
created.append(", result= ");
created.append(to_string(createdSymlink));
WcaLog(LOGMSG_STANDARD, created.c_str());
i++;
}
ReleaseStr(installDir);
ReleaseStr(installerVersion);
ReleaseStr(binDir);
return WcaFinalize(er);
}
/* MDEV-19781 MariaDB symlinks on Windows */
extern "C" UINT __stdcall DeleteSymlinks(MSIHANDLE hInstall)
{
HRESULT hr = S_OK;
UINT er = ERROR_SUCCESS;
wchar_t customActionData[10000];
wchar_t installDir[MAX_PATH];
DWORD len = 10000;
DWORD size = MAX_VERSION_PROPERTY_SIZE;
wchar_t binDir[MAX_PATH];
size_t blen = NULL;
hr = WcaInitialize(hInstall, __FUNCTION__);
WcaLog(LOGMSG_STANDARD, "DeleteSymlinks initialized.");
if (MsiGetPropertyW(hInstall, L"CustomActionData", customActionData, &len) != ERROR_SUCCESS)
{
hr = HRESULT_FROM_WIN32(GetLastError());
MsiProcessMessage(hInstall, INSTALLMESSAGE_INFO, hr);
}
wstring wsCustomActionData(customActionData);
string sCustomActionData(wsCustomActionData.begin(), wsCustomActionData.end());
WcaLog(LOGMSG_STANDARD, sCustomActionData.c_str());
stringstream ss;
ss << sCustomActionData;
vector<string> vCustomActionData;
while( ss.good() )
{
string substr;
getline( ss, substr, '|' );
WcaLog(LOGMSG_STANDARD, substr.c_str());
vCustomActionData.push_back( substr );
}
int i = 0;
string sBinPath = "";
string sPathFrom = "";
string sPathTo = "";
for(auto const& value: vCustomActionData) {
if (i == 0) {
sBinPath = value;
sBinPath.append("bin\\");
} else if (i == 1) {
sPathFrom = value;
} else if (i == 2) {
sPathTo = value;
}
WcaLog(LOGMSG_STANDARD, value.c_str());
i++;
}
WcaLog(LOGMSG_STANDARD, sBinPath.c_str());
WcaLog(LOGMSG_STANDARD, sPathFrom.c_str());
WcaLog(LOGMSG_STANDARD, sPathTo.c_str());
stringstream ssPathFrom, ssPathTo;
ssPathFrom << sPathFrom;
ssPathTo << sPathTo;
vector<string> vPathFrom;
vector<string> vPathTo;
while(ssPathFrom.good()) {
string substr = "";
getline(ssPathFrom, substr, ';');
substr = substr.insert(0, sBinPath);
WcaLog(LOGMSG_STANDARD, substr.c_str());
vPathFrom.push_back(substr);
}
while(ssPathTo.good()) {
string substr = "";
getline(ssPathTo, substr, ';');
substr = substr.insert(0, sBinPath);
WcaLog(LOGMSG_STANDARD, substr.c_str());
vPathTo.push_back(substr);
}
i = 0;
for(auto const& value: vPathTo) {
string &sTmpPathFrom = vPathFrom[i];
string &sTmpPathTo = vPathTo[i];
sTmpPathFrom.append(".exe");
sTmpPathTo.append(".exe");
wstring wsPathFrom = s2ws(sTmpPathFrom);
LPCWSTR lPathFrom = wsPathFrom.c_str();
wstring wsPathTo = s2ws(sTmpPathTo);
LPCWSTR lPathTo = wsPathTo.c_str();
int deletedSymlink = -1;
if (checkIfFileExists(wsPathTo))
deletedSymlink = DeleteFileW(wsPathTo.c_str());
string deleted = "Deleted symlink: ";
deleted.append(sTmpPathTo);
deleted.append(" --> ");
deleted.append(sTmpPathFrom);
deleted.append(", result= ");
deleted.append(to_string(deletedSymlink));
WcaLog(LOGMSG_STANDARD, deleted.c_str());
i++;
}
/*
for(size_t i = 0; i < std::size(symlink_to); i++) {
wchar_t pathTo[MAX_PATH];
wcscpy(pathTo, binDir);
wcscat(pathTo, symlink_to[i].data());
wstring wsPathTo(pathTo);
if ( checkIfFileExists(wsPathTo) ) {
DeleteFileW(pathTo);
} else {
hr = HRESULT_FROM_WIN32(GetLastError());
ExitOnFailure(hr, "Could not delete symlink");
}
}
*/
ReleaseStr(installDir);
ReleaseStr(binDir);
return WcaFinalize(er);
}
\ No newline at end of file
......@@ -8,3 +8,5 @@ CheckDatabaseProperties
CheckDataDirectoryEmpty
CheckDBInUse
CheckServiceUpgrades
CreateSymlinks
DeleteSymlinks
# get the symlink lists
#INCLUDE(${CMAKE_SOURCE_DIR}/../../cmake/symlinks.cmake)
#INCLUDE(symlinks)
INCLUDE(${CMAKE_CURRENT_LIST_DIR}/../../cmake/symlinks.cmake)
MACRO(MAKE_WIX_IDENTIFIER str varname)
STRING(REPLACE "/" "." ${varname} "${str}")
STRING(REGEX REPLACE "[^a-zA-Z_0-9.]" "_" ${varname} "${${varname}}")
......
......@@ -59,6 +59,9 @@
<Property Id="BUFFERPOOLSIZE" Secure="yes"/>
<!-- Innodb page size -->
<Property Id="PAGESIZE" Secure="yes" Value="16K"/>
<!-- Symlinks -->
<Property Id="SYMLINK_TOS" Value="@MARIADB_SYMLINK_TOS@" />
<Property Id="SYMLINK_FROMS" Value="@MARIADB_SYMLINK_FROMS@" />
<CustomAction Id="LaunchUrl" BinaryKey="WixCA" DllEntry="WixShellExec" Execute="immediate" Return="check" Impersonate="yes" />
......@@ -597,6 +600,19 @@
<?endif ?>
<!-- Custom action, create symlinks -->
<CustomAction Id="CreateSymlinks.SetProperty" Return="check" Property="CreateSymlinks" Value="[INSTALLDIR]|[SYMLINK_FROMS]|[SYMLINK_TOS]" />
<CustomAction Id="CreateSymlinks" BinaryKey="wixca.dll" DllEntry="CreateSymlinks" Execute="deferred" Impersonate="no" Return="ignore" />
<CustomAction Id="DeleteSymlinks.SetProperty" Return="check" Property="DeleteSymlinks" Value="[INSTALLDIR]|[SYMLINK_FROMS]|[SYMLINK_TOS]" />
<CustomAction Id='DeleteSymlinks' BinaryKey="wixca.dll" DllEntry="DeleteSymlinks" Execute="deferred" Impersonate="no" Return="ignore" />
<InstallExecuteSequence>
<Custom Action="CreateSymlinks.SetProperty" Before="CreateSymlinks">NOT Installed</Custom>
<Custom Action="CreateSymlinks" Before="InstallFinalize">NOT Installed</Custom>
<Custom Action="DeleteSymlinks.SetProperty" Before="DeleteSymlinks">Installed AND NOT REINSTALL</Custom>
<Custom Action="DeleteSymlinks" Before="RemoveFiles">Installed AND NOT REINSTALL</Custom>
</InstallExecuteSequence>
<!-- Custom action, call mysql_install_db -->
<SetProperty Sequence='execute' Before='CreateDatabaseCommand' Id="SKIPNETWORKING" Value="--skip-networking" >SKIPNETWORKING</SetProperty>
<SetProperty Sequence='execute' Before='CreateDatabaseCommand' Id="ALLOWREMOTEROOTACCESS" Value="--allow-remote-root-access">ALLOWREMOTEROOTACCESS</SetProperty>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment