Merge abotchkov@work.mysql.com:/home/bk/mysql-4.1
into bisonxp.(none):/home/hf/work/mysql-4.1 BitKeeper/etc/logging_ok: auto-union sql/mysql_priv.h: Auto merged sql/sql_base.cc: Auto merged sql/sql_class.cc: Auto merged sql/sql_class.h: Auto merged sql/sql_handler.cc: Auto merged sql/sql_parse.cc: Auto merged sql/sql_select.cc: Auto merged sql/sql_show.cc: Auto merged sql/sql_table.cc: Auto merged
This commit is contained in:
commit
2da868d45c
@ -478,3 +478,4 @@ vio/test-ssl
|
|||||||
vio/test-sslclient
|
vio/test-sslclient
|
||||||
vio/test-sslserver
|
vio/test-sslserver
|
||||||
vio/viotest-ssl
|
vio/viotest-ssl
|
||||||
|
tests/client_test
|
||||||
|
@ -14,6 +14,7 @@ davida@isil.mysql.com
|
|||||||
heikki@donna.mysql.fi
|
heikki@donna.mysql.fi
|
||||||
heikki@hundin.mysql.fi
|
heikki@hundin.mysql.fi
|
||||||
hf@bison.(none)
|
hf@bison.(none)
|
||||||
|
hf@bisonxp.(none)
|
||||||
jani@dsl-jkl1657.dial.inet.fi
|
jani@dsl-jkl1657.dial.inet.fi
|
||||||
jani@hynda.(none)
|
jani@hynda.(none)
|
||||||
jani@hynda.mysql.fi
|
jani@hynda.mysql.fi
|
||||||
@ -66,7 +67,7 @@ tonu@x153.internalnet
|
|||||||
tonu@x3.internalnet
|
tonu@x3.internalnet
|
||||||
venu@myvenu.com
|
venu@myvenu.com
|
||||||
venu@work.mysql.com
|
venu@work.mysql.com
|
||||||
|
walrus@mysql.com
|
||||||
worm@altair.is.lan
|
worm@altair.is.lan
|
||||||
zak@balfor.local
|
zak@balfor.local
|
||||||
zak@linux.local
|
zak@linux.local
|
||||||
hf@bisonxp.(none)
|
|
||||||
|
@ -98,6 +98,14 @@ ha_checksum mi_unique_hash(MI_UNIQUEDEF *def, const byte *record)
|
|||||||
}
|
}
|
||||||
end= pos+length;
|
end= pos+length;
|
||||||
if (type == HA_KEYTYPE_TEXT || type == HA_KEYTYPE_VARTEXT)
|
if (type == HA_KEYTYPE_TEXT || type == HA_KEYTYPE_VARTEXT)
|
||||||
|
{
|
||||||
|
if (keyseg->charset->hash_sort)
|
||||||
|
{
|
||||||
|
ulong nr=1, nr2=4;
|
||||||
|
keyseg->charset->hash_sort(keyseg->charset,(const uchar*)pos,length,&nr, &nr2);
|
||||||
|
crc=nr;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
uchar *sort_order=keyseg->charset->sort_order;
|
uchar *sort_order=keyseg->charset->sort_order;
|
||||||
while (pos != end)
|
while (pos != end)
|
||||||
@ -105,6 +113,7 @@ ha_checksum mi_unique_hash(MI_UNIQUEDEF *def, const byte *record)
|
|||||||
(((uchar) sort_order[*(uchar*) pos++]))) +
|
(((uchar) sort_order[*(uchar*) pos++]))) +
|
||||||
(crc >> (8*sizeof(ha_checksum)-8));
|
(crc >> (8*sizeof(ha_checksum)-8));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
while (pos != end)
|
while (pos != end)
|
||||||
crc=((crc << 8) +
|
crc=((crc << 8) +
|
||||||
@ -172,6 +181,13 @@ int mi_unique_comp(MI_UNIQUEDEF *def, const byte *a, const byte *b,
|
|||||||
}
|
}
|
||||||
end= pos_a+length;
|
end= pos_a+length;
|
||||||
if (type == HA_KEYTYPE_TEXT || type == HA_KEYTYPE_VARTEXT)
|
if (type == HA_KEYTYPE_TEXT || type == HA_KEYTYPE_VARTEXT)
|
||||||
|
{
|
||||||
|
if (use_strcoll(keyseg->charset))
|
||||||
|
{
|
||||||
|
if (my_strnncoll(keyseg->charset,pos_a,length,pos_b,length))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
uchar *sort_order=keyseg->charset->sort_order;
|
uchar *sort_order=keyseg->charset->sort_order;
|
||||||
while (pos_a != end)
|
while (pos_a != end)
|
||||||
@ -179,6 +195,7 @@ int mi_unique_comp(MI_UNIQUEDEF *def, const byte *a, const byte *b,
|
|||||||
sort_order[*(uchar*) pos_b++])
|
sort_order[*(uchar*) pos_b++])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
while (pos_a != end)
|
while (pos_a != end)
|
||||||
if (*pos_a++ != *pos_b++)
|
if (*pos_a++ != *pos_b++)
|
||||||
|
@ -32,7 +32,7 @@ result_file=$RESULT_DIR/$test_name.result
|
|||||||
|
|
||||||
touch $result_file
|
touch $result_file
|
||||||
echo "Running the test case against empty file, will fail, but don't worry"
|
echo "Running the test case against empty file, will fail, but don't worry"
|
||||||
./mysql-test-run --do-test=$test_name
|
./mysql-test-run --local $test_name
|
||||||
|
|
||||||
reject_file=$result_file.reject
|
reject_file=$result_file.reject
|
||||||
|
|
||||||
|
1334
mysql-test/r/ctype_many.result
Normal file
1334
mysql-test/r/ctype_many.result
Normal file
File diff suppressed because it is too large
Load Diff
@ -65,6 +65,21 @@ a
|
|||||||
select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
|
select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
|
||||||
b (select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)
|
b (select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)
|
||||||
8 7.5000
|
8 7.5000
|
||||||
8 6.0000
|
8 4.5000
|
||||||
9 5.5000
|
9 7.5000
|
||||||
|
select * from t3 where exists (select * from t2 where t2.b=t3.a);
|
||||||
|
a
|
||||||
|
7
|
||||||
|
select * from t3 where not exists (select * from t2 where t2.b=t3.a);
|
||||||
|
a
|
||||||
|
6
|
||||||
|
3
|
||||||
|
insert into t4 values (12,7),(1,7),(10,9),(9,6),(7,6),(3,9);
|
||||||
|
select b,max(a) as ma from t4 group by b having b < (select max(t2.a)
|
||||||
|
from t2 where t2.b=t4.b);
|
||||||
|
b ma
|
||||||
|
select b,max(a) as ma from t4 group by b having b >= (select max(t2.a)
|
||||||
|
from t2 where t2.b=t4.b);
|
||||||
|
b ma
|
||||||
|
7 12
|
||||||
drop table t1,t2,t3,t4;
|
drop table t1,t2,t3,t4;
|
||||||
|
189
mysql-test/t/ctype_many.test
Normal file
189
mysql-test/t/ctype_many.test
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
comment CHAR(32) CHARACTER SET latin1 NOT NULL,
|
||||||
|
koi8_ru_f CHAR(32) CHARACTER SET koi8_ru NOT NULL
|
||||||
|
) CHARSET=latin5;
|
||||||
|
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
ALTER TABLE t1 CHANGE comment comment CHAR(32) CHARACTER SET latin2 NOT NULL;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
ALTER TABLE t1 ADD latin5_f CHAR(32) NOT NULL;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
ALTER TABLE t1 CHARSET=latin2;
|
||||||
|
ALTER TABLE t1 ADD latin2_f CHAR(32) NOT NULL;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
ALTER TABLE t1 DROP latin2_f, DROP latin5_f;
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('a','LAT SMALL A');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('b','LAT SMALL B');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('c','LAT SMALL C');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('d','LAT SMALL D');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('e','LAT SMALL E');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('f','LAT SMALL F');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('g','LAT SMALL G');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('h','LAT SMALL H');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('i','LAT SMALL I');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('j','LAT SMALL J');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('k','LAT SMALL K');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('l','LAT SMALL L');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('m','LAT SMALL M');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('n','LAT SMALL N');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('o','LAT SMALL O');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('p','LAT SMALL P');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('q','LAT SMALL Q');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('r','LAT SMALL R');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('s','LAT SMALL S');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('t','LAT SMALL T');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('u','LAT SMALL U');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('v','LAT SMALL V');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('w','LAT SMALL W');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('x','LAT SMALL X');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('y','LAT SMALL Y');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('z','LAT SMALL Z');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('A','LAT CAPIT A');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('B','LAT CAPIT B');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('C','LAT CAPIT C');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('D','LAT CAPIT D');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('E','LAT CAPIT E');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('F','LAT CAPIT F');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('G','LAT CAPIT G');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('H','LAT CAPIT H');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('I','LAT CAPIT I');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('J','LAT CAPIT J');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('K','LAT CAPIT K');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('L','LAT CAPIT L');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('M','LAT CAPIT M');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('N','LAT CAPIT N');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('O','LAT CAPIT O');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('P','LAT CAPIT P');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Q','LAT CAPIT Q');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('R','LAT CAPIT R');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('S','LAT CAPIT S');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('T','LAT CAPIT T');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('U','LAT CAPIT U');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('V','LAT CAPIT V');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('W','LAT CAPIT W');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('X','LAT CAPIT X');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Y','LAT CAPIT Y');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Z','LAT CAPIT Z');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Á','CYR SMALL A');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Â','CYR SMALL BE');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('×','CYR SMALL VE');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Ç','CYR SMALL GE');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Ä','CYR SMALL DE');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Å','CYR SMALL IE');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('£','CYR SMALL IO');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Ö','CYR SMALL ZHE');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Ú','CYR SMALL ZE');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('É','CYR SMALL I');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Ë','CYR SMALL KA');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Ì','CYR SMALL EL');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Í','CYR SMALL EM');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Î','CYR SMALL EN');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Ï','CYR SMALL O');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Ð','CYR SMALL PE');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Ò','CYR SMALL ER');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Ó','CYR SMALL ES');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Ô','CYR SMALL TE');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Õ','CYR SMALL U');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Æ','CYR SMALL EF');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('È','CYR SMALL HA');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Ã','CYR SMALL TSE');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Þ','CYR SMALL CHE');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Û','CYR SMALL SHA');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Ý','CYR SMALL SCHA');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('ß','CYR SMALL HARD SIGN');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Ù','CYR SMALL YERU');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Ø','CYR SMALL SOFT SIGN');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Ü','CYR SMALL E');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('À','CYR SMALL YU');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('Ñ','CYR SMALL YA');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('á','CYR CAPIT A');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('â','CYR CAPIT BE');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('÷','CYR CAPIT VE');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('ç','CYR CAPIT GE');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('ä','CYR CAPIT DE');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('å','CYR CAPIT IE');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('³','CYR CAPIT IO');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('ö','CYR CAPIT ZHE');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('ú','CYR CAPIT ZE');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('é','CYR CAPIT I');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('ë','CYR CAPIT KA');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('ì','CYR CAPIT EL');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('í','CYR CAPIT EM');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('î','CYR CAPIT EN');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('ï','CYR CAPIT O');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('ð','CYR CAPIT PE');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('ò','CYR CAPIT ER');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('ó','CYR CAPIT ES');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('ô','CYR CAPIT TE');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('õ','CYR CAPIT U');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('æ','CYR CAPIT EF');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('è','CYR CAPIT HA');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('ã','CYR CAPIT TSE');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('þ','CYR CAPIT CHE');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('û','CYR CAPIT SHA');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('ý','CYR CAPIT SCHA');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('ÿ','CYR CAPIT HARD SIGN');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('ù','CYR CAPIT YERU');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('ø','CYR CAPIT SOFT SIGN');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('ü','CYR CAPIT E');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('à','CYR CAPIT YU');
|
||||||
|
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('ñ','CYR CAPIT YA');
|
||||||
|
|
||||||
|
ALTER TABLE t1 ADD utf8_f CHAR(32) CHARACTER SET utf8 NOT NULL;
|
||||||
|
UPDATE t1 SET utf8_f=CONVERT(koi8_ru_f USING utf8);
|
||||||
|
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
SELECT koi8_ru_f,MIN(comment) FROM t1 GROUP BY 1;
|
||||||
|
SELECT utf8_f,MIN(comment) FROM t1 GROUP BY 1;
|
||||||
|
SELECT DISTINCT koi8_ru_f FROM t1;
|
||||||
|
SELECT DISTINCT utf8_f FROM t1;
|
||||||
|
SELECT lower(koi8_ru_f) FROM t1 ORDER BY 1 DESC;
|
||||||
|
SELECT lower(utf8_f) FROM t1 ORDER BY 1 DESC;
|
||||||
|
|
||||||
|
SELECT t11.comment,t12.comment
|
||||||
|
FROM t1 t11,t1 t12 WHERE CONVERT(t11.koi8_ru_f USING utf8)=t12.utf8_f
|
||||||
|
ORDER BY t11.koi8_ru_f;
|
||||||
|
|
||||||
|
SELECT t11.comment,t12.comment
|
||||||
|
FROM t1 t11,t1 t12
|
||||||
|
WHERE t11.koi8_ru_f=CONVERT(t12.utf8_f USING koi8_ru)
|
||||||
|
ORDER BY t12.utf8_f;
|
||||||
|
|
||||||
|
ALTER TABLE t1 ADD ucs2_f CHAR(32) CHARACTER SET ucs2 NOT NULL;
|
||||||
|
|
||||||
|
INSERT INTO t1 (ucs2_f,comment) VALUES (0x0391,'GREEK CAPIT ALPHA');
|
||||||
|
INSERT INTO t1 (ucs2_f,comment) VALUES (0x0392,'GREEK CAPIT BETA');
|
||||||
|
INSERT INTO t1 (ucs2_f,comment) VALUES (0x0393,'GREEK CAPIT GAMMA');
|
||||||
|
INSERT INTO t1 (ucs2_f,comment) VALUES (0x0394,'GREEK CAPIT DELTA');
|
||||||
|
INSERT INTO t1 (ucs2_f,comment) VALUES (0x0395,'GREEK CAPIT EPSILON');
|
||||||
|
INSERT INTO t1 (ucs2_f,comment) VALUES (0x03B1,'GREEK SMALL ALPHA');
|
||||||
|
INSERT INTO t1 (ucs2_f,comment) VALUES (0x03B2,'GREEK SMALL BETA');
|
||||||
|
INSERT INTO t1 (ucs2_f,comment) VALUES (0x03B3,'GREEK SMALL GAMMA');
|
||||||
|
INSERT INTO t1 (ucs2_f,comment) VALUES (0x03B4,'GREEK SMALL DELTA');
|
||||||
|
INSERT INTO t1 (ucs2_f,comment) VALUES (0x03B5,'GREEK SMALL EPSILON');
|
||||||
|
INSERT INTO t1 (ucs2_f,comment) VALUES (0x0531,'ARMENIAN CAPIT AYB');
|
||||||
|
INSERT INTO t1 (ucs2_f,comment) VALUES (0x0532,'ARMENIAN CAPIT BEN');
|
||||||
|
INSERT INTO t1 (ucs2_f,comment) VALUES (0x0533,'ARMENIAN CAPIT GIM');
|
||||||
|
INSERT INTO t1 (ucs2_f,comment) VALUES (0x0534,'ARMENIAN CAPIT DA');
|
||||||
|
INSERT INTO t1 (ucs2_f,comment) VALUES (0x0535,'ARMENIAN CAPIT ECH');
|
||||||
|
INSERT INTO t1 (ucs2_f,comment) VALUES (0x0536,'ARMENIAN CAPIT ZA');
|
||||||
|
INSERT INTO t1 (ucs2_f,comment) VALUES (0x0561,'ARMENIAN SMALL YAB');
|
||||||
|
INSERT INTO t1 (ucs2_f,comment) VALUES (0x0562,'ARMENIAN SMALL BEN');
|
||||||
|
INSERT INTO t1 (ucs2_f,comment) VALUES (0x0563,'ARMENIAN SMALL GIM');
|
||||||
|
INSERT INTO t1 (ucs2_f,comment) VALUES (0x0564,'ARMENIAN SMALL DA');
|
||||||
|
INSERT INTO t1 (ucs2_f,comment) VALUES (0x0565,'ARMENIAN SMALL ECH');
|
||||||
|
INSERT INTO t1 (ucs2_f,comment) VALUES (0x0566,'ARMENIAN SMALL ZA');
|
||||||
|
|
||||||
|
ALTER TABLE t1 ADD armscii8_f CHAR(32) CHARACTER SET armscii8 NOT NULL;
|
||||||
|
ALTER TABLE t1 ADD greek_f CHAR(32) CHARACTER SET greek NOT NULL;
|
||||||
|
UPDATE t1 SET greek_f=CONVERT(ucs2_f USING greek) WHERE comment LIKE 'GRE%';
|
||||||
|
UPDATE t1 SET armscii8_f=CONVERT(ucs2_f USING armscii8) WHERE comment LIKE 'ARM%';
|
||||||
|
UPDATE t1 SET utf8_f=CONVERT(ucs2_f USING utf8) WHERE utf8_f='';
|
||||||
|
UPDATE t1 SET ucs2_f=CONVERT(utf8_f USING ucs2) WHERE ucs2_f='';
|
||||||
|
SELECT min(comment),count(*) FROM t1 GROUP BY ucs2_f;
|
||||||
|
DROP TABLE t1;
|
@ -26,4 +26,11 @@ select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from
|
|||||||
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3 where t3.a > t1.a) order by 1 desc limit 1);
|
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3 where t3.a > t1.a) order by 1 desc limit 1);
|
||||||
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3 where t3.a < t1.a) order by 1 desc limit 1);
|
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3 where t3.a < t1.a) order by 1 desc limit 1);
|
||||||
select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
|
select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
|
||||||
|
select * from t3 where exists (select * from t2 where t2.b=t3.a);
|
||||||
|
select * from t3 where not exists (select * from t2 where t2.b=t3.a);
|
||||||
|
insert into t4 values (12,7),(1,7),(10,9),(9,6),(7,6),(3,9);
|
||||||
|
select b,max(a) as ma from t4 group by b having b < (select max(t2.a)
|
||||||
|
from t2 where t2.b=t4.b);
|
||||||
|
select b,max(a) as ma from t4 group by b having b >= (select max(t2.a)
|
||||||
|
from t2 where t2.b=t4.b);
|
||||||
drop table t1,t2,t3,t4;
|
drop table t1,t2,t3,t4;
|
||||||
|
@ -115,7 +115,6 @@ sub new
|
|||||||
$self->{'data_source'} = "DBI:mysql:database=$database;host=$host";
|
$self->{'data_source'} = "DBI:mysql:database=$database;host=$host";
|
||||||
$self->{'data_source'} .= ";mysql_socket=$socket" if($socket);
|
$self->{'data_source'} .= ";mysql_socket=$socket" if($socket);
|
||||||
$self->{'limits'} = \%limits;
|
$self->{'limits'} = \%limits;
|
||||||
$self->{'smds'} = \%smds;
|
|
||||||
$self->{'blob'} = "blob";
|
$self->{'blob'} = "blob";
|
||||||
$self->{'text'} = "text";
|
$self->{'text'} = "text";
|
||||||
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
|
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
|
||||||
@ -168,25 +167,6 @@ sub new
|
|||||||
$limits{'working_all_fields'} = 1;
|
$limits{'working_all_fields'} = 1;
|
||||||
$limits{'working_blobs'} = 1; # If big varchar/blobs works
|
$limits{'working_blobs'} = 1; # If big varchar/blobs works
|
||||||
|
|
||||||
$smds{'time'} = 1;
|
|
||||||
$smds{'q1'} = 'b'; # with time not supp by mysql ('')
|
|
||||||
$smds{'q2'} = 'b';
|
|
||||||
$smds{'q3'} = 'b'; # with time ('')
|
|
||||||
$smds{'q4'} = 'c'; # with time not supp by mysql (d)
|
|
||||||
$smds{'q5'} = 'b'; # with time not supp by mysql ('')
|
|
||||||
$smds{'q6'} = 'c'; # with time not supp by mysql ('')
|
|
||||||
$smds{'q7'} = 'c';
|
|
||||||
$smds{'q8'} = 'f';
|
|
||||||
$smds{'q9'} = 'c';
|
|
||||||
$smds{'q10'} = 'b';
|
|
||||||
$smds{'q11'} = 'b';
|
|
||||||
$smds{'q12'} = 'd';
|
|
||||||
$smds{'q13'} = 'c';
|
|
||||||
$smds{'q14'} = 'd';
|
|
||||||
$smds{'q15'} = 'd';
|
|
||||||
$smds{'q16'} = 'a';
|
|
||||||
$smds{'q17'} = 'c';
|
|
||||||
|
|
||||||
# Some fixes that depends on the environment
|
# Some fixes that depends on the environment
|
||||||
if (defined($main::opt_create_options) &&
|
if (defined($main::opt_create_options) &&
|
||||||
$main::opt_create_options =~ /type=heap/i)
|
$main::opt_create_options =~ /type=heap/i)
|
||||||
@ -199,6 +179,11 @@ sub new
|
|||||||
$limits{'max_text_size'} = 8000; # Limit in Innobase
|
$limits{'max_text_size'} = 8000; # Limit in Innobase
|
||||||
$self->{'transactions'} = 1; # Transactions enabled
|
$self->{'transactions'} = 1; # Transactions enabled
|
||||||
}
|
}
|
||||||
|
if (defined($main::opt_create_options) &&
|
||||||
|
$main::opt_create_options =~ /type=bdb/i)
|
||||||
|
{
|
||||||
|
$self->{'transactions'} = 1; # Transactions enabled
|
||||||
|
}
|
||||||
if (defined($main::opt_create_options) &&
|
if (defined($main::opt_create_options) &&
|
||||||
$main::opt_create_options =~ /type=gemini/i)
|
$main::opt_create_options =~ /type=gemini/i)
|
||||||
{
|
{
|
||||||
@ -266,7 +251,6 @@ sub create
|
|||||||
{
|
{
|
||||||
$field =~ s/ decimal/ double(10,2)/i;
|
$field =~ s/ decimal/ double(10,2)/i;
|
||||||
$field =~ s/ big_decimal/ double(10,2)/i;
|
$field =~ s/ big_decimal/ double(10,2)/i;
|
||||||
$field =~ s/ date/ int/i; # Because of tcp ?
|
|
||||||
$query.= $field . ',';
|
$query.= $field . ',';
|
||||||
}
|
}
|
||||||
foreach $index (@$index)
|
foreach $index (@$index)
|
||||||
@ -575,7 +559,6 @@ sub new
|
|||||||
$self->{'cmp_name'} = "pg";
|
$self->{'cmp_name'} = "pg";
|
||||||
$self->{'data_source'} = "DBI:Pg:dbname=$database";
|
$self->{'data_source'} = "DBI:Pg:dbname=$database";
|
||||||
$self->{'limits'} = \%limits;
|
$self->{'limits'} = \%limits;
|
||||||
$self->{'smds'} = \%smds;
|
|
||||||
$self->{'blob'} = "text";
|
$self->{'blob'} = "text";
|
||||||
$self->{'text'} = "text";
|
$self->{'text'} = "text";
|
||||||
$self->{'double_quotes'} = 1;
|
$self->{'double_quotes'} = 1;
|
||||||
@ -626,27 +609,6 @@ sub new
|
|||||||
$limits{'working_all_fields'} = 1;
|
$limits{'working_all_fields'} = 1;
|
||||||
$limits{'working_blobs'} = 1; # If big varchar/blobs works
|
$limits{'working_blobs'} = 1; # If big varchar/blobs works
|
||||||
|
|
||||||
# the different cases per query ...
|
|
||||||
$smds{'q1'} = 'b'; # with time
|
|
||||||
$smds{'q2'} = 'b';
|
|
||||||
$smds{'q3'} = 'b'; # with time
|
|
||||||
$smds{'q4'} = 'c'; # with time
|
|
||||||
$smds{'q5'} = 'b'; # with time
|
|
||||||
$smds{'q6'} = 'c'; # strange error ....
|
|
||||||
$smds{'q7'} = 'c';
|
|
||||||
$smds{'q8'} = 'f'; # needs 128M to execute - can't do insert ...group by
|
|
||||||
$smds{'q9'} = 'c';
|
|
||||||
$smds{'q10'} = 'b';
|
|
||||||
$smds{'q11'} = 'b'; # can't do float8 * int4 - create operator
|
|
||||||
$smds{'q12'} = 'd'; # strange error???
|
|
||||||
$smds{'q13'} = 'c';
|
|
||||||
$smds{'q14'} = 'd'; # strange error???
|
|
||||||
$smds{'q15'} = 'd'; # strange error???
|
|
||||||
$smds{'q16'} = 'a';
|
|
||||||
$smds{'q17'} = 'c';
|
|
||||||
$smds{'time'} = 1; # the use of the time table -> 1 is on.
|
|
||||||
# when 0 then the date field must be a
|
|
||||||
# date field not a int field!!!
|
|
||||||
return $self;
|
return $self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -871,7 +833,6 @@ sub new
|
|||||||
$self->{'cmp_name'} = "solid";
|
$self->{'cmp_name'} = "solid";
|
||||||
$self->{'data_source'} = "DBI:Solid:";
|
$self->{'data_source'} = "DBI:Solid:";
|
||||||
$self->{'limits'} = \%limits;
|
$self->{'limits'} = \%limits;
|
||||||
$self->{'smds'} = \%smds;
|
|
||||||
$self->{'blob'} = "long varchar";
|
$self->{'blob'} = "long varchar";
|
||||||
$self->{'text'} = "long varchar";
|
$self->{'text'} = "long varchar";
|
||||||
$self->{'double_quotes'} = 1;
|
$self->{'double_quotes'} = 1;
|
||||||
@ -922,28 +883,6 @@ sub new
|
|||||||
$limits{'order_by_unused'} = 1;
|
$limits{'order_by_unused'} = 1;
|
||||||
$limits{'working_all_fields'} = 1;
|
$limits{'working_all_fields'} = 1;
|
||||||
|
|
||||||
# for the smds small benchmark test ....
|
|
||||||
# the different cases per query ...
|
|
||||||
$smds{'q1'} = 'a';
|
|
||||||
$smds{'q2'} = '';
|
|
||||||
$smds{'q3'} = 'b'; #doesn't work -> strange error about column -fixed
|
|
||||||
$smds{'q4'} = 'a';
|
|
||||||
$smds{'q5'} = 'b';
|
|
||||||
$smds{'q6'} = 'c';
|
|
||||||
$smds{'q7'} = 'b';
|
|
||||||
$smds{'q8'} = 'f';
|
|
||||||
$smds{'q9'} = 'b';
|
|
||||||
$smds{'q10'} = 'b';
|
|
||||||
$smds{'q11'} = '';
|
|
||||||
$smds{'q12'} = 'd';
|
|
||||||
$smds{'q13'} = 'b';
|
|
||||||
$smds{'q14'} = 'd';
|
|
||||||
$smds{'q15'} = 'd';
|
|
||||||
$smds{'q16'} = '';
|
|
||||||
$smds{'q17'} = '';
|
|
||||||
$smds{'time'} = 1; # the use of the time table -> 1 is on.
|
|
||||||
# when 0 then the date field must be a
|
|
||||||
# date field not a int field!!!
|
|
||||||
return $self;
|
return $self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1119,7 +1058,6 @@ sub new
|
|||||||
$self->{'cmp_name'} = "empress";
|
$self->{'cmp_name'} = "empress";
|
||||||
$self->{'data_source'} = "DBI:EmpressNet:SERVER=$host;Database=/usr/local/empress/rdbms/bin/$database";
|
$self->{'data_source'} = "DBI:EmpressNet:SERVER=$host;Database=/usr/local/empress/rdbms/bin/$database";
|
||||||
$self->{'limits'} = \%limits;
|
$self->{'limits'} = \%limits;
|
||||||
$self->{'smds'} = \%smds;
|
|
||||||
$self->{'blob'} = "text";
|
$self->{'blob'} = "text";
|
||||||
$self->{'text'} = "text";
|
$self->{'text'} = "text";
|
||||||
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
|
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
|
||||||
@ -1172,28 +1110,6 @@ sub new
|
|||||||
$limits{'order_by_unused'} = 1;
|
$limits{'order_by_unused'} = 1;
|
||||||
$limits{'working_all_fields'} = 1;
|
$limits{'working_all_fields'} = 1;
|
||||||
|
|
||||||
# for the smds small benchmark test ....
|
|
||||||
# the different cases per query ... EMPRESS
|
|
||||||
$smds{'q1'} = 'a';
|
|
||||||
$smds{'q2'} = '';
|
|
||||||
$smds{'q3'} = 'a';
|
|
||||||
$smds{'q4'} = 'a';
|
|
||||||
$smds{'q5'} = 'a';
|
|
||||||
$smds{'q6'} = 'a';
|
|
||||||
$smds{'q7'} = 'b';
|
|
||||||
$smds{'q8'} = 'd';
|
|
||||||
$smds{'q9'} = 'b';
|
|
||||||
$smds{'q10'} = 'a';
|
|
||||||
$smds{'q11'} = '';
|
|
||||||
$smds{'q12'} = 'd';
|
|
||||||
$smds{'q13'} = 'b';
|
|
||||||
$smds{'q14'} = 'b';
|
|
||||||
$smds{'q15'} = 'a';
|
|
||||||
$smds{'q16'} = '';
|
|
||||||
$smds{'q17'} = '';
|
|
||||||
$smds{'time'} = 1; # the use of the time table -> 1 is on.
|
|
||||||
# when 0 then the date field must be a
|
|
||||||
# date field not a int field!!!
|
|
||||||
return $self;
|
return $self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1410,7 +1326,6 @@ sub new
|
|||||||
$self->{'cmp_name'} = "Oracle";
|
$self->{'cmp_name'} = "Oracle";
|
||||||
$self->{'data_source'} = "DBI:Oracle:$database";
|
$self->{'data_source'} = "DBI:Oracle:$database";
|
||||||
$self->{'limits'} = \%limits;
|
$self->{'limits'} = \%limits;
|
||||||
$self->{'smds'} = \%smds;
|
|
||||||
$self->{'blob'} = "long";
|
$self->{'blob'} = "long";
|
||||||
$self->{'text'} = "long";
|
$self->{'text'} = "long";
|
||||||
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
|
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
|
||||||
@ -1464,24 +1379,6 @@ sub new
|
|||||||
$limits{'order_by_unused'} = 1;
|
$limits{'order_by_unused'} = 1;
|
||||||
$limits{'working_all_fields'} = 1;
|
$limits{'working_all_fields'} = 1;
|
||||||
|
|
||||||
$smds{'time'} = 1;
|
|
||||||
$smds{'q1'} = 'b'; # with time not supp by mysql ('')
|
|
||||||
$smds{'q2'} = 'b';
|
|
||||||
$smds{'q3'} = 'b'; # with time ('')
|
|
||||||
$smds{'q4'} = 'c'; # with time not supp by mysql (d)
|
|
||||||
$smds{'q5'} = 'b'; # with time not supp by mysql ('')
|
|
||||||
$smds{'q6'} = 'c'; # with time not supp by mysql ('')
|
|
||||||
$smds{'q7'} = 'c';
|
|
||||||
$smds{'q8'} = 'f';
|
|
||||||
$smds{'q9'} = 'c';
|
|
||||||
$smds{'q10'} = 'b';
|
|
||||||
$smds{'q11'} = 'b';
|
|
||||||
$smds{'q12'} = 'd';
|
|
||||||
$smds{'q13'} = 'c';
|
|
||||||
$smds{'q14'} = 'd';
|
|
||||||
$smds{'q15'} = 'd';
|
|
||||||
$smds{'q16'} = 'a';
|
|
||||||
$smds{'q17'} = 'c';
|
|
||||||
|
|
||||||
return $self;
|
return $self;
|
||||||
}
|
}
|
||||||
@ -1675,7 +1572,6 @@ sub new
|
|||||||
$self->{'cmp_name'} = "Informix";
|
$self->{'cmp_name'} = "Informix";
|
||||||
$self->{'data_source'} = "DBI:Informix:$database";
|
$self->{'data_source'} = "DBI:Informix:$database";
|
||||||
$self->{'limits'} = \%limits;
|
$self->{'limits'} = \%limits;
|
||||||
$self->{'smds'} = \%smds;
|
|
||||||
$self->{'blob'} = "byte in table";
|
$self->{'blob'} = "byte in table";
|
||||||
$self->{'text'} = "byte in table";
|
$self->{'text'} = "byte in table";
|
||||||
$self->{'double_quotes'} = 0; # Can handle: 'Walker''s'
|
$self->{'double_quotes'} = 0; # Can handle: 'Walker''s'
|
||||||
@ -1888,7 +1784,6 @@ sub new
|
|||||||
$self->{'data_source'} .= ":$host";
|
$self->{'data_source'} .= ":$host";
|
||||||
}
|
}
|
||||||
$self->{'limits'} = \%limits;
|
$self->{'limits'} = \%limits;
|
||||||
$self->{'smds'} = \%smds;
|
|
||||||
$self->{'blob'} = "blob";
|
$self->{'blob'} = "blob";
|
||||||
$self->{'text'} = "blob"; # text ?
|
$self->{'text'} = "blob"; # text ?
|
||||||
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
|
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
|
||||||
@ -2071,7 +1966,6 @@ sub new
|
|||||||
$self->{'data_source'} .= ":$host";
|
$self->{'data_source'} .= ":$host";
|
||||||
}
|
}
|
||||||
$self->{'limits'} = \%limits;
|
$self->{'limits'} = \%limits;
|
||||||
$self->{'smds'} = \%smds;
|
|
||||||
$self->{'blob'} = "text";
|
$self->{'blob'} = "text";
|
||||||
$self->{'text'} = "text";
|
$self->{'text'} = "text";
|
||||||
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
|
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
|
||||||
@ -2264,7 +2158,6 @@ sub new
|
|||||||
$self->{'data_source'} .= ";hostname=$host";
|
$self->{'data_source'} .= ";hostname=$host";
|
||||||
}
|
}
|
||||||
$self->{'limits'} = \%limits;
|
$self->{'limits'} = \%limits;
|
||||||
$self->{'smds'} = \%smds;
|
|
||||||
$self->{'blob'} = "text";
|
$self->{'blob'} = "text";
|
||||||
$self->{'text'} = "text";
|
$self->{'text'} = "text";
|
||||||
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
|
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
|
||||||
@ -2497,7 +2390,6 @@ sub new
|
|||||||
$self->{'cmp_name'} = "Adabas";
|
$self->{'cmp_name'} = "Adabas";
|
||||||
$self->{'data_source'} = "DBI:Adabas:$database";
|
$self->{'data_source'} = "DBI:Adabas:$database";
|
||||||
$self->{'limits'} = \%limits;
|
$self->{'limits'} = \%limits;
|
||||||
$self->{'smds'} = \%smds;
|
|
||||||
$self->{'blob'} = "long";
|
$self->{'blob'} = "long";
|
||||||
$self->{'text'} = "long";
|
$self->{'text'} = "long";
|
||||||
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
|
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
|
||||||
@ -2549,24 +2441,6 @@ sub new
|
|||||||
$limits{'order_by_unused'} = 1;
|
$limits{'order_by_unused'} = 1;
|
||||||
$limits{'working_all_fields'} = 1;
|
$limits{'working_all_fields'} = 1;
|
||||||
|
|
||||||
$smds{'time'} = 1;
|
|
||||||
$smds{'q1'} = 'b'; # with time not supp by mysql ('')
|
|
||||||
$smds{'q2'} = 'b';
|
|
||||||
$smds{'q3'} = 'b'; # with time ('')
|
|
||||||
$smds{'q4'} = 'c'; # with time not supp by mysql (d)
|
|
||||||
$smds{'q5'} = 'b'; # with time not supp by mysql ('')
|
|
||||||
$smds{'q6'} = 'c'; # with time not supp by mysql ('')
|
|
||||||
$smds{'q7'} = 'c';
|
|
||||||
$smds{'q8'} = 'f';
|
|
||||||
$smds{'q9'} = 'c';
|
|
||||||
$smds{'q10'} = 'b';
|
|
||||||
$smds{'q11'} = 'b';
|
|
||||||
$smds{'q12'} = 'd';
|
|
||||||
$smds{'q13'} = 'c';
|
|
||||||
$smds{'q14'} = 'd';
|
|
||||||
$smds{'q15'} = 'd';
|
|
||||||
$smds{'q16'} = 'a';
|
|
||||||
$smds{'q17'} = 'c';
|
|
||||||
|
|
||||||
return $self;
|
return $self;
|
||||||
}
|
}
|
||||||
@ -2718,7 +2592,6 @@ sub new
|
|||||||
$self->{'data_source'} .= ":$host";
|
$self->{'data_source'} .= ":$host";
|
||||||
}
|
}
|
||||||
$self->{'limits'} = \%limits;
|
$self->{'limits'} = \%limits;
|
||||||
$self->{'smds'} = \%smds;
|
|
||||||
$self->{'blob'} = "varchar(255)";
|
$self->{'blob'} = "varchar(255)";
|
||||||
$self->{'text'} = "varchar(255)";
|
$self->{'text'} = "varchar(255)";
|
||||||
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
|
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
|
||||||
@ -2894,7 +2767,6 @@ sub new
|
|||||||
$self->{'cmp_name'} = "mimer";
|
$self->{'cmp_name'} = "mimer";
|
||||||
$self->{'data_source'} = "DBI:mimer:$database:$host";
|
$self->{'data_source'} = "DBI:mimer:$database:$host";
|
||||||
$self->{'limits'} = \%limits;
|
$self->{'limits'} = \%limits;
|
||||||
$self->{'smds'} = \%smds;
|
|
||||||
$self->{'blob'} = "binary varying(15000)";
|
$self->{'blob'} = "binary varying(15000)";
|
||||||
$self->{'text'} = "character varying(15000)";
|
$self->{'text'} = "character varying(15000)";
|
||||||
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
|
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
|
||||||
@ -2950,24 +2822,6 @@ sub new
|
|||||||
$limits{'order_by_unused'} = 1;
|
$limits{'order_by_unused'} = 1;
|
||||||
$limits{'working_all_fields'} = 1;
|
$limits{'working_all_fields'} = 1;
|
||||||
|
|
||||||
$smds{'time'} = 1;
|
|
||||||
$smds{'q1'} = 'b'; # with time not supp by mysql ('')
|
|
||||||
$smds{'q2'} = 'b';
|
|
||||||
$smds{'q3'} = 'b'; # with time ('')
|
|
||||||
$smds{'q4'} = 'c'; # with time not supp by mysql (d)
|
|
||||||
$smds{'q5'} = 'b'; # with time not supp by mysql ('')
|
|
||||||
$smds{'q6'} = 'c'; # with time not supp by mysql ('')
|
|
||||||
$smds{'q7'} = 'c';
|
|
||||||
$smds{'q8'} = 'f';
|
|
||||||
$smds{'q9'} = 'c';
|
|
||||||
$smds{'q10'} = 'b';
|
|
||||||
$smds{'q11'} = 'b';
|
|
||||||
$smds{'q12'} = 'd';
|
|
||||||
$smds{'q13'} = 'c';
|
|
||||||
$smds{'q14'} = 'd';
|
|
||||||
$smds{'q15'} = 'd';
|
|
||||||
$smds{'q16'} = 'a';
|
|
||||||
$smds{'q17'} = 'c';
|
|
||||||
return $self;
|
return $self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3112,7 +2966,6 @@ sub new
|
|||||||
$self->{'cmp_name'} = "interbase";
|
$self->{'cmp_name'} = "interbase";
|
||||||
$self->{'data_source'} = "DBI:InterBase:database=$database:ib_dialect=3";
|
$self->{'data_source'} = "DBI:InterBase:database=$database:ib_dialect=3";
|
||||||
$self->{'limits'} = \%limits;
|
$self->{'limits'} = \%limits;
|
||||||
$self->{'smds'} = \%smds;
|
|
||||||
$self->{'blob'} = "blob";
|
$self->{'blob'} = "blob";
|
||||||
$self->{'text'} = "";
|
$self->{'text'} = "";
|
||||||
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
|
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
|
||||||
@ -3166,24 +3019,6 @@ sub new
|
|||||||
$limits{'order_by_unused'} = 1;
|
$limits{'order_by_unused'} = 1;
|
||||||
$limits{'working_all_fields'} = 1;
|
$limits{'working_all_fields'} = 1;
|
||||||
|
|
||||||
$smds{'time'} = 1;
|
|
||||||
$smds{'q1'} = 'b'; # with time not supp by mysql ('')
|
|
||||||
$smds{'q2'} = 'b';
|
|
||||||
$smds{'q3'} = 'b'; # with time ('')
|
|
||||||
$smds{'q4'} = 'c'; # with time not supp by mysql (d)
|
|
||||||
$smds{'q5'} = 'b'; # with time not supp by mysql ('')
|
|
||||||
$smds{'q6'} = 'c'; # with time not supp by mysql ('')
|
|
||||||
$smds{'q7'} = 'c';
|
|
||||||
$smds{'q8'} = 'f';
|
|
||||||
$smds{'q9'} = 'c';
|
|
||||||
$smds{'q10'} = 'b';
|
|
||||||
$smds{'q11'} = 'b';
|
|
||||||
$smds{'q12'} = 'd';
|
|
||||||
$smds{'q13'} = 'c';
|
|
||||||
$smds{'q14'} = 'd';
|
|
||||||
$smds{'q15'} = 'd';
|
|
||||||
$smds{'q16'} = 'a';
|
|
||||||
$smds{'q17'} = 'c';
|
|
||||||
|
|
||||||
return $self;
|
return $self;
|
||||||
}
|
}
|
||||||
@ -3331,7 +3166,6 @@ sub new
|
|||||||
$self->{'cmp_name'} = "FrontBase";
|
$self->{'cmp_name'} = "FrontBase";
|
||||||
$self->{'data_source'} = "DBI:FB:dbname=$database;host=$host";
|
$self->{'data_source'} = "DBI:FB:dbname=$database;host=$host";
|
||||||
$self->{'limits'} = \%limits;
|
$self->{'limits'} = \%limits;
|
||||||
$self->{'smds'} = \%smds;
|
|
||||||
$self->{'blob'} = "varchar(8000000)";
|
$self->{'blob'} = "varchar(8000000)";
|
||||||
$self->{'text'} = "varchar(8000000)";
|
$self->{'text'} = "varchar(8000000)";
|
||||||
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
|
$self->{'double_quotes'} = 1; # Can handle: 'Walker''s'
|
||||||
|
11
sql/field.cc
11
sql/field.cc
@ -3782,10 +3782,10 @@ uint Field_varstring::max_packed_col_length(uint max_length)
|
|||||||
Field_blob::Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
|
Field_blob::Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
|
||||||
enum utype unireg_check_arg, const char *field_name_arg,
|
enum utype unireg_check_arg, const char *field_name_arg,
|
||||||
struct st_table *table_arg,uint blob_pack_length,
|
struct st_table *table_arg,uint blob_pack_length,
|
||||||
bool binary_arg)
|
bool binary_arg, CHARSET_INFO *cs)
|
||||||
:Field_str(ptr_arg, (1L << min(blob_pack_length,3)*8)-1L,
|
:Field_str(ptr_arg, (1L << min(blob_pack_length,3)*8)-1L,
|
||||||
null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg,
|
null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg,
|
||||||
table_arg, default_charset_info),
|
table_arg, cs),
|
||||||
packlength(blob_pack_length),binary_flag(binary_arg), geom_flag(true)
|
packlength(blob_pack_length),binary_flag(binary_arg), geom_flag(true)
|
||||||
{
|
{
|
||||||
flags|= BLOB_FLAG;
|
flags|= BLOB_FLAG;
|
||||||
@ -3967,9 +3967,9 @@ String *Field_blob::val_str(String *val_buffer __attribute__((unused)),
|
|||||||
char *blob;
|
char *blob;
|
||||||
memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
|
memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
|
||||||
if (!blob)
|
if (!blob)
|
||||||
val_ptr->set("",0,default_charset_info); // A bit safer than ->length(0)
|
val_ptr->set("",0,field_charset); // A bit safer than ->length(0)
|
||||||
else
|
else
|
||||||
val_ptr->set((const char*) blob,get_length(ptr),default_charset_info);
|
val_ptr->set((const char*) blob,get_length(ptr),field_charset);
|
||||||
return val_ptr;
|
return val_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4782,7 +4782,8 @@ Field *make_field(char *ptr, uint32 field_length,
|
|||||||
if (f_is_blob(pack_flag))
|
if (f_is_blob(pack_flag))
|
||||||
return new Field_blob(ptr,null_pos,null_bit,
|
return new Field_blob(ptr,null_pos,null_bit,
|
||||||
unireg_check, field_name, table,
|
unireg_check, field_name, table,
|
||||||
pack_length,f_is_binary(pack_flag) != 0);
|
pack_length,f_is_binary(pack_flag) != 0,
|
||||||
|
default_charset_info);
|
||||||
if (f_is_geom(pack_flag))
|
if (f_is_geom(pack_flag))
|
||||||
return new Field_geom(ptr,null_pos,null_bit,
|
return new Field_geom(ptr,null_pos,null_bit,
|
||||||
unireg_check, field_name, table,
|
unireg_check, field_name, table,
|
||||||
|
11
sql/field.h
11
sql/field.h
@ -842,11 +842,11 @@ public:
|
|||||||
Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
|
Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
|
||||||
enum utype unireg_check_arg, const char *field_name_arg,
|
enum utype unireg_check_arg, const char *field_name_arg,
|
||||||
struct st_table *table_arg,uint blob_pack_length,
|
struct st_table *table_arg,uint blob_pack_length,
|
||||||
bool binary_arg);
|
bool binary_arg, CHARSET_INFO *cs);
|
||||||
Field_blob(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
|
Field_blob(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
|
||||||
struct st_table *table_arg, bool binary_arg)
|
struct st_table *table_arg, bool binary_arg, CHARSET_INFO *cs)
|
||||||
:Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0,
|
:Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0,
|
||||||
NONE, field_name_arg, table_arg, default_charset_info),
|
NONE, field_name_arg, table_arg, cs),
|
||||||
packlength(3),binary_flag(binary_arg), geom_flag(true)
|
packlength(3),binary_flag(binary_arg), geom_flag(true)
|
||||||
{
|
{
|
||||||
flags|= BLOB_FLAG;
|
flags|= BLOB_FLAG;
|
||||||
@ -930,11 +930,12 @@ public:
|
|||||||
struct st_table *table_arg,uint blob_pack_length,
|
struct st_table *table_arg,uint blob_pack_length,
|
||||||
bool binary_arg)
|
bool binary_arg)
|
||||||
:Field_blob(ptr_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
|
:Field_blob(ptr_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
|
||||||
field_name_arg, table_arg, blob_pack_length,binary_arg) {}
|
field_name_arg, table_arg, blob_pack_length,binary_arg,
|
||||||
|
default_charset_info) {}
|
||||||
Field_geom(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
|
Field_geom(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
|
||||||
struct st_table *table_arg, bool binary_arg)
|
struct st_table *table_arg, bool binary_arg)
|
||||||
:Field_blob(len_arg, maybe_null_arg, field_name_arg,
|
:Field_blob(len_arg, maybe_null_arg, field_name_arg,
|
||||||
table_arg, binary_arg) {}
|
table_arg, binary_arg, default_charset_info) {}
|
||||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY; }
|
enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY; }
|
||||||
|
|
||||||
void get_key_image(char *buff,uint length, imagetype type);
|
void get_key_image(char *buff,uint length, imagetype type);
|
||||||
|
@ -508,7 +508,8 @@ void field_conv(Field *to,Field *from)
|
|||||||
if (!blob->value.is_alloced() &&
|
if (!blob->value.is_alloced() &&
|
||||||
from->real_type() != FIELD_TYPE_STRING)
|
from->real_type() != FIELD_TYPE_STRING)
|
||||||
blob->value.copy();
|
blob->value.copy();
|
||||||
blob->store(blob->value.ptr(),blob->value.length(),default_charset_info);
|
blob->store(blob->value.ptr(),blob->value.length(),
|
||||||
|
to->binary()?default_charset_info:((Field_str*)to)->charset());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((from->result_type() == STRING_RESULT &&
|
if ((from->result_type() == STRING_RESULT &&
|
||||||
@ -520,7 +521,9 @@ void field_conv(Field *to,Field *from)
|
|||||||
char buff[MAX_FIELD_WIDTH];
|
char buff[MAX_FIELD_WIDTH];
|
||||||
String result(buff,sizeof(buff),default_charset_info);
|
String result(buff,sizeof(buff),default_charset_info);
|
||||||
from->val_str(&result,&result);
|
from->val_str(&result,&result);
|
||||||
to->store(result.c_ptr_quick(),result.length(),default_charset_info);
|
to->store(result.c_ptr_quick(),result.length(),
|
||||||
|
to->binary()?default_charset_info:((Field_str*)to)->charset());
|
||||||
|
// QQ: what to do if "from" and "to" are of dirrent charsets?
|
||||||
}
|
}
|
||||||
else if (from->result_type() == REAL_RESULT)
|
else if (from->result_type() == REAL_RESULT)
|
||||||
to->store(from->val_real());
|
to->store(from->val_real());
|
||||||
|
@ -137,6 +137,7 @@ enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
|
|||||||
#define HA_CREATE_USED_MAX_ROWS 32
|
#define HA_CREATE_USED_MAX_ROWS 32
|
||||||
#define HA_CREATE_USED_AVG_ROW_LENGTH 64
|
#define HA_CREATE_USED_AVG_ROW_LENGTH 64
|
||||||
#define HA_CREATE_USED_PACK_KEYS 128
|
#define HA_CREATE_USED_PACK_KEYS 128
|
||||||
|
#define HA_CREATE_USED_CHARSET 256
|
||||||
|
|
||||||
typedef struct st_thd_trans {
|
typedef struct st_thd_trans {
|
||||||
void *bdb_tid;
|
void *bdb_tid;
|
||||||
|
63
sql/item.cc
63
sql/item.cc
@ -133,6 +133,9 @@ void Item_field::set_field(Field *field_par)
|
|||||||
field_name=field_par->field_name;
|
field_name=field_par->field_name;
|
||||||
binary=field_par->binary();
|
binary=field_par->binary();
|
||||||
unsigned_flag=test(field_par->flags & UNSIGNED_FLAG);
|
unsigned_flag=test(field_par->flags & UNSIGNED_FLAG);
|
||||||
|
/* For string fields copy character set from original field */
|
||||||
|
if (!field_par->binary())
|
||||||
|
str_value.set_charset(((Field_str*)field_par)->charset());
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *Item_ident::full_name() const
|
const char *Item_ident::full_name() const
|
||||||
@ -443,12 +446,13 @@ String *Item_copy_string::val_str(String *str)
|
|||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
bool Item::fix_fields(THD *thd,
|
bool Item::fix_fields(THD *thd,
|
||||||
struct st_table_list *list)
|
struct st_table_list *list,
|
||||||
|
Item ** ref)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables)
|
bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||||
{
|
{
|
||||||
if (!field) // If field is not checked
|
if (!field) // If field is not checked
|
||||||
{
|
{
|
||||||
@ -464,7 +468,7 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables)
|
|||||||
mention of table name, but if we join tables in one list it will
|
mention of table name, but if we join tables in one list it will
|
||||||
cause error ER_NON_UNIQ_ERROR in find_field_in_tables.
|
cause error ER_NON_UNIQ_ERROR in find_field_in_tables.
|
||||||
*/
|
*/
|
||||||
SELECT_LEX *last;
|
SELECT_LEX *last= 0;
|
||||||
for (SELECT_LEX *sl= thd->lex.select->outer_select();
|
for (SELECT_LEX *sl= thd->lex.select->outer_select();
|
||||||
sl && !tmp;
|
sl && !tmp;
|
||||||
sl= sl->outer_select())
|
sl= sl->outer_select())
|
||||||
@ -473,6 +477,8 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables)
|
|||||||
if (!tmp)
|
if (!tmp)
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
depended_from= last;
|
||||||
/*
|
/*
|
||||||
Mark all selects from resolved to 1 before select where was
|
Mark all selects from resolved to 1 before select where was
|
||||||
found table as depended (of select where was found table)
|
found table as depended (of select where was found table)
|
||||||
@ -491,6 +497,7 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables)
|
|||||||
tbl->shared= 1;
|
tbl->shared= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
set_field(tmp);
|
set_field(tmp);
|
||||||
}
|
}
|
||||||
else if (thd && thd->set_query_id && field->query_id != thd->query_id)
|
else if (thd && thd->set_query_id && field->query_id != thd->query_id)
|
||||||
@ -501,6 +508,14 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables)
|
|||||||
table->used_fields++;
|
table->used_fields++;
|
||||||
table->used_keys&=field->part_of_key;
|
table->used_keys&=field->part_of_key;
|
||||||
}
|
}
|
||||||
|
if (depended_from != 0 && depended_from->having_fix_field)
|
||||||
|
{
|
||||||
|
*ref= new Item_ref((char *)db_name, (char *)table_name,
|
||||||
|
(char *)field_name);
|
||||||
|
if (!*ref)
|
||||||
|
return 1;
|
||||||
|
return (*ref)->fix_fields(thd, tables, ref);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -784,12 +799,50 @@ bool Item_null::send(THD *thd, String *packet)
|
|||||||
Find field in select list having the same name
|
Find field in select list having the same name
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables)
|
bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
||||||
{
|
{
|
||||||
if (!ref)
|
if (!ref)
|
||||||
{
|
{
|
||||||
if (!(ref=find_item_in_list(this,thd->lex.select->item_list)))
|
if (!(ref= find_item_in_list(this,thd->lex.select->item_list)))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
We can't find table field in table list of current select,
|
||||||
|
consequently we have to find it in outer subselect(s).
|
||||||
|
We can't join lists of outer & current select, because of scope
|
||||||
|
of view rules. For example if both tables (outer & current) have
|
||||||
|
field 'field' it is not mistake to refer to this field without
|
||||||
|
mention of table name, but if we join tables in one list it will
|
||||||
|
cause error ER_NON_UNIQ_ERROR in find_field_in_tables.
|
||||||
|
*/
|
||||||
|
SELECT_LEX *last=0;
|
||||||
|
for (SELECT_LEX *sl= thd->lex.select->outer_select();
|
||||||
|
sl && !ref;
|
||||||
|
sl= sl->outer_select())
|
||||||
|
ref= find_item_in_list(this, (last= sl)->item_list);
|
||||||
|
if (!ref)
|
||||||
return 1;
|
return 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
depended_from= last;
|
||||||
|
/*
|
||||||
|
Mark all selects from resolved to 1 before select where was
|
||||||
|
found table as depended (of select where was found table)
|
||||||
|
*/
|
||||||
|
for (SELECT_LEX *s= thd->lex.select;
|
||||||
|
s &&s != last;
|
||||||
|
s= s->outer_select())
|
||||||
|
if( !s->depended )
|
||||||
|
{
|
||||||
|
s->depended= 1; //Select is depended of outer select
|
||||||
|
//Tables will be reopened many times
|
||||||
|
for (TABLE_LIST *tbl=
|
||||||
|
(TABLE_LIST*)s->table_list.first;
|
||||||
|
tbl;
|
||||||
|
tbl= tbl->next)
|
||||||
|
tbl->shared= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
max_length= (*ref)->max_length;
|
max_length= (*ref)->max_length;
|
||||||
maybe_null= (*ref)->maybe_null;
|
maybe_null= (*ref)->maybe_null;
|
||||||
decimals= (*ref)->decimals;
|
decimals= (*ref)->decimals;
|
||||||
|
11
sql/item.h
11
sql/item.h
@ -52,7 +52,7 @@ public:
|
|||||||
virtual ~Item() { name=0; } /*lint -e1509 */
|
virtual ~Item() { name=0; } /*lint -e1509 */
|
||||||
void set_name(char* str,uint length=0);
|
void set_name(char* str,uint length=0);
|
||||||
void init_make_field(Send_field *tmp_field,enum enum_field_types type);
|
void init_make_field(Send_field *tmp_field,enum enum_field_types type);
|
||||||
virtual bool fix_fields(THD *,struct st_table_list *);
|
virtual bool fix_fields(THD *, struct st_table_list *, Item **);
|
||||||
virtual bool save_in_field(Field *field);
|
virtual bool save_in_field(Field *field);
|
||||||
virtual void save_org_in_field(Field *field)
|
virtual void save_org_in_field(Field *field)
|
||||||
{ (void) save_in_field(field); }
|
{ (void) save_in_field(field); }
|
||||||
@ -85,15 +85,18 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class st_select_lex;
|
||||||
class Item_ident :public Item
|
class Item_ident :public Item
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
const char *db_name;
|
const char *db_name;
|
||||||
const char *table_name;
|
const char *table_name;
|
||||||
const char *field_name;
|
const char *field_name;
|
||||||
|
st_select_lex *depended_from;
|
||||||
Item_ident(const char *db_name_par,const char *table_name_par,
|
Item_ident(const char *db_name_par,const char *table_name_par,
|
||||||
const char *field_name_par)
|
const char *field_name_par)
|
||||||
:db_name(db_name_par),table_name(table_name_par),field_name(field_name_par)
|
:db_name(db_name_par),table_name(table_name_par),
|
||||||
|
field_name(field_name_par), depended_from(0)
|
||||||
{ name = (char*) field_name_par; }
|
{ name = (char*) field_name_par; }
|
||||||
const char *full_name() const;
|
const char *full_name() const;
|
||||||
};
|
};
|
||||||
@ -120,7 +123,7 @@ public:
|
|||||||
String *str_result(String* tmp);
|
String *str_result(String* tmp);
|
||||||
bool send(THD *thd, String *str_arg) { return result_field->send(thd,str_arg); }
|
bool send(THD *thd, String *str_arg) { return result_field->send(thd,str_arg); }
|
||||||
void make_field(Send_field *field);
|
void make_field(Send_field *field);
|
||||||
bool fix_fields(THD *,struct st_table_list *);
|
bool fix_fields(THD *, struct st_table_list *, Item **);
|
||||||
bool save_in_field(Field *field);
|
bool save_in_field(Field *field);
|
||||||
void save_org_in_field(Field *field);
|
void save_org_in_field(Field *field);
|
||||||
table_map used_tables() const;
|
table_map used_tables() const;
|
||||||
@ -390,7 +393,7 @@ public:
|
|||||||
}
|
}
|
||||||
bool send(THD *thd, String *tmp) { return (*ref)->send(thd, tmp); }
|
bool send(THD *thd, String *tmp) { return (*ref)->send(thd, tmp); }
|
||||||
void make_field(Send_field *field) { (*ref)->make_field(field); }
|
void make_field(Send_field *field) { (*ref)->make_field(field); }
|
||||||
bool fix_fields(THD *,struct st_table_list *);
|
bool fix_fields(THD *, struct st_table_list *, Item **);
|
||||||
bool save_in_field(Field *field) { return (*ref)->save_in_field(field); }
|
bool save_in_field(Field *field) { return (*ref)->save_in_field(field); }
|
||||||
void save_org_in_field(Field *field) { (*ref)->save_org_in_field(field); }
|
void save_org_in_field(Field *field) { (*ref)->save_org_in_field(field); }
|
||||||
enum Item_result result_type () const { return (*ref)->result_type(); }
|
enum Item_result result_type () const { return (*ref)->result_type(); }
|
||||||
|
@ -727,12 +727,12 @@ double Item_func_case::val()
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Item_func_case::fix_fields(THD *thd,TABLE_LIST *tables)
|
Item_func_case::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||||
{
|
{
|
||||||
if (first_expr && first_expr->fix_fields(thd,tables) ||
|
if (first_expr && first_expr->fix_fields(thd, tables, &first_expr) ||
|
||||||
else_expr && else_expr->fix_fields(thd,tables))
|
else_expr && else_expr->fix_fields(thd, tables, &else_expr))
|
||||||
return 1;
|
return 1;
|
||||||
if (Item_func::fix_fields(thd,tables))
|
if (Item_func::fix_fields(thd, tables, ref))
|
||||||
return 1;
|
return 1;
|
||||||
if (first_expr)
|
if (first_expr)
|
||||||
{
|
{
|
||||||
@ -1074,7 +1074,7 @@ longlong Item_func_bit_and::val_int()
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Item_cond::fix_fields(THD *thd,TABLE_LIST *tables)
|
Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||||
{
|
{
|
||||||
List_iterator<Item> li(list);
|
List_iterator<Item> li(list);
|
||||||
Item *item;
|
Item *item;
|
||||||
@ -1096,7 +1096,7 @@ Item_cond::fix_fields(THD *thd,TABLE_LIST *tables)
|
|||||||
#endif
|
#endif
|
||||||
item= *li.ref(); // new current item
|
item= *li.ref(); // new current item
|
||||||
}
|
}
|
||||||
if (item->fix_fields(thd,tables))
|
if (item->fix_fields(thd, tables, li.ref()))
|
||||||
return 1; /* purecov: inspected */
|
return 1; /* purecov: inspected */
|
||||||
used_tables_cache|=item->used_tables();
|
used_tables_cache|=item->used_tables();
|
||||||
with_sum_func= with_sum_func || item->with_sum_func;
|
with_sum_func= with_sum_func || item->with_sum_func;
|
||||||
@ -1272,9 +1272,9 @@ Item_func::optimize_type Item_func_like::select_optimize() const
|
|||||||
return OPTIMIZE_NONE;
|
return OPTIMIZE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Item_func_like::fix_fields(THD *thd,struct st_table_list *tlist)
|
bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref)
|
||||||
{
|
{
|
||||||
if (Item_bool_func2::fix_fields(thd, tlist))
|
if (Item_bool_func2::fix_fields(thd, tlist, ref))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1324,9 +1324,10 @@ bool Item_func_like::fix_fields(THD *thd,struct st_table_list *tlist)
|
|||||||
#ifdef USE_REGEX
|
#ifdef USE_REGEX
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Item_func_regex::fix_fields(THD *thd,TABLE_LIST *tables)
|
Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||||
{
|
{
|
||||||
if (args[0]->fix_fields(thd,tables) || args[1]->fix_fields(thd,tables))
|
if (args[0]->fix_fields(thd, tables, args) ||
|
||||||
|
args[1]->fix_fields(thd,tables, args + 1))
|
||||||
return 1; /* purecov: inspected */
|
return 1; /* purecov: inspected */
|
||||||
with_sum_func=args[0]->with_sum_func || args[1]->with_sum_func;
|
with_sum_func=args[0]->with_sum_func || args[1]->with_sum_func;
|
||||||
max_length=1; decimals=0;
|
max_length=1; decimals=0;
|
||||||
|
@ -177,9 +177,10 @@ public:
|
|||||||
Item_func_interval(Item *a,List<Item> &list)
|
Item_func_interval(Item *a,List<Item> &list)
|
||||||
:Item_int_func(list),item(a),intervals(0) {}
|
:Item_int_func(list),item(a),intervals(0) {}
|
||||||
longlong val_int();
|
longlong val_int();
|
||||||
bool fix_fields(THD *thd,struct st_table_list *tlist)
|
bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref)
|
||||||
{
|
{
|
||||||
return (item->fix_fields(thd,tlist) || Item_func::fix_fields(thd,tlist));
|
return (item->fix_fields(thd, tlist, &item) ||
|
||||||
|
Item_func::fix_fields(thd, tlist, ref));
|
||||||
}
|
}
|
||||||
void fix_length_and_dec();
|
void fix_length_and_dec();
|
||||||
~Item_func_interval() { delete item; }
|
~Item_func_interval() { delete item; }
|
||||||
@ -259,7 +260,7 @@ public:
|
|||||||
enum Item_result result_type () const { return cached_result_type; }
|
enum Item_result result_type () const { return cached_result_type; }
|
||||||
const char *func_name() const { return "case"; }
|
const char *func_name() const { return "case"; }
|
||||||
void print(String *str);
|
void print(String *str);
|
||||||
bool fix_fields(THD *thd,struct st_table_list *tlist);
|
bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref);
|
||||||
Item *find_item(String *str);
|
Item *find_item(String *str);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -409,9 +410,10 @@ class Item_func_in :public Item_int_func
|
|||||||
Item_func_in(Item *a,List<Item> &list)
|
Item_func_in(Item *a,List<Item> &list)
|
||||||
:Item_int_func(list),item(a),array(0),in_item(0) {}
|
:Item_int_func(list),item(a),array(0),in_item(0) {}
|
||||||
longlong val_int();
|
longlong val_int();
|
||||||
bool fix_fields(THD *thd,struct st_table_list *tlist)
|
bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref)
|
||||||
{
|
{
|
||||||
return (item->fix_fields(thd,tlist) || Item_func::fix_fields(thd,tlist));
|
return (item->fix_fields(thd, tlist, &item) ||
|
||||||
|
Item_func::fix_fields(thd, tlist, ref));
|
||||||
}
|
}
|
||||||
void fix_length_and_dec();
|
void fix_length_and_dec();
|
||||||
~Item_func_in() { delete item; delete array; delete in_item; }
|
~Item_func_in() { delete item; delete array; delete in_item; }
|
||||||
@ -505,7 +507,7 @@ public:
|
|||||||
cond_result eq_cmp_result() const { return COND_TRUE; }
|
cond_result eq_cmp_result() const { return COND_TRUE; }
|
||||||
const char *func_name() const { return "like"; }
|
const char *func_name() const { return "like"; }
|
||||||
void fix_length_and_dec();
|
void fix_length_and_dec();
|
||||||
bool fix_fields(THD *thd,struct st_table_list *tlist);
|
bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref);
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef USE_REGEX
|
#ifdef USE_REGEX
|
||||||
@ -523,7 +525,7 @@ public:
|
|||||||
regex_compiled(0),regex_is_const(0) {}
|
regex_compiled(0),regex_is_const(0) {}
|
||||||
~Item_func_regex();
|
~Item_func_regex();
|
||||||
longlong val_int();
|
longlong val_int();
|
||||||
bool fix_fields(THD *thd,struct st_table_list *tlist);
|
bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref);
|
||||||
const char *func_name() const { return "regex"; }
|
const char *func_name() const { return "regex"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -552,7 +554,7 @@ public:
|
|||||||
{ list.push_back(i1); list.push_back(i2); }
|
{ list.push_back(i1); list.push_back(i2); }
|
||||||
~Item_cond() { list.delete_elements(); }
|
~Item_cond() { list.delete_elements(); }
|
||||||
bool add(Item *item) { return list.push_back(item); }
|
bool add(Item *item) { return list.push_back(item); }
|
||||||
bool fix_fields(THD *,struct st_table_list *);
|
bool fix_fields(THD *, struct st_table_list *, Item **ref);
|
||||||
|
|
||||||
enum Type type() const { return COND_ITEM; }
|
enum Type type() const { return COND_ITEM; }
|
||||||
List<Item>* argument_list() { return &list; }
|
List<Item>* argument_list() { return &list; }
|
||||||
|
@ -58,7 +58,7 @@ Item_func::Item_func(List<Item> &list)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Item_func::fix_fields(THD *thd,TABLE_LIST *tables)
|
Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||||
{
|
{
|
||||||
Item **arg,**arg_end;
|
Item **arg,**arg_end;
|
||||||
char buff[STACK_BUFF_ALLOC]; // Max argument in function
|
char buff[STACK_BUFF_ALLOC]; // Max argument in function
|
||||||
@ -72,12 +72,23 @@ Item_func::fix_fields(THD *thd,TABLE_LIST *tables)
|
|||||||
{ // Print purify happy
|
{ // Print purify happy
|
||||||
for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
|
for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
|
||||||
{
|
{
|
||||||
if ((*arg)->fix_fields(thd,tables))
|
if ((*arg)->fix_fields(thd, tables, arg))
|
||||||
return 1; /* purecov: inspected */
|
return 1; /* purecov: inspected */
|
||||||
if ((*arg)->maybe_null)
|
if ((*arg)->maybe_null)
|
||||||
maybe_null=1;
|
maybe_null=1;
|
||||||
if ((*arg)->binary)
|
if ((*arg)->binary)
|
||||||
binary=1;
|
binary=1;
|
||||||
|
/*
|
||||||
|
Change charset to arg charset if it is not equal to
|
||||||
|
default_charset_info. This will work for many cases,
|
||||||
|
but generally this should be done more carefull. Each string
|
||||||
|
function should have it's own fix_fields() method to correctly
|
||||||
|
setup it's result's character set taking in account arguments.
|
||||||
|
For example: left(a,b) should take in account only first argument,
|
||||||
|
but ignore the second one.
|
||||||
|
*/
|
||||||
|
if ((*arg)->str_value.charset() != default_charset_info)
|
||||||
|
str_value.set_charset((*arg)->str_value.charset());
|
||||||
with_sum_func= with_sum_func || (*arg)->with_sum_func;
|
with_sum_func= with_sum_func || (*arg)->with_sum_func;
|
||||||
used_tables_cache|=(*arg)->used_tables();
|
used_tables_cache|=(*arg)->used_tables();
|
||||||
const_item_cache&= (*arg)->const_item();
|
const_item_cache&= (*arg)->const_item();
|
||||||
@ -1091,7 +1102,7 @@ udf_handler::~udf_handler()
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
udf_handler::fix_fields(THD *thd,TABLE_LIST *tables,Item_result_field *func,
|
udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func,
|
||||||
uint arg_count, Item **arguments)
|
uint arg_count, Item **arguments)
|
||||||
{
|
{
|
||||||
char buff[STACK_BUFF_ALLOC]; // Max argument in function
|
char buff[STACK_BUFF_ALLOC]; // Max argument in function
|
||||||
@ -1135,7 +1146,7 @@ udf_handler::fix_fields(THD *thd,TABLE_LIST *tables,Item_result_field *func,
|
|||||||
arg != arg_end ;
|
arg != arg_end ;
|
||||||
arg++,i++)
|
arg++,i++)
|
||||||
{
|
{
|
||||||
if ((*arg)->fix_fields(thd,tables))
|
if ((*arg)->fix_fields(thd, tables, arg))
|
||||||
return 1;
|
return 1;
|
||||||
if ((*arg)->binary)
|
if ((*arg)->binary)
|
||||||
func->binary=1;
|
func->binary=1;
|
||||||
@ -1754,11 +1765,12 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Item_func_set_user_var::fix_fields(THD *thd,TABLE_LIST *tables)
|
bool Item_func_set_user_var::fix_fields(THD *thd, TABLE_LIST *tables,
|
||||||
|
Item **ref)
|
||||||
{
|
{
|
||||||
if (!thd)
|
if (!thd)
|
||||||
thd=current_thd;
|
thd=current_thd;
|
||||||
if (Item_func::fix_fields(thd,tables) ||
|
if (Item_func::fix_fields(thd, tables, ref) ||
|
||||||
!(entry= get_variable(&thd->user_vars, name, 1)))
|
!(entry= get_variable(&thd->user_vars, name, 1)))
|
||||||
return 1;
|
return 1;
|
||||||
entry->update_query_id=thd->query_id;
|
entry->update_query_id=thd->query_id;
|
||||||
@ -2084,7 +2096,7 @@ void Item_func_match::init_search(bool no_order)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist)
|
bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
|
||||||
{
|
{
|
||||||
List_iterator<Item> li(fields);
|
List_iterator<Item> li(fields);
|
||||||
Item *item;
|
Item *item;
|
||||||
@ -2097,7 +2109,7 @@ bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist)
|
|||||||
modifications to find_best and auto_close as complement to auto_init code
|
modifications to find_best and auto_close as complement to auto_init code
|
||||||
above.
|
above.
|
||||||
*/
|
*/
|
||||||
if (Item_func::fix_fields(thd,tlist) || !const_item())
|
if (Item_func::fix_fields(thd, tlist, ref) || !const_item())
|
||||||
{
|
{
|
||||||
my_error(ER_WRONG_ARGUMENTS,MYF(0),"AGAINST");
|
my_error(ER_WRONG_ARGUMENTS,MYF(0),"AGAINST");
|
||||||
return 1;
|
return 1;
|
||||||
@ -2105,7 +2117,7 @@ bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist)
|
|||||||
|
|
||||||
while ((item=li++))
|
while ((item=li++))
|
||||||
{
|
{
|
||||||
if (item->fix_fields(thd,tlist))
|
if (item->fix_fields(thd, tlist, li.ref()))
|
||||||
return 1;
|
return 1;
|
||||||
if (item->type() == Item::REF_ITEM)
|
if (item->type() == Item::REF_ITEM)
|
||||||
li.replace(item= *((Item_ref *)item)->ref);
|
li.replace(item= *((Item_ref *)item)->ref);
|
||||||
|
@ -99,7 +99,7 @@ public:
|
|||||||
}
|
}
|
||||||
Item_func(List<Item> &list);
|
Item_func(List<Item> &list);
|
||||||
~Item_func() {} /* Nothing to do; Items are freed automaticly */
|
~Item_func() {} /* Nothing to do; Items are freed automaticly */
|
||||||
bool fix_fields(THD *,struct st_table_list *);
|
bool fix_fields(THD *,struct st_table_list *, Item **ref);
|
||||||
void make_field(Send_field *field);
|
void make_field(Send_field *field);
|
||||||
table_map used_tables() const;
|
table_map used_tables() const;
|
||||||
void update_used_tables();
|
void update_used_tables();
|
||||||
@ -567,9 +567,10 @@ public:
|
|||||||
Item_func_field(Item *a,List<Item> &list) :Item_int_func(list),item(a) {}
|
Item_func_field(Item *a,List<Item> &list) :Item_int_func(list),item(a) {}
|
||||||
~Item_func_field() { delete item; }
|
~Item_func_field() { delete item; }
|
||||||
longlong val_int();
|
longlong val_int();
|
||||||
bool fix_fields(THD *thd,struct st_table_list *tlist)
|
bool fix_fields(THD *thd,struct st_table_list *tlist, Item **ref)
|
||||||
{
|
{
|
||||||
return (item->fix_fields(thd,tlist) || Item_func::fix_fields(thd,tlist));
|
return (item->fix_fields(thd, tlist, &item) ||
|
||||||
|
Item_func::fix_fields(thd, tlist, ref));
|
||||||
}
|
}
|
||||||
void update_used_tables()
|
void update_used_tables()
|
||||||
{
|
{
|
||||||
@ -708,11 +709,11 @@ public:
|
|||||||
:Item_func(list), udf(udf_arg) {}
|
:Item_func(list), udf(udf_arg) {}
|
||||||
~Item_udf_func() {}
|
~Item_udf_func() {}
|
||||||
const char *func_name() const { return udf.name(); }
|
const char *func_name() const { return udf.name(); }
|
||||||
bool fix_fields(THD *thd,struct st_table_list *tables)
|
bool fix_fields(THD *thd, struct st_table_list *tables, Item **ref)
|
||||||
{
|
{
|
||||||
bool res=udf.fix_fields(thd,tables,this,arg_count,args);
|
bool res= udf.fix_fields(thd, tables, this, arg_count, args);
|
||||||
used_tables_cache=udf.used_tables_cache;
|
used_tables_cache= udf.used_tables_cache;
|
||||||
const_item_cache=udf.const_item_cache;
|
const_item_cache= udf.const_item_cache;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
Item_result result_type () const { return udf.result_type(); }
|
Item_result result_type () const { return udf.result_type(); }
|
||||||
@ -867,7 +868,7 @@ public:
|
|||||||
void update_hash(void *ptr, uint length, enum Item_result type);
|
void update_hash(void *ptr, uint length, enum Item_result type);
|
||||||
bool update();
|
bool update();
|
||||||
enum Item_result result_type () const { return cached_result_type; }
|
enum Item_result result_type () const { return cached_result_type; }
|
||||||
bool fix_fields(THD *thd,struct st_table_list *tables);
|
bool fix_fields(THD *thd, struct st_table_list *tables, Item **ref);
|
||||||
void fix_length_and_dec();
|
void fix_length_and_dec();
|
||||||
void print(String *str);
|
void print(String *str);
|
||||||
const char *func_name() const { return "set_user_var"; }
|
const char *func_name() const { return "set_user_var"; }
|
||||||
@ -941,7 +942,7 @@ public:
|
|||||||
}
|
}
|
||||||
enum Functype functype() const { return FT_FUNC; }
|
enum Functype functype() const { return FT_FUNC; }
|
||||||
void update_used_tables() {}
|
void update_used_tables() {}
|
||||||
bool fix_fields(THD *thd,struct st_table_list *tlist);
|
bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref);
|
||||||
bool eq(const Item *, bool binary_cmp) const;
|
bool eq(const Item *, bool binary_cmp) const;
|
||||||
longlong val_int() { return val()!=0.0; }
|
longlong val_int() { return val()!=0.0; }
|
||||||
double val();
|
double val();
|
||||||
|
@ -759,6 +759,7 @@ String *Item_func_left::val_str(String *str)
|
|||||||
if (!res->alloced_length())
|
if (!res->alloced_length())
|
||||||
{ // Don't change const str
|
{ // Don't change const str
|
||||||
str_value= *res; // Not malloced string
|
str_value= *res; // Not malloced string
|
||||||
|
str_value.set_charset(res->charset());
|
||||||
res= &str_value;
|
res= &str_value;
|
||||||
}
|
}
|
||||||
res->length((uint) length);
|
res->length((uint) length);
|
||||||
@ -1791,6 +1792,7 @@ String *Item_func_conv_charset::val_str(String *str)
|
|||||||
null_value=1;
|
null_value=1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
null_value=0;
|
||||||
|
|
||||||
from=arg->charset();
|
from=arg->charset();
|
||||||
to=conv_charset;
|
to=conv_charset;
|
||||||
@ -1798,7 +1800,7 @@ String *Item_func_conv_charset::val_str(String *str)
|
|||||||
s=(const uchar*)arg->ptr();
|
s=(const uchar*)arg->ptr();
|
||||||
se=s+arg->length();
|
se=s+arg->length();
|
||||||
|
|
||||||
dmaxlen=arg->length()*(conv_charset->mbmaxlen?conv_charset->mbmaxlen:1)+1;
|
dmaxlen=arg->length()*(to->mbmaxlen?to->mbmaxlen:1)+1;
|
||||||
str->alloc(dmaxlen);
|
str->alloc(dmaxlen);
|
||||||
d0=d=(unsigned char*)str->ptr();
|
d0=d=(unsigned char*)str->ptr();
|
||||||
de=d+dmaxlen;
|
de=d+dmaxlen;
|
||||||
@ -1840,7 +1842,7 @@ outp:
|
|||||||
|
|
||||||
void Item_func_conv_charset::fix_length_and_dec()
|
void Item_func_conv_charset::fix_length_and_dec()
|
||||||
{
|
{
|
||||||
/* BAR TODO: What to do here??? */
|
max_length = args[0]->max_length*(conv_charset->mbmaxlen?conv_charset->mbmaxlen:1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1910,9 +1912,41 @@ outp:
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Item_func_conv_charset::fix_fields(THD *thd,struct st_table_list *tables)
|
||||||
|
{
|
||||||
|
char buff[STACK_BUFF_ALLOC]; // Max argument in function
|
||||||
|
binary=0;
|
||||||
|
used_tables_cache=0;
|
||||||
|
const_item_cache=1;
|
||||||
|
|
||||||
|
if (thd && check_stack_overrun(thd,buff))
|
||||||
|
return 0; // Fatal error if flag is set!
|
||||||
|
if (args[0]->fix_fields(thd, tables, args))
|
||||||
|
return 1;
|
||||||
|
maybe_null=args[0]->maybe_null;
|
||||||
|
binary=args[0]->binary;
|
||||||
|
const_item_cache=args[0]->const_item();
|
||||||
|
str_value.set_charset(conv_charset);
|
||||||
|
fix_length_and_dec();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Item_func_conv_charset3::fix_length_and_dec()
|
void Item_func_conv_charset3::fix_length_and_dec()
|
||||||
{
|
{
|
||||||
/* BAR TODO: What to do here??? */
|
max_length = args[0]->max_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String *Item_func_charset::val_str(String *str)
|
||||||
|
{
|
||||||
|
String *res = args[0]->val_str(str);
|
||||||
|
|
||||||
|
if ((null_value=(args[0]->null_value || !res->charset())))
|
||||||
|
return 0;
|
||||||
|
str->copy(res->charset()->name,strlen(res->charset()->name));
|
||||||
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,9 +40,10 @@ public:
|
|||||||
if (!t_arg)
|
if (!t_arg)
|
||||||
return result_field;
|
return result_field;
|
||||||
return (max_length > 255) ?
|
return (max_length > 255) ?
|
||||||
(Field *)new Field_blob(max_length,maybe_null, name,t_arg, binary) :
|
(Field *)new Field_blob(max_length,maybe_null, name,t_arg, binary,
|
||||||
|
str_value.charset()) :
|
||||||
(Field *) new Field_string(max_length,maybe_null, name,t_arg, binary,
|
(Field *) new Field_string(max_length,maybe_null, name,t_arg, binary,
|
||||||
default_charset_info);
|
str_value.charset());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -79,10 +80,10 @@ public:
|
|||||||
String *val_str(String *);
|
String *val_str(String *);
|
||||||
void fix_length_and_dec();
|
void fix_length_and_dec();
|
||||||
void update_used_tables();
|
void update_used_tables();
|
||||||
bool fix_fields(THD *thd,struct st_table_list *tlist)
|
bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
|
||||||
{
|
{
|
||||||
return (separator->fix_fields(thd,tlist)
|
return (separator->fix_fields(thd, tlist, &separator)
|
||||||
|| Item_func::fix_fields(thd,tlist));
|
|| Item_func::fix_fields(thd, tlist, ref));
|
||||||
}
|
}
|
||||||
const char *func_name() const { return "concat_ws"; }
|
const char *func_name() const { return "concat_ws"; }
|
||||||
};
|
};
|
||||||
@ -325,9 +326,10 @@ public:
|
|||||||
double val();
|
double val();
|
||||||
longlong val_int();
|
longlong val_int();
|
||||||
String *val_str(String *str);
|
String *val_str(String *str);
|
||||||
bool fix_fields(THD *thd,struct st_table_list *tlist)
|
bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
|
||||||
{
|
{
|
||||||
return (item->fix_fields(thd,tlist) || Item_func::fix_fields(thd,tlist));
|
return (item->fix_fields(thd, tlist, &item) ||
|
||||||
|
Item_func::fix_fields(thd, tlist, ref));
|
||||||
}
|
}
|
||||||
void fix_length_and_dec();
|
void fix_length_and_dec();
|
||||||
void update_used_tables();
|
void update_used_tables();
|
||||||
@ -344,9 +346,10 @@ public:
|
|||||||
Item_func_make_set(Item *a,List<Item> &list) :Item_str_func(list),item(a) {}
|
Item_func_make_set(Item *a,List<Item> &list) :Item_str_func(list),item(a) {}
|
||||||
~Item_func_make_set() { delete item; }
|
~Item_func_make_set() { delete item; }
|
||||||
String *val_str(String *str);
|
String *val_str(String *str);
|
||||||
bool fix_fields(THD *thd,struct st_table_list *tlist)
|
bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
|
||||||
{
|
{
|
||||||
return (item->fix_fields(thd,tlist) || Item_func::fix_fields(thd,tlist));
|
return (item->fix_fields(thd, tlist, &item) ||
|
||||||
|
Item_func::fix_fields(thd, tlist, ref));
|
||||||
}
|
}
|
||||||
void fix_length_and_dec();
|
void fix_length_and_dec();
|
||||||
void update_used_tables();
|
void update_used_tables();
|
||||||
@ -488,6 +491,7 @@ public:
|
|||||||
{
|
{
|
||||||
conv_charset=cs;
|
conv_charset=cs;
|
||||||
}
|
}
|
||||||
|
bool fix_fields(THD *thd,struct st_table_list *tables);
|
||||||
String *val_str(String *);
|
String *val_str(String *);
|
||||||
void fix_length_and_dec();
|
void fix_length_and_dec();
|
||||||
const char *func_name() const { return "conv_charset"; }
|
const char *func_name() const { return "conv_charset"; }
|
||||||
@ -503,6 +507,18 @@ public:
|
|||||||
const char *func_name() const { return "conv_charset3"; }
|
const char *func_name() const { return "conv_charset3"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Item_func_charset :public Item_str_func
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Item_func_charset(Item *a) :Item_str_func(a) {}
|
||||||
|
String *val_str(String *);
|
||||||
|
const char *func_name() const { return "charset"; }
|
||||||
|
void fix_length_and_dec()
|
||||||
|
{
|
||||||
|
max_length=20; // should be enough
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************
|
/*******************************************************
|
||||||
Spatial functions
|
Spatial functions
|
||||||
|
@ -35,12 +35,13 @@ SUBSELECT TODO:
|
|||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
#include "sql_select.h"
|
#include "sql_select.h"
|
||||||
|
|
||||||
Item_subselect::Item_subselect(THD *thd, st_select_lex *select_lex):
|
Item_subselect::Item_subselect(THD *thd, st_select_lex *select_lex,
|
||||||
|
select_subselect *result):
|
||||||
assigned(0), executed(0), optimized(0), error(0)
|
assigned(0), executed(0), optimized(0), error(0)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("Item_subselect::Item_subselect");
|
DBUG_ENTER("Item_subselect::Item_subselect");
|
||||||
DBUG_PRINT("subs", ("select_lex 0x%xl", (long) select_lex));
|
DBUG_PRINT("subs", ("select_lex 0x%xl", (long) select_lex));
|
||||||
result= new select_subselect(this);
|
this->result= result;
|
||||||
SELECT_LEX_UNIT *unit= select_lex->master_unit();
|
SELECT_LEX_UNIT *unit= select_lex->master_unit();
|
||||||
unit->offset_limit_cnt= unit->global_parameters->offset_limit;
|
unit->offset_limit_cnt= unit->global_parameters->offset_limit;
|
||||||
unit->select_limit_cnt= unit->global_parameters->select_limit+
|
unit->select_limit_cnt= unit->global_parameters->select_limit+
|
||||||
@ -51,41 +52,15 @@ Item_subselect::Item_subselect(THD *thd, st_select_lex *select_lex):
|
|||||||
select_lex->options&= ~OPTION_FOUND_ROWS;
|
select_lex->options&= ~OPTION_FOUND_ROWS;
|
||||||
join= new JOIN(thd, select_lex->item_list, select_lex->options, result);
|
join= new JOIN(thd, select_lex->item_list, select_lex->options, result);
|
||||||
this->select_lex= select_lex;
|
this->select_lex= select_lex;
|
||||||
maybe_null= 1;
|
assign_null();
|
||||||
/*
|
/*
|
||||||
item value is NULL if select_subselect not changed this value
|
item value is NULL if select_subselect not changed this value
|
||||||
(i.e. some rows will be found returned)
|
(i.e. some rows will be found returned)
|
||||||
*/
|
*/
|
||||||
assign_null();
|
null_value= 1;
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
Item::Type Item_subselect::type() const
|
|
||||||
{
|
|
||||||
return SUBSELECT_ITEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
double Item_subselect::val ()
|
|
||||||
{
|
|
||||||
if (exec())
|
|
||||||
return 0;
|
|
||||||
return real_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
longlong Item_subselect::val_int ()
|
|
||||||
{
|
|
||||||
if (exec())
|
|
||||||
return 0;
|
|
||||||
return int_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
String *Item_subselect::val_str (String *str)
|
|
||||||
{
|
|
||||||
if (exec() || null_value)
|
|
||||||
return 0;
|
|
||||||
return &str_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Item_subselect::make_field (Send_field *tmp_field)
|
void Item_subselect::make_field (Send_field *tmp_field)
|
||||||
{
|
{
|
||||||
if (null_value)
|
if (null_value)
|
||||||
@ -100,17 +75,10 @@ void Item_subselect::make_field (Send_field *tmp_field)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Item_subselect::fix_fields(THD *thd,TABLE_LIST *tables)
|
bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (thd->having_fix_field)
|
|
||||||
{
|
|
||||||
//TODO: subselects in having do not suported now
|
|
||||||
my_printf_error(ER_SYNTAX_ERROR, ER(ER_SYNTAX_ERROR), MYF(0));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// Is it one field subselect?
|
// Is it one field subselect?
|
||||||
if (select_lex->item_list.elements != 1)
|
if (select_lex->item_list.elements > max_columns)
|
||||||
{
|
{
|
||||||
my_printf_error(ER_SUBSELECT_NO_1_COL, ER(ER_SUBSELECT_NO_1_COL), MYF(0));
|
my_printf_error(ER_SUBSELECT_NO_1_COL, ER(ER_SUBSELECT_NO_1_COL), MYF(0));
|
||||||
return 1;
|
return 1;
|
||||||
@ -131,13 +99,14 @@ bool Item_subselect::fix_fields(THD *thd,TABLE_LIST *tables)
|
|||||||
|
|
||||||
int Item_subselect::exec()
|
int Item_subselect::exec()
|
||||||
{
|
{
|
||||||
|
DBUG_ENTER("Item_subselect::exec");
|
||||||
if (!optimized)
|
if (!optimized)
|
||||||
{
|
{
|
||||||
optimized=1;
|
optimized=1;
|
||||||
if (join->optimize())
|
if (join->optimize())
|
||||||
{
|
{
|
||||||
executed= 1;
|
executed= 1;
|
||||||
return (join->error?join->error:1);
|
DBUG_RETURN(join->error?join->error:1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (join->select_lex->depended && executed)
|
if (join->select_lex->depended && executed)
|
||||||
@ -145,7 +114,7 @@ int Item_subselect::exec()
|
|||||||
if (join->reinit())
|
if (join->reinit())
|
||||||
{
|
{
|
||||||
error= 1;
|
error= 1;
|
||||||
return 1;
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
assign_null();
|
assign_null();
|
||||||
executed= assigned= 0;
|
executed= assigned= 0;
|
||||||
@ -157,7 +126,80 @@ int Item_subselect::exec()
|
|||||||
join->exec();
|
join->exec();
|
||||||
join->thd->lex.select= save_select;
|
join->thd->lex.select= save_select;
|
||||||
executed= 1;
|
executed= 1;
|
||||||
return join->error;
|
DBUG_RETURN(join->error);
|
||||||
}
|
}
|
||||||
return 0;
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline table_map Item_subselect::used_tables() const
|
||||||
|
{
|
||||||
|
return (table_map) select_lex->depended ? 1L : 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
Item_singleval_subselect::Item_singleval_subselect(THD *thd,
|
||||||
|
st_select_lex *select_lex):
|
||||||
|
Item_subselect(thd, select_lex, new select_singleval_subselect(this))
|
||||||
|
{
|
||||||
|
max_columns= 1;
|
||||||
|
maybe_null= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Item::Type Item_subselect::type() const
|
||||||
|
{
|
||||||
|
return SUBSELECT_ITEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
double Item_singleval_subselect::val ()
|
||||||
|
{
|
||||||
|
if (exec())
|
||||||
|
return 0;
|
||||||
|
return real_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
longlong Item_singleval_subselect::val_int ()
|
||||||
|
{
|
||||||
|
if (exec())
|
||||||
|
return 0;
|
||||||
|
return int_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
String *Item_singleval_subselect::val_str (String *str)
|
||||||
|
{
|
||||||
|
if (exec() || null_value)
|
||||||
|
return 0;
|
||||||
|
return &str_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
Item_exists_subselect::Item_exists_subselect(THD *thd,
|
||||||
|
st_select_lex *select_lex):
|
||||||
|
Item_subselect(thd, select_lex, new select_singleval_subselect(this))
|
||||||
|
{
|
||||||
|
max_columns= UINT_MAX;
|
||||||
|
null_value= 0; //can't be NULL
|
||||||
|
maybe_null= 0; //can't be NULL
|
||||||
|
value= 0;
|
||||||
|
select_lex->select_limit= 1; // we need only 1 row to determinate existence
|
||||||
|
}
|
||||||
|
|
||||||
|
double Item_exists_subselect::val ()
|
||||||
|
{
|
||||||
|
if (exec())
|
||||||
|
return 0;
|
||||||
|
return (double) value;
|
||||||
|
}
|
||||||
|
|
||||||
|
longlong Item_exists_subselect::val_int ()
|
||||||
|
{
|
||||||
|
if (exec())
|
||||||
|
return 0;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
String *Item_exists_subselect::val_str(String *str)
|
||||||
|
{
|
||||||
|
if (exec())
|
||||||
|
return 0;
|
||||||
|
str->set(value);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -20,46 +20,38 @@
|
|||||||
#pragma interface /* gcc class implementation */
|
#pragma interface /* gcc class implementation */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct st_select_lex;
|
class st_select_lex;
|
||||||
class JOIN;
|
class JOIN;
|
||||||
class select_subselect;
|
class select_subselect;
|
||||||
|
|
||||||
/* simple (not depended of covered select ) subselect */
|
/* base class for subselects */
|
||||||
|
|
||||||
class Item_subselect :public Item
|
class Item_subselect :public Item
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
longlong int_value;
|
uint max_columns;
|
||||||
double real_value;
|
|
||||||
my_bool assigned; /* value already assigned to subselect */
|
my_bool assigned; /* value already assigned to subselect */
|
||||||
my_bool executed; /* simple subselect is executed */
|
my_bool executed; /* simple subselect is executed */
|
||||||
my_bool optimized; /* simple subselect is optimized */
|
my_bool optimized; /* simple subselect is optimized */
|
||||||
my_bool error; /* error in query */
|
my_bool error; /* error in query */
|
||||||
enum Item_result res_type;
|
|
||||||
|
|
||||||
int exec();
|
int exec();
|
||||||
void assign_null()
|
virtual void assign_null()
|
||||||
{
|
{
|
||||||
null_value= 1;
|
null_value= 1;
|
||||||
int_value= 0;
|
|
||||||
real_value= 0;
|
|
||||||
max_length= 4;
|
|
||||||
res_type= STRING_RESULT;
|
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
st_select_lex *select_lex;
|
st_select_lex *select_lex;
|
||||||
JOIN *join;
|
JOIN *join;
|
||||||
select_subselect *result;
|
select_subselect *result;
|
||||||
|
|
||||||
Item_subselect(THD *thd, st_select_lex *select_lex);
|
Item_subselect(THD *thd, st_select_lex *select_lex,
|
||||||
|
select_subselect* result);
|
||||||
Item_subselect(Item_subselect *item)
|
Item_subselect(Item_subselect *item)
|
||||||
{
|
{
|
||||||
null_value= item->null_value;
|
null_value= item->null_value;
|
||||||
int_value= item->int_value;
|
|
||||||
real_value= item->real_value;
|
|
||||||
max_length= item->max_length;
|
|
||||||
decimals= item->decimals;
|
decimals= item->decimals;
|
||||||
res_type= item->res_type;
|
max_columns= item->max_columns;
|
||||||
assigned= item->assigned;
|
assigned= item->assigned;
|
||||||
executed= item->executed;
|
executed= item->executed;
|
||||||
select_lex= item->select_lex;
|
select_lex= item->select_lex;
|
||||||
@ -69,16 +61,75 @@ public:
|
|||||||
error= item->error;
|
error= item->error;
|
||||||
}
|
}
|
||||||
enum Type type() const;
|
enum Type type() const;
|
||||||
double val ();
|
|
||||||
longlong val_int ();
|
|
||||||
String *val_str (String *);
|
|
||||||
bool is_null() { return null_value; }
|
bool is_null() { return null_value; }
|
||||||
void make_field (Send_field *);
|
void make_field (Send_field *);
|
||||||
bool fix_fields(THD *thd, TABLE_LIST *tables);
|
bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref);
|
||||||
Item *new_item() { return new Item_subselect(this); }
|
table_map used_tables() const;
|
||||||
enum Item_result result_type() const { return res_type; }
|
|
||||||
|
|
||||||
friend class select_subselect;
|
friend class select_subselect;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* single value subselect */
|
||||||
|
|
||||||
|
class Item_singleval_subselect :public Item_subselect
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
longlong int_value;
|
||||||
|
double real_value;
|
||||||
|
enum Item_result res_type;
|
||||||
|
|
||||||
|
virtual void assign_null()
|
||||||
|
{
|
||||||
|
null_value= 1;
|
||||||
|
int_value= 0;
|
||||||
|
real_value= 0;
|
||||||
|
max_length= 4;
|
||||||
|
res_type= STRING_RESULT;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
Item_singleval_subselect(THD *thd, st_select_lex *select_lex);
|
||||||
|
Item_singleval_subselect(Item_singleval_subselect *item):
|
||||||
|
Item_subselect(item)
|
||||||
|
{
|
||||||
|
int_value= item->int_value;
|
||||||
|
real_value= item->real_value;
|
||||||
|
max_length= item->max_length;
|
||||||
|
decimals= item->decimals;
|
||||||
|
res_type= item->res_type;
|
||||||
|
}
|
||||||
|
double val ();
|
||||||
|
longlong val_int ();
|
||||||
|
String *val_str (String *);
|
||||||
|
Item *new_item() { return new Item_singleval_subselect(this); }
|
||||||
|
enum Item_result result_type() const { return res_type; }
|
||||||
|
|
||||||
|
friend class select_singleval_subselect;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* exists subselect */
|
||||||
|
|
||||||
|
class Item_exists_subselect :public Item_subselect
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
longlong value;
|
||||||
|
|
||||||
|
virtual void assign_null()
|
||||||
|
{
|
||||||
|
value= 0;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
Item_exists_subselect(THD *thd, st_select_lex *select_lex);
|
||||||
|
Item_exists_subselect(Item_exists_subselect *item):
|
||||||
|
Item_subselect(item)
|
||||||
|
{
|
||||||
|
value= item->value;
|
||||||
|
}
|
||||||
|
Item *new_item() { return new Item_exists_subselect(this); }
|
||||||
|
enum Item_result result_type() const { return INT_RESULT;}
|
||||||
|
longlong val_int();
|
||||||
|
double val();
|
||||||
|
String *val_str(String*);
|
||||||
|
|
||||||
|
friend class select_exists_subselect;
|
||||||
|
};
|
||||||
|
@ -112,7 +112,7 @@ Item_sum_int::val_str(String *str)
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Item_sum_num::fix_fields(THD *thd,TABLE_LIST *tables)
|
Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||||
{
|
{
|
||||||
if (!thd->allow_sum_func)
|
if (!thd->allow_sum_func)
|
||||||
{
|
{
|
||||||
@ -124,7 +124,7 @@ Item_sum_num::fix_fields(THD *thd,TABLE_LIST *tables)
|
|||||||
maybe_null=0;
|
maybe_null=0;
|
||||||
for (uint i=0 ; i < arg_count ; i++)
|
for (uint i=0 ; i < arg_count ; i++)
|
||||||
{
|
{
|
||||||
if (args[i]->fix_fields(thd,tables))
|
if (args[i]->fix_fields(thd, tables, args + i))
|
||||||
return 1;
|
return 1;
|
||||||
if (decimals < args[i]->decimals)
|
if (decimals < args[i]->decimals)
|
||||||
decimals=args[i]->decimals;
|
decimals=args[i]->decimals;
|
||||||
@ -140,7 +140,7 @@ Item_sum_num::fix_fields(THD *thd,TABLE_LIST *tables)
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Item_sum_hybrid::fix_fields(THD *thd,TABLE_LIST *tables)
|
Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||||
{
|
{
|
||||||
Item *item=args[0];
|
Item *item=args[0];
|
||||||
if (!thd->allow_sum_func)
|
if (!thd->allow_sum_func)
|
||||||
@ -149,7 +149,7 @@ Item_sum_hybrid::fix_fields(THD *thd,TABLE_LIST *tables)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
thd->allow_sum_func=0; // No included group funcs
|
thd->allow_sum_func=0; // No included group funcs
|
||||||
if (item->fix_fields(thd,tables))
|
if (item->fix_fields(thd, tables, args))
|
||||||
return 1;
|
return 1;
|
||||||
hybrid_type=item->result_type();
|
hybrid_type=item->result_type();
|
||||||
if (hybrid_type == INT_RESULT)
|
if (hybrid_type == INT_RESULT)
|
||||||
@ -930,9 +930,10 @@ Item_sum_count_distinct::~Item_sum_count_distinct()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Item_sum_count_distinct::fix_fields(THD *thd,TABLE_LIST *tables)
|
bool Item_sum_count_distinct::fix_fields(THD *thd, TABLE_LIST *tables,
|
||||||
|
Item **ref)
|
||||||
{
|
{
|
||||||
if (Item_sum_num::fix_fields(thd,tables) ||
|
if (Item_sum_num::fix_fields(thd, tables, ref) ||
|
||||||
!(tmp_table_param= new TMP_TABLE_PARAM))
|
!(tmp_table_param= new TMP_TABLE_PARAM))
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -80,7 +80,7 @@ public:
|
|||||||
Item_sum_num(Item *item_par) :Item_sum(item_par) {}
|
Item_sum_num(Item *item_par) :Item_sum(item_par) {}
|
||||||
Item_sum_num(Item *a, Item* b) :Item_sum(a,b) {}
|
Item_sum_num(Item *a, Item* b) :Item_sum(a,b) {}
|
||||||
Item_sum_num(List<Item> &list) :Item_sum(list) {}
|
Item_sum_num(List<Item> &list) :Item_sum(list) {}
|
||||||
bool fix_fields(THD *,struct st_table_list *);
|
bool fix_fields(THD *, TABLE_LIST *, Item **);
|
||||||
longlong val_int() { return (longlong) val(); } /* Real as default */
|
longlong val_int() { return (longlong) val(); } /* Real as default */
|
||||||
String *val_str(String*str);
|
String *val_str(String*str);
|
||||||
void reset_field();
|
void reset_field();
|
||||||
@ -146,7 +146,7 @@ class Item_sum_count_distinct :public Item_sum_int
|
|||||||
{
|
{
|
||||||
TABLE *table;
|
TABLE *table;
|
||||||
table_map used_table_cache;
|
table_map used_table_cache;
|
||||||
bool fix_fields(THD *thd,TABLE_LIST *tables);
|
bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref);
|
||||||
uint32 *field_lengths;
|
uint32 *field_lengths;
|
||||||
TMP_TABLE_PARAM *tmp_table_param;
|
TMP_TABLE_PARAM *tmp_table_param;
|
||||||
TREE tree;
|
TREE tree;
|
||||||
@ -283,7 +283,7 @@ class Item_sum_hybrid :public Item_sum
|
|||||||
Item_sum_hybrid(Item *item_par,int sign) :Item_sum(item_par),cmp_sign(sign),
|
Item_sum_hybrid(Item *item_par,int sign) :Item_sum(item_par),cmp_sign(sign),
|
||||||
used_table_cache(~(table_map) 0)
|
used_table_cache(~(table_map) 0)
|
||||||
{}
|
{}
|
||||||
bool fix_fields(THD *,struct st_table_list *);
|
bool fix_fields(THD *, TABLE_LIST *, Item **);
|
||||||
table_map used_tables() const { return used_table_cache; }
|
table_map used_tables() const { return used_table_cache; }
|
||||||
bool const_item() const { return !used_table_cache; }
|
bool const_item() const { return !used_table_cache; }
|
||||||
|
|
||||||
@ -382,7 +382,7 @@ public:
|
|||||||
{ quick_group=0;}
|
{ quick_group=0;}
|
||||||
~Item_udf_sum() {}
|
~Item_udf_sum() {}
|
||||||
const char *func_name() const { return udf.name(); }
|
const char *func_name() const { return udf.name(); }
|
||||||
bool fix_fields(THD *thd,struct st_table_list *tables)
|
bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||||
{
|
{
|
||||||
return udf.fix_fields(thd,tables,this,this->arg_count,this->args);
|
return udf.fix_fields(thd,tables,this,this->arg_count,this->args);
|
||||||
}
|
}
|
||||||
|
@ -42,5 +42,5 @@ public:
|
|||||||
bool add() { return 0; }
|
bool add() { return 0; }
|
||||||
void reset_field() {}
|
void reset_field() {}
|
||||||
void update_field(int offset) {}
|
void update_field(int offset) {}
|
||||||
bool fix_fields(THD *thd,struct st_table_list *tlist) { return 0;}
|
bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) { return 0;}
|
||||||
};
|
};
|
||||||
|
@ -82,6 +82,7 @@ static SYMBOL symbols[] = {
|
|||||||
{ "CASE", SYM(CASE_SYM),0,0},
|
{ "CASE", SYM(CASE_SYM),0,0},
|
||||||
{ "CHAR", SYM(CHAR_SYM),0,0},
|
{ "CHAR", SYM(CHAR_SYM),0,0},
|
||||||
{ "CHARACTER", SYM(CHAR_SYM),0,0},
|
{ "CHARACTER", SYM(CHAR_SYM),0,0},
|
||||||
|
{ "CHARSET", SYM(CHARSET),0,0},
|
||||||
{ "CHANGE", SYM(CHANGE),0,0},
|
{ "CHANGE", SYM(CHANGE),0,0},
|
||||||
{ "CHANGED", SYM(CHANGED),0,0},
|
{ "CHANGED", SYM(CHANGED),0,0},
|
||||||
{ "CHECK", SYM(CHECK_SYM),0,0},
|
{ "CHECK", SYM(CHECK_SYM),0,0},
|
||||||
|
@ -289,7 +289,8 @@ inline THD *_current_thd(void)
|
|||||||
|
|
||||||
#define prepare_execute(A) ((A)->command == COM_EXECUTE)
|
#define prepare_execute(A) ((A)->command == COM_EXECUTE)
|
||||||
|
|
||||||
int mysql_create_db(THD *thd, char *db, uint create_info, bool silent);
|
int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent);
|
||||||
|
int mysql_alter_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent);
|
||||||
int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent);
|
int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent);
|
||||||
void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags);
|
void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags);
|
||||||
int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists);
|
int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists);
|
||||||
@ -471,6 +472,7 @@ int mysqld_show_logs(THD *thd);
|
|||||||
void mysqld_list_fields(THD *thd,TABLE_LIST *table, const char *wild);
|
void mysqld_list_fields(THD *thd,TABLE_LIST *table, const char *wild);
|
||||||
int mysqld_dump_create_info(THD *thd, TABLE *table, int fd = -1);
|
int mysqld_dump_create_info(THD *thd, TABLE *table, int fd = -1);
|
||||||
int mysqld_show_create(THD *thd, TABLE_LIST *table_list);
|
int mysqld_show_create(THD *thd, TABLE_LIST *table_list);
|
||||||
|
int mysqld_show_create_db(THD *thd, const char *dbname);
|
||||||
|
|
||||||
void mysqld_list_processes(THD *thd,const char *user,bool verbose);
|
void mysqld_list_processes(THD *thd,const char *user,bool verbose);
|
||||||
int mysqld_show_status(THD *thd);
|
int mysqld_show_status(THD *thd);
|
||||||
|
@ -1876,7 +1876,7 @@ int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (item->fix_fields(thd,tables))
|
if (item->fix_fields(thd, tables, it.ref()))
|
||||||
DBUG_RETURN(-1); /* purecov: inspected */
|
DBUG_RETURN(-1); /* purecov: inspected */
|
||||||
if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM &&
|
if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM &&
|
||||||
sum_func_list)
|
sum_func_list)
|
||||||
@ -2027,7 +2027,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
|
|||||||
if (*conds)
|
if (*conds)
|
||||||
{
|
{
|
||||||
thd->where="where clause";
|
thd->where="where clause";
|
||||||
if ((*conds)->fix_fields(thd,tables))
|
if ((*conds)->fix_fields(thd, tables, conds))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2038,7 +2038,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
|
|||||||
{
|
{
|
||||||
/* Make a join an a expression */
|
/* Make a join an a expression */
|
||||||
thd->where="on clause";
|
thd->where="on clause";
|
||||||
if (table->on_expr->fix_fields(thd,tables))
|
if (table->on_expr->fix_fields(thd, tables, &table->on_expr))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
thd->cond_count++;
|
thd->cond_count++;
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ static void free_var(user_var_entry *entry)
|
|||||||
|
|
||||||
THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
|
THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
|
||||||
insert_id_used(0), in_lock_tables(0),
|
insert_id_used(0), in_lock_tables(0),
|
||||||
global_read_lock(0), bootstrap(0), having_fix_field(0)
|
global_read_lock(0), bootstrap(0)
|
||||||
{
|
{
|
||||||
host=user=priv_user=db=query=ip=0;
|
host=user=priv_user=db=query=ip=0;
|
||||||
host_or_ip="unknown ip";
|
host_or_ip="unknown ip";
|
||||||
@ -103,6 +103,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
|
|||||||
file_id = 0;
|
file_id = 0;
|
||||||
cond_count=0;
|
cond_count=0;
|
||||||
convert_set=0;
|
convert_set=0;
|
||||||
|
db_charset=default_charset_info;
|
||||||
mysys_var=0;
|
mysys_var=0;
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
dbug_sentry=THD_SENTRY_MAGIC;
|
dbug_sentry=THD_SENTRY_MAGIC;
|
||||||
@ -769,7 +770,6 @@ void select_dump::send_error(uint errcode,const char *err)
|
|||||||
file= -1;
|
file= -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool select_dump::send_eof()
|
bool select_dump::send_eof()
|
||||||
{
|
{
|
||||||
int error=test(end_io_cache(&cache));
|
int error=test(end_io_cache(&cache));
|
||||||
@ -788,10 +788,11 @@ select_subselect::select_subselect(Item_subselect *item)
|
|||||||
this->item=item;
|
this->item=item;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool select_subselect::send_data(List<Item> &items)
|
bool select_singleval_subselect::send_data(List<Item> &items)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("select_subselect::send_data");
|
DBUG_ENTER("select_singleval_subselect::send_data");
|
||||||
if (item->assigned){
|
Item_singleval_subselect *it= (Item_singleval_subselect *)item;
|
||||||
|
if (it->assigned){
|
||||||
my_printf_error(ER_SUBSELECT_NO_1_ROW, ER(ER_SUBSELECT_NO_1_ROW), MYF(0));
|
my_printf_error(ER_SUBSELECT_NO_1_ROW, ER(ER_SUBSELECT_NO_1_ROW), MYF(0));
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
@ -806,18 +807,33 @@ bool select_subselect::send_data(List<Item> &items)
|
|||||||
Following val() call have to be first, because function AVG() & STD()
|
Following val() call have to be first, because function AVG() & STD()
|
||||||
calculate value on it & determinate "is it NULL?".
|
calculate value on it & determinate "is it NULL?".
|
||||||
*/
|
*/
|
||||||
item->real_value= val_item->val();
|
it->real_value= val_item->val();
|
||||||
if ((item->null_value= val_item->is_null()))
|
if ((it->null_value= val_item->is_null()))
|
||||||
{
|
{
|
||||||
item->assign_null();
|
it->assign_null();
|
||||||
} else {
|
} else {
|
||||||
item->max_length= val_item->max_length;
|
it->max_length= val_item->max_length;
|
||||||
item->decimals= val_item->decimals;
|
it->decimals= val_item->decimals;
|
||||||
item->binary= val_item->binary;
|
it->binary= val_item->binary;
|
||||||
val_item->val_str(&item->str_value);
|
val_item->val_str(&it->str_value);
|
||||||
item->int_value= val_item->val_int();
|
it->int_value= val_item->val_int();
|
||||||
item->res_type= val_item->result_type();
|
it->res_type= val_item->result_type();
|
||||||
}
|
}
|
||||||
item->assigned= 1;
|
it->assigned= 1;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool select_exists_subselect::send_data(List<Item> &items)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("select_exists_subselect::send_data");
|
||||||
|
Item_exists_subselect *it= (Item_exists_subselect *)item;
|
||||||
|
if (unit->offset_limit_cnt)
|
||||||
|
{ // Using limit offset,count
|
||||||
|
unit->offset_limit_cnt--;
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
it->value= 1;
|
||||||
|
it->assigned= 1;
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -460,7 +460,6 @@ public:
|
|||||||
bool query_error, bootstrap, cleanup_done;
|
bool query_error, bootstrap, cleanup_done;
|
||||||
bool safe_to_cache_query;
|
bool safe_to_cache_query;
|
||||||
bool volatile killed;
|
bool volatile killed;
|
||||||
bool having_fix_field; //TRUE when having fix field called
|
|
||||||
bool prepare_command;
|
bool prepare_command;
|
||||||
ulong param_count,current_param_number;
|
ulong param_count,current_param_number;
|
||||||
Error<mysql_st_error> err_list;
|
Error<mysql_st_error> err_list;
|
||||||
@ -480,6 +479,7 @@ public:
|
|||||||
ulong slave_proxy_id;
|
ulong slave_proxy_id;
|
||||||
NET* slave_net; // network connection from slave -> m.
|
NET* slave_net; // network connection from slave -> m.
|
||||||
my_off_t log_pos;
|
my_off_t log_pos;
|
||||||
|
CHARSET_INFO *db_charset;
|
||||||
|
|
||||||
THD();
|
THD();
|
||||||
~THD();
|
~THD();
|
||||||
@ -749,19 +749,36 @@ class select_union :public select_result {
|
|||||||
bool flush();
|
bool flush();
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Single value subselect interface class */
|
/* Base subselect interface class */
|
||||||
class select_subselect :public select_result
|
class select_subselect :public select_result
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
Item_subselect *item;
|
Item_subselect *item;
|
||||||
public:
|
public:
|
||||||
select_subselect(Item_subselect *item);
|
select_subselect(Item_subselect *item);
|
||||||
bool send_fields(List<Item> &list, uint flag) { return 0; };
|
bool send_fields(List<Item> &list, uint flag) { return 0; };
|
||||||
bool send_data(List<Item> &items);
|
bool send_data(List<Item> &items)=0;
|
||||||
bool send_eof() { return 0; };
|
bool send_eof() { return 0; };
|
||||||
|
|
||||||
friend class Ttem_subselect;
|
friend class Ttem_subselect;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Single value subselect interface class */
|
||||||
|
class select_singleval_subselect :public select_subselect
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
select_singleval_subselect(Item_subselect *item):select_subselect(item){}
|
||||||
|
bool send_data(List<Item> &items);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* EXISTS subselect interface class */
|
||||||
|
class select_exists_subselect :public select_subselect
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
select_exists_subselect(Item_subselect *item):select_subselect(item){}
|
||||||
|
bool send_data(List<Item> &items);
|
||||||
|
};
|
||||||
|
|
||||||
/* Structs used when sorting */
|
/* Structs used when sorting */
|
||||||
|
|
||||||
typedef struct st_sort_field {
|
typedef struct st_sort_field {
|
||||||
|
277
sql/sql_db.cc
277
sql/sql_db.cc
@ -25,18 +25,112 @@
|
|||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MY_DB_OPT_FILE ".db.opt"
|
||||||
|
|
||||||
static long mysql_rm_known_files(THD *thd, MY_DIR *dirp,
|
static long mysql_rm_known_files(THD *thd, MY_DIR *dirp,
|
||||||
const char *db, const char *path,
|
const char *db, const char *path,
|
||||||
uint level);
|
uint level);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create database options file:
|
||||||
|
Currently databse default charset is only stored there.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int write_db_opt(THD *thd,const char *db,HA_CREATE_INFO *create,char *fn)
|
||||||
|
{
|
||||||
|
register File file;
|
||||||
|
char buf[256]; // Should be enough
|
||||||
|
int error=0;
|
||||||
|
|
||||||
|
if ((file=my_create(fn,CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0)
|
||||||
|
{
|
||||||
|
sprintf(buf,"default-character-set=%s\n",
|
||||||
|
(create && create->table_charset) ?
|
||||||
|
create->table_charset->name : "DEFAULT");
|
||||||
|
|
||||||
|
if (my_write(file,(byte*)buf,strlen(buf),MYF(MY_NABP+MY_WME)))
|
||||||
|
{
|
||||||
|
// QQ : should we send more suitable error message?
|
||||||
|
my_error(ER_CANT_CREATE_DB,MYF(0),db,my_errno);
|
||||||
|
error = -1;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
my_close(file,MYF(0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// QQ : should we send more suitable error message?
|
||||||
|
my_error(ER_CANT_CREATE_DB,MYF(0),db,my_errno);
|
||||||
|
error = -1;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Load database options file:
|
||||||
|
*/
|
||||||
|
static int load_db_opt(THD *thd,const char *db,HA_CREATE_INFO *create,char *fn)
|
||||||
|
{
|
||||||
|
register File file;
|
||||||
|
char buf[256]="";
|
||||||
|
|
||||||
|
if ((file=my_open(fn,O_RDWR|O_BINARY,MYF(MY_WME))) >= 0)
|
||||||
|
{
|
||||||
|
int nbytes=my_read(file,(byte*)buf,sizeof(buf)-1,MYF(0));
|
||||||
|
if ( nbytes >= 0 )
|
||||||
|
{
|
||||||
|
char *ln=buf;
|
||||||
|
char *pe=buf+nbytes;
|
||||||
|
|
||||||
|
buf[nbytes]='\0';
|
||||||
|
|
||||||
|
for ( ln=buf; ln<pe; )
|
||||||
|
{
|
||||||
|
char *le,*val;
|
||||||
|
for ( le=ln, val=0 ; le<pe ; le++ )
|
||||||
|
{
|
||||||
|
switch(le[0])
|
||||||
|
{
|
||||||
|
case '=':
|
||||||
|
le[0]='\0';
|
||||||
|
val=le+1;
|
||||||
|
le++;
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
case '\n':
|
||||||
|
le[0]='\0';
|
||||||
|
le++;
|
||||||
|
for( ; (le[0]=='\r' || le[0]=='\n') ; le++);
|
||||||
|
if (!strcmp(ln,"default-character-set") && val && val[0])
|
||||||
|
{
|
||||||
|
create->table_charset=get_charset_by_name(val, MYF(0));
|
||||||
|
}
|
||||||
|
goto cnt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cnt:
|
||||||
|
ln=le;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
my_close(file,MYF(0));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* db-name is already validated when we come here */
|
/* db-name is already validated when we come here */
|
||||||
|
|
||||||
int mysql_create_db(THD *thd, char *db, uint create_options, bool silent)
|
int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent)
|
||||||
{
|
{
|
||||||
char path[FN_REFLEN+16];
|
char path[FN_REFLEN+16];
|
||||||
MY_DIR *dirp;
|
MY_DIR *dirp;
|
||||||
long result=1;
|
long result=1;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
uint create_options = create_info ? create_info->options : 0;
|
||||||
|
|
||||||
DBUG_ENTER("mysql_create_db");
|
DBUG_ENTER("mysql_create_db");
|
||||||
|
|
||||||
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
|
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
|
||||||
@ -73,6 +167,12 @@ int mysql_create_db(THD *thd, char *db, uint create_options, bool silent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strcat(path,"/");
|
||||||
|
unpack_dirname(path,path);
|
||||||
|
strcat(path,MY_DB_OPT_FILE);
|
||||||
|
if ((error=write_db_opt(thd,db,create_info,path)))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
if (!silent)
|
if (!silent)
|
||||||
{
|
{
|
||||||
if (!thd->query)
|
if (!thd->query)
|
||||||
@ -104,7 +204,81 @@ exit2:
|
|||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *del_exts[]= {".frm", ".BAK", ".TMD", NullS};
|
|
||||||
|
/* db-name is already validated when we come here */
|
||||||
|
|
||||||
|
int mysql_alter_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent)
|
||||||
|
{
|
||||||
|
char path[FN_REFLEN+16];
|
||||||
|
MY_DIR *dirp;
|
||||||
|
long result=1;
|
||||||
|
int error = 0;
|
||||||
|
DBUG_ENTER("mysql_create_db");
|
||||||
|
register File file;
|
||||||
|
uint create_options = create_info ? create_info->options : 0;
|
||||||
|
|
||||||
|
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
|
||||||
|
|
||||||
|
// do not alter database if another thread is holding read lock
|
||||||
|
if (wait_if_global_read_lock(thd,0))
|
||||||
|
{
|
||||||
|
error= -1;
|
||||||
|
goto exit2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check directory */
|
||||||
|
(void)sprintf(path,"%s/%s", mysql_data_home, db);
|
||||||
|
strcat(path,"/");
|
||||||
|
unpack_dirname(path,path); // Convert if not unix
|
||||||
|
strcat(path,MY_DB_OPT_FILE);
|
||||||
|
if ((error=write_db_opt(thd,db,create_info,path)))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Change options if current
|
||||||
|
database is being altered
|
||||||
|
*/
|
||||||
|
if (thd->db && !strcmp(thd->db,db))
|
||||||
|
{
|
||||||
|
thd->db_charset= create_info ? create_info->table_charset : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!silent)
|
||||||
|
{
|
||||||
|
if (!thd->query)
|
||||||
|
{
|
||||||
|
thd->query = path;
|
||||||
|
thd->query_length = (uint) (strxmov(path,"alter database ", db, NullS)-
|
||||||
|
path);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
mysql_update_log.write(thd,thd->query, thd->query_length);
|
||||||
|
if (mysql_bin_log.is_open())
|
||||||
|
{
|
||||||
|
Query_log_event qinfo(thd, thd->query);
|
||||||
|
mysql_bin_log.write(&qinfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (thd->query == path)
|
||||||
|
{
|
||||||
|
thd->query = 0; // just in case
|
||||||
|
thd->query_length = 0;
|
||||||
|
}
|
||||||
|
send_ok(&thd->net, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
start_waiting_global_read_lock(thd);
|
||||||
|
exit2:
|
||||||
|
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NullS};
|
||||||
static TYPELIB deletable_extentions=
|
static TYPELIB deletable_extentions=
|
||||||
{array_elements(del_exts)-1,"del_exts", del_exts};
|
{array_elements(del_exts)-1,"del_exts", del_exts};
|
||||||
|
|
||||||
@ -332,6 +506,8 @@ bool mysql_change_db(THD *thd,const char *name)
|
|||||||
char *dbname=my_strdup((char*) name,MYF(MY_WME));
|
char *dbname=my_strdup((char*) name,MYF(MY_WME));
|
||||||
char path[FN_REFLEN];
|
char path[FN_REFLEN];
|
||||||
uint db_access;
|
uint db_access;
|
||||||
|
HA_CREATE_INFO create;
|
||||||
|
|
||||||
DBUG_ENTER("mysql_change_db");
|
DBUG_ENTER("mysql_change_db");
|
||||||
|
|
||||||
if (!dbname || !(db_length=strip_sp(dbname)))
|
if (!dbname || !(db_length=strip_sp(dbname)))
|
||||||
@ -382,5 +558,102 @@ bool mysql_change_db(THD *thd,const char *name)
|
|||||||
thd->db=dbname;
|
thd->db=dbname;
|
||||||
thd->db_length=db_length;
|
thd->db_length=db_length;
|
||||||
thd->db_access=db_access;
|
thd->db_access=db_access;
|
||||||
|
|
||||||
|
strcat(path,"/");
|
||||||
|
unpack_dirname(path,path);
|
||||||
|
strcat(path,MY_DB_OPT_FILE);
|
||||||
|
bzero(&create,sizeof(create));
|
||||||
|
load_db_opt(thd,name,&create,path);
|
||||||
|
thd->db_charset=create.table_charset;
|
||||||
|
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int mysqld_show_create_db(THD *thd,const char *name)
|
||||||
|
{
|
||||||
|
int length, db_length;
|
||||||
|
char *dbname=my_strdup((char*) name,MYF(MY_WME));
|
||||||
|
char path[FN_REFLEN];
|
||||||
|
uint db_access;
|
||||||
|
HA_CREATE_INFO create;
|
||||||
|
CONVERT *convert=thd->convert_set;
|
||||||
|
|
||||||
|
DBUG_ENTER("mysql_show_create_db");
|
||||||
|
|
||||||
|
if (!dbname || !(db_length=strip_sp(dbname)))
|
||||||
|
{
|
||||||
|
x_free(dbname); /* purecov: inspected */
|
||||||
|
send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */
|
||||||
|
DBUG_RETURN(1); /* purecov: inspected */
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((db_length > NAME_LEN) || check_db_name(dbname))
|
||||||
|
{
|
||||||
|
net_printf(&thd->net,ER_WRONG_DB_NAME, dbname);
|
||||||
|
x_free(dbname);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (test_all_bits(thd->master_access,DB_ACLS))
|
||||||
|
db_access=DB_ACLS;
|
||||||
|
else
|
||||||
|
db_access= (acl_get(thd->host,thd->ip,(char*) &thd->remote.sin_addr,
|
||||||
|
thd->priv_user,dbname) |
|
||||||
|
thd->master_access);
|
||||||
|
if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname)))
|
||||||
|
{
|
||||||
|
net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR,
|
||||||
|
thd->priv_user,
|
||||||
|
thd->host_or_ip,
|
||||||
|
dbname);
|
||||||
|
mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
|
||||||
|
thd->priv_user,
|
||||||
|
thd->host_or_ip,
|
||||||
|
dbname);
|
||||||
|
my_free(dbname,MYF(0));
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
(void) sprintf(path,"%s/%s",mysql_data_home,dbname);
|
||||||
|
length=unpack_dirname(path,path); // Convert if not unix
|
||||||
|
if (length && path[length-1] == FN_LIBCHAR)
|
||||||
|
path[length-1]=0; // remove ending '\'
|
||||||
|
if (access(path,F_OK))
|
||||||
|
{
|
||||||
|
net_printf(&thd->net,ER_BAD_DB_ERROR,dbname);
|
||||||
|
my_free(dbname,MYF(0));
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
strcat(path,"/");
|
||||||
|
unpack_dirname(path,path);
|
||||||
|
strcat(path,MY_DB_OPT_FILE);
|
||||||
|
bzero(&create,sizeof(create));
|
||||||
|
load_db_opt(thd,name,&create,path);
|
||||||
|
|
||||||
|
List<Item> field_list;
|
||||||
|
field_list.push_back(new Item_empty_string("Database",NAME_LEN));
|
||||||
|
field_list.push_back(new Item_empty_string("Create Database",1024));
|
||||||
|
|
||||||
|
if (send_fields(thd,field_list,1))
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
|
String *packet = &thd->packet;
|
||||||
|
packet->length(0);
|
||||||
|
net_store_data(packet, convert, name);
|
||||||
|
sprintf(path, "CREATE DATABASE %s", name);
|
||||||
|
if (create.table_charset)
|
||||||
|
{
|
||||||
|
strcat(path," DEFAULT CHARACTER SET ");
|
||||||
|
strcat(path,create.table_charset->name);
|
||||||
|
}
|
||||||
|
net_store_data(packet, convert, path);
|
||||||
|
|
||||||
|
if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length()))
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
|
send_eof(&thd->net);
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
|
|||||||
}
|
}
|
||||||
tables->table=table;
|
tables->table=table;
|
||||||
|
|
||||||
if (cond && cond->fix_fields(thd,tables))
|
if (cond && cond->fix_fields(thd, tables, &cond))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (keyname)
|
if (keyname)
|
||||||
|
@ -525,6 +525,18 @@ int yylex(void *arg)
|
|||||||
yylval->lex_str=get_token(lex,length);
|
yylval->lex_str=get_token(lex,length);
|
||||||
if (lex->convert_set)
|
if (lex->convert_set)
|
||||||
lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
|
lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Note: "SELECT _bla AS 'alias'"
|
||||||
|
_bla should be considered as a IDENT if charset haven't been found.
|
||||||
|
So we don't use MYF(MY_WME) with get_charset_by_name to avoid
|
||||||
|
producing an error.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((yylval->lex_str.str[0]=='_') &&
|
||||||
|
(lex->charset=get_charset_by_name(yylval->lex_str.str+1,MYF(0))))
|
||||||
|
return(UNDERSCORE_CHARSET);
|
||||||
|
else
|
||||||
return(IDENT);
|
return(IDENT);
|
||||||
|
|
||||||
case STATE_IDENT_SEP: // Found ident and now '.'
|
case STATE_IDENT_SEP: // Found ident and now '.'
|
||||||
@ -930,8 +942,8 @@ void st_select_lex::init_select()
|
|||||||
interval_list.empty();
|
interval_list.empty();
|
||||||
use_index.empty();
|
use_index.empty();
|
||||||
ftfunc_list.empty();
|
ftfunc_list.empty();
|
||||||
linkage=UNSPECIFIED_TYPE;
|
linkage= UNSPECIFIED_TYPE;
|
||||||
depended= 0;
|
depended= having_fix_field= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -42,9 +42,11 @@ enum enum_sql_command {
|
|||||||
SQLCOM_SHOW_KEYS, SQLCOM_SHOW_VARIABLES, SQLCOM_SHOW_LOGS, SQLCOM_SHOW_STATUS,
|
SQLCOM_SHOW_KEYS, SQLCOM_SHOW_VARIABLES, SQLCOM_SHOW_LOGS, SQLCOM_SHOW_STATUS,
|
||||||
SQLCOM_SHOW_PROCESSLIST, SQLCOM_SHOW_MASTER_STAT, SQLCOM_SHOW_SLAVE_STAT,
|
SQLCOM_SHOW_PROCESSLIST, SQLCOM_SHOW_MASTER_STAT, SQLCOM_SHOW_SLAVE_STAT,
|
||||||
SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_CREATE, SQLCOM_SHOW_CHARSETS,
|
SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_CREATE, SQLCOM_SHOW_CHARSETS,
|
||||||
|
SQLCOM_SHOW_CREATE_DB,
|
||||||
|
|
||||||
SQLCOM_LOAD,SQLCOM_SET_OPTION,SQLCOM_LOCK_TABLES,SQLCOM_UNLOCK_TABLES,
|
SQLCOM_LOAD,SQLCOM_SET_OPTION,SQLCOM_LOCK_TABLES,SQLCOM_UNLOCK_TABLES,
|
||||||
SQLCOM_GRANT, SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB,
|
SQLCOM_GRANT,
|
||||||
|
SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB, SQLCOM_ALTER_DB,
|
||||||
SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT,
|
SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT,
|
||||||
SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION,
|
SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION,
|
||||||
SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK,
|
SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK,
|
||||||
@ -234,11 +236,12 @@ private:
|
|||||||
bool create_total_list_n_last_return(THD *thd, st_lex *lex,
|
bool create_total_list_n_last_return(THD *thd, st_lex *lex,
|
||||||
TABLE_LIST ***result);
|
TABLE_LIST ***result);
|
||||||
};
|
};
|
||||||
typedef struct st_select_lex_unit SELECT_LEX_UNIT;
|
typedef class st_select_lex_unit SELECT_LEX_UNIT;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SELECT_LEX - store information of parsed SELECT_LEX statment
|
SELECT_LEX - store information of parsed SELECT_LEX statment
|
||||||
*/
|
*/
|
||||||
|
class JOIN;
|
||||||
class st_select_lex: public st_select_lex_node {
|
class st_select_lex: public st_select_lex_node {
|
||||||
public:
|
public:
|
||||||
char *db, *db1, *table1, *db2, *table2; /* For outer join using .. */
|
char *db, *db1, *table1, *db2, *table2; /* For outer join using .. */
|
||||||
@ -250,10 +253,14 @@ public:
|
|||||||
List<String> interval_list, use_index, *use_index_ptr,
|
List<String> interval_list, use_index, *use_index_ptr,
|
||||||
ignore_index, *ignore_index_ptr;
|
ignore_index, *ignore_index_ptr;
|
||||||
List<Item_func_match> ftfunc_list;
|
List<Item_func_match> ftfunc_list;
|
||||||
|
JOIN *join; /* after JOIN::prepare it is pointer to corresponding JOIN */
|
||||||
uint in_sum_expr;
|
uint in_sum_expr;
|
||||||
bool create_refs,
|
bool create_refs,
|
||||||
braces, /* SELECT ... UNION (SELECT ... ) <- this braces */
|
braces, /* SELECT ... UNION (SELECT ... ) <- this braces */
|
||||||
depended; /* depended from outer select subselect */
|
depended, /* depended from outer select subselect */
|
||||||
|
/* TRUE when having fix field called in processing of this SELECT */
|
||||||
|
having_fix_field;
|
||||||
|
|
||||||
void init_query();
|
void init_query();
|
||||||
void init_select();
|
void init_select();
|
||||||
st_select_lex_unit* master_unit() { return (st_select_lex_unit*) master; }
|
st_select_lex_unit* master_unit() { return (st_select_lex_unit*) master; }
|
||||||
@ -277,7 +284,7 @@ public:
|
|||||||
|
|
||||||
friend void mysql_init_query(THD *thd);
|
friend void mysql_init_query(THD *thd);
|
||||||
};
|
};
|
||||||
typedef struct st_select_lex SELECT_LEX;
|
typedef class st_select_lex SELECT_LEX;
|
||||||
|
|
||||||
class Set_option :public Sql_alloc {
|
class Set_option :public Sql_alloc {
|
||||||
public:
|
public:
|
||||||
|
@ -2310,7 +2310,7 @@ mysql_execute_command(void)
|
|||||||
}
|
}
|
||||||
if (check_access(thd,CREATE_ACL,lex->name,0,1))
|
if (check_access(thd,CREATE_ACL,lex->name,0,1))
|
||||||
break;
|
break;
|
||||||
res=mysql_create_db(thd,lex->name,lex->create_info.options,0);
|
res=mysql_create_db(thd,lex->name,&lex->create_info,0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_DROP_DB:
|
case SQLCOM_DROP_DB:
|
||||||
@ -2330,6 +2330,40 @@ mysql_execute_command(void)
|
|||||||
res=mysql_rm_db(thd,lex->name,lex->drop_if_exists,0);
|
res=mysql_rm_db(thd,lex->name,lex->drop_if_exists,0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SQLCOM_ALTER_DB:
|
||||||
|
{
|
||||||
|
if (!strip_sp(lex->name) || check_db_name(lex->name))
|
||||||
|
{
|
||||||
|
net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (check_access(thd,ALTER_ACL,lex->name,0,1))
|
||||||
|
break;
|
||||||
|
if (thd->locked_tables || thd->active_transaction())
|
||||||
|
{
|
||||||
|
send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
res=mysql_alter_db(thd,lex->name,&lex->create_info,0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SQLCOM_SHOW_CREATE_DB:
|
||||||
|
{
|
||||||
|
if (!strip_sp(lex->name) || check_db_name(lex->name))
|
||||||
|
{
|
||||||
|
net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (check_access(thd,DROP_ACL,lex->name,0,1))
|
||||||
|
break;
|
||||||
|
if (thd->locked_tables || thd->active_transaction())
|
||||||
|
{
|
||||||
|
send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
res=mysqld_show_create_db(thd,lex->name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case SQLCOM_CREATE_FUNCTION:
|
case SQLCOM_CREATE_FUNCTION:
|
||||||
if (check_access(thd,INSERT_ACL,"mysql",0,1))
|
if (check_access(thd,INSERT_ACL,"mysql",0,1))
|
||||||
break;
|
break;
|
||||||
|
@ -448,7 +448,7 @@ static bool mysql_test_upd_fields(THD *thd, TABLE_LIST *table_list,
|
|||||||
static bool mysql_test_select_fields(THD *thd, TABLE_LIST *tables,
|
static bool mysql_test_select_fields(THD *thd, TABLE_LIST *tables,
|
||||||
List<Item> &fields, List<Item> &values,
|
List<Item> &fields, List<Item> &values,
|
||||||
COND *conds, ORDER *order, ORDER *group,
|
COND *conds, ORDER *order, ORDER *group,
|
||||||
Item *having,thr_lock_type lock_type)
|
Item *having, thr_lock_type lock_type)
|
||||||
{
|
{
|
||||||
TABLE *table;
|
TABLE *table;
|
||||||
bool hidden_group_fields;
|
bool hidden_group_fields;
|
||||||
@ -470,7 +470,7 @@ static bool mysql_test_select_fields(THD *thd, TABLE_LIST *tables,
|
|||||||
{
|
{
|
||||||
thd->where="having clause";
|
thd->where="having clause";
|
||||||
thd->allow_sum_func=1;
|
thd->allow_sum_func=1;
|
||||||
if (having->fix_fields(thd,tables) || thd->fatal_error)
|
if (having->fix_fields(thd, tables, &having) || thd->fatal_error)
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
if (having->with_sum_func)
|
if (having->with_sum_func)
|
||||||
having->split_sum_func(all_fields);
|
having->split_sum_func(all_fields);
|
||||||
|
@ -211,6 +211,7 @@ JOIN::prepare(TABLE_LIST *tables_init,
|
|||||||
proc_param= proc_param_init;
|
proc_param= proc_param_init;
|
||||||
tables_list= tables_init;
|
tables_list= tables_init;
|
||||||
select_lex= select;
|
select_lex= select;
|
||||||
|
select->join= this;
|
||||||
union_part= (unit->first_select()->next_select() != 0);
|
union_part= (unit->first_select()->next_select() != 0);
|
||||||
|
|
||||||
/* Check that all tables, fields, conds and order are ok */
|
/* Check that all tables, fields, conds and order are ok */
|
||||||
@ -227,10 +228,9 @@ JOIN::prepare(TABLE_LIST *tables_init,
|
|||||||
{
|
{
|
||||||
thd->where="having clause";
|
thd->where="having clause";
|
||||||
thd->allow_sum_func=1;
|
thd->allow_sum_func=1;
|
||||||
bool having_fix_field_store= thd->having_fix_field;
|
select_lex->having_fix_field= 1;
|
||||||
thd->having_fix_field= 1;
|
bool having_fix_rc= having->fix_fields(thd, tables_list, &having);
|
||||||
bool having_fix_rc= having->fix_fields(thd,tables_list);
|
select_lex->having_fix_field= 0;
|
||||||
thd->having_fix_field= having_fix_field_store;
|
|
||||||
if (having_fix_rc || thd->fatal_error)
|
if (having_fix_rc || thd->fatal_error)
|
||||||
DBUG_RETURN(-1); /* purecov: inspected */
|
DBUG_RETURN(-1); /* purecov: inspected */
|
||||||
if (having->with_sum_func)
|
if (having->with_sum_func)
|
||||||
@ -349,7 +349,7 @@ JOIN::optimize()
|
|||||||
}
|
}
|
||||||
else if ((conds=new Item_cond_and(conds,having)))
|
else if ((conds=new Item_cond_and(conds,having)))
|
||||||
{
|
{
|
||||||
conds->fix_fields(thd, tables_list);
|
conds->fix_fields(thd, tables_list, &conds);
|
||||||
conds->change_ref_to_fields(thd, tables_list);
|
conds->change_ref_to_fields(thd, tables_list);
|
||||||
having= 0;
|
having= 0;
|
||||||
}
|
}
|
||||||
@ -613,6 +613,15 @@ JOIN::reinit()
|
|||||||
if (setup_tables(tables_list))
|
if (setup_tables(tables_list))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
|
// Reset of sum functions
|
||||||
|
first_record= 0;
|
||||||
|
if (sum_funcs)
|
||||||
|
{
|
||||||
|
Item_sum *func, **func_ptr= sum_funcs;
|
||||||
|
while ((func= *(func_ptr++)))
|
||||||
|
func->null_value= 1;
|
||||||
|
}
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -966,6 +975,21 @@ JOIN::cleanup(THD *thd)
|
|||||||
delete select;
|
delete select;
|
||||||
delete_dynamic(&keyuse);
|
delete_dynamic(&keyuse);
|
||||||
delete procedure;
|
delete procedure;
|
||||||
|
for (SELECT_LEX_UNIT *unit= select_lex->first_inner_unit();
|
||||||
|
unit != 0;
|
||||||
|
unit= unit->next_unit())
|
||||||
|
for (SELECT_LEX *sl= unit->first_select();
|
||||||
|
sl != 0;
|
||||||
|
sl= sl->next_select())
|
||||||
|
{
|
||||||
|
if (sl->join)
|
||||||
|
{
|
||||||
|
int err= sl->join->cleanup(thd);
|
||||||
|
if (err)
|
||||||
|
error= err;
|
||||||
|
sl->join= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3381,7 +3405,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
|
|||||||
21))))
|
21))))
|
||||||
{
|
{
|
||||||
cond=new_cond;
|
cond=new_cond;
|
||||||
cond->fix_fields(thd,0);
|
cond->fix_fields(thd, 0, &cond);
|
||||||
}
|
}
|
||||||
thd->insert_id(0); // Clear for next request
|
thd->insert_id(0); // Clear for next request
|
||||||
}
|
}
|
||||||
@ -3395,7 +3419,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
|
|||||||
if ((new_cond= new Item_func_eq(args[0],new Item_int("0", 0, 2))))
|
if ((new_cond= new Item_func_eq(args[0],new Item_int("0", 0, 2))))
|
||||||
{
|
{
|
||||||
cond=new_cond;
|
cond=new_cond;
|
||||||
cond->fix_fields(thd,0);
|
cond->fix_fields(thd, 0, &cond);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3523,7 +3547,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
|||||||
case STRING_RESULT:
|
case STRING_RESULT:
|
||||||
if (item_sum->max_length > 255)
|
if (item_sum->max_length > 255)
|
||||||
return new Field_blob(item_sum->max_length,maybe_null,
|
return new Field_blob(item_sum->max_length,maybe_null,
|
||||||
item->name,table,item->binary);
|
item->name,table,item->binary,default_charset_info);
|
||||||
return new Field_string(item_sum->max_length,maybe_null,
|
return new Field_string(item_sum->max_length,maybe_null,
|
||||||
item->name,table,item->binary,default_charset_info);
|
item->name,table,item->binary,default_charset_info);
|
||||||
}
|
}
|
||||||
@ -3576,10 +3600,12 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
|||||||
case STRING_RESULT:
|
case STRING_RESULT:
|
||||||
if (item->max_length > 255)
|
if (item->max_length > 255)
|
||||||
new_field= new Field_blob(item->max_length,maybe_null,
|
new_field= new Field_blob(item->max_length,maybe_null,
|
||||||
item->name,table,item->binary);
|
item->name,table,item->binary,
|
||||||
|
item->str_value.charset());
|
||||||
else
|
else
|
||||||
new_field= new Field_string(item->max_length,maybe_null,
|
new_field= new Field_string(item->max_length,maybe_null,
|
||||||
item->name,table,item->binary,default_charset_info);
|
item->name,table,item->binary,
|
||||||
|
item->str_value.charset());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (copy_func)
|
if (copy_func)
|
||||||
@ -4103,7 +4129,9 @@ static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
|
|||||||
{
|
{
|
||||||
Field *field=keyinfo->key_part[i].field;
|
Field *field=keyinfo->key_part[i].field;
|
||||||
seg->flag= 0;
|
seg->flag= 0;
|
||||||
seg->language= MY_CHARSET_CURRENT;
|
seg->language= field->binary() ? MY_CHARSET_CURRENT :
|
||||||
|
((Field_str*)field)->charset()->number;
|
||||||
|
|
||||||
seg->length= keyinfo->key_part[i].length;
|
seg->length= keyinfo->key_part[i].length;
|
||||||
seg->start= keyinfo->key_part[i].offset;
|
seg->start= keyinfo->key_part[i].offset;
|
||||||
if (field->flags & BLOB_FLAG)
|
if (field->flags & BLOB_FLAG)
|
||||||
@ -6428,7 +6456,7 @@ find_order_in_list(THD *thd,TABLE_LIST *tables,ORDER *order,List<Item> &fields,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
order->in_field_list=0;
|
order->in_field_list=0;
|
||||||
if ((*order->item)->fix_fields(thd,tables) || thd->fatal_error)
|
if ((*order->item)->fix_fields(thd, tables, order->item) || thd->fatal_error)
|
||||||
return 1; // Wrong field
|
return 1; // Wrong field
|
||||||
all_fields.push_front(*order->item); // Add new field to field list
|
all_fields.push_front(*order->item); // Add new field to field list
|
||||||
order->item=(Item**) all_fields.head_ref();
|
order->item=(Item**) all_fields.head_ref();
|
||||||
@ -6526,7 +6554,7 @@ setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
thd->where="procedure list";
|
thd->where="procedure list";
|
||||||
if ((*new_field->item)->fix_fields(thd,tables))
|
if ((*new_field->item)->fix_fields(thd, tables, new_field->item))
|
||||||
DBUG_RETURN(1); /* purecov: inspected */
|
DBUG_RETURN(1); /* purecov: inspected */
|
||||||
thd->where=0;
|
thd->where=0;
|
||||||
all_fields.push_front(*new_field->item);
|
all_fields.push_front(*new_field->item);
|
||||||
@ -7091,7 +7119,7 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
|
|||||||
Here we pass 0 as the first argument to fix_fields that don't need
|
Here we pass 0 as the first argument to fix_fields that don't need
|
||||||
to do any stack checking (This is already done in the initial fix_fields).
|
to do any stack checking (This is already done in the initial fix_fields).
|
||||||
*/
|
*/
|
||||||
cond->fix_fields((THD *) 0,(TABLE_LIST *) 0);
|
cond->fix_fields((THD *) 0,(TABLE_LIST *) 0, (Item**)&cond);
|
||||||
if (join_tab->select)
|
if (join_tab->select)
|
||||||
{
|
{
|
||||||
error=(int) cond->add(join_tab->select->cond);
|
error=(int) cond->add(join_tab->select->cond);
|
||||||
|
@ -1158,6 +1158,12 @@ store_create_info(THD *thd, TABLE *table, String *packet)
|
|||||||
char buff[128];
|
char buff[128];
|
||||||
char* p;
|
char* p;
|
||||||
|
|
||||||
|
if (table->table_charset)
|
||||||
|
{
|
||||||
|
packet->append(" CHARSET=");
|
||||||
|
packet->append(table->table_charset->name);
|
||||||
|
}
|
||||||
|
|
||||||
if (table->min_rows)
|
if (table->min_rows)
|
||||||
{
|
{
|
||||||
packet->append(" MIN_ROWS=");
|
packet->append(" MIN_ROWS=");
|
||||||
@ -1389,7 +1395,7 @@ int mysqld_show_charsets(THD *thd, const char *wild)
|
|||||||
net_store_data(&packet2,(uint32) cs->mbmaxlen);
|
net_store_data(&packet2,(uint32) cs->mbmaxlen);
|
||||||
|
|
||||||
if (my_net_write(&thd->net, (char*) packet2.ptr(),packet2.length()))
|
if (my_net_write(&thd->net, (char*) packet2.ptr(),packet2.length()))
|
||||||
goto err; /* purecov: inspected */
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
send_eof(&thd->net);
|
send_eof(&thd->net);
|
||||||
|
@ -375,6 +375,11 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
|
|||||||
sql_field->offset= pos;
|
sql_field->offset= pos;
|
||||||
if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
|
if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
|
||||||
auto_increment++;
|
auto_increment++;
|
||||||
|
if(!sql_field->charset)
|
||||||
|
sql_field->charset = create_info->table_charset ?
|
||||||
|
create_info->table_charset :
|
||||||
|
thd->db_charset? thd->db_charset :
|
||||||
|
default_charset_info;
|
||||||
pos+=sql_field->pack_length;
|
pos+=sql_field->pack_length;
|
||||||
}
|
}
|
||||||
if (auto_increment > 1)
|
if (auto_increment > 1)
|
||||||
@ -1648,6 +1653,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
create_info->max_rows=table->max_rows;
|
create_info->max_rows=table->max_rows;
|
||||||
if (!(used_fields & HA_CREATE_USED_AVG_ROW_LENGTH))
|
if (!(used_fields & HA_CREATE_USED_AVG_ROW_LENGTH))
|
||||||
create_info->avg_row_length=table->avg_row_length;
|
create_info->avg_row_length=table->avg_row_length;
|
||||||
|
if (!(used_fields & HA_CREATE_USED_CHARSET))
|
||||||
|
create_info->table_charset=table->table_charset;
|
||||||
|
|
||||||
table->file->update_create_info(create_info);
|
table->file->update_create_info(create_info);
|
||||||
if ((create_info->table_options &
|
if ((create_info->table_options &
|
||||||
|
113
sql/sql_yacc.yy
113
sql/sql_yacc.yy
@ -162,6 +162,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
|||||||
%token CACHE_SYM
|
%token CACHE_SYM
|
||||||
%token CASCADE
|
%token CASCADE
|
||||||
%token CAST_SYM
|
%token CAST_SYM
|
||||||
|
%token CHARSET
|
||||||
%token CHECKSUM_SYM
|
%token CHECKSUM_SYM
|
||||||
%token CHECK_SYM
|
%token CHECK_SYM
|
||||||
%token CIPHER
|
%token CIPHER
|
||||||
@ -333,6 +334,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
|||||||
%token UDF_SONAME_SYM
|
%token UDF_SONAME_SYM
|
||||||
%token UDF_SYM
|
%token UDF_SYM
|
||||||
%token UNCOMMITTED_SYM
|
%token UNCOMMITTED_SYM
|
||||||
|
%token UNDERSCORE_CHARSET
|
||||||
%token UNION_SYM
|
%token UNION_SYM
|
||||||
%token UNIQUE_SYM
|
%token UNIQUE_SYM
|
||||||
%token USAGE
|
%token USAGE
|
||||||
@ -524,7 +526,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
|||||||
|
|
||||||
%type <lex_str>
|
%type <lex_str>
|
||||||
IDENT TEXT_STRING REAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM LEX_HOSTNAME
|
IDENT TEXT_STRING REAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM LEX_HOSTNAME
|
||||||
ULONGLONG_NUM field_ident select_alias ident ident_or_text
|
ULONGLONG_NUM field_ident select_alias ident ident_or_text UNDERSCORE_CHARSET
|
||||||
|
|
||||||
%type <lex_str_ptr>
|
%type <lex_str_ptr>
|
||||||
opt_table_alias
|
opt_table_alias
|
||||||
@ -554,7 +556,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
|||||||
literal text_literal insert_ident order_ident
|
literal text_literal insert_ident order_ident
|
||||||
simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr
|
simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr
|
||||||
table_wild opt_pad no_in_expr expr_expr simple_expr no_and_expr
|
table_wild opt_pad no_in_expr expr_expr simple_expr no_and_expr
|
||||||
using_list param_marker subselect subselect_init
|
using_list param_marker singleval_subselect singleval_subselect_init
|
||||||
|
exists_subselect exists_subselect_init
|
||||||
|
|
||||||
%type <item_list>
|
%type <item_list>
|
||||||
expr_list udf_expr_list when_list ident_list ident_list_arg
|
expr_list udf_expr_list when_list ident_list ident_list_arg
|
||||||
@ -767,7 +770,7 @@ create:
|
|||||||
bzero((char*) &lex->create_info,sizeof(lex->create_info));
|
bzero((char*) &lex->create_info,sizeof(lex->create_info));
|
||||||
lex->create_info.options=$2 | $4;
|
lex->create_info.options=$2 | $4;
|
||||||
lex->create_info.db_type= default_table_type;
|
lex->create_info.db_type= default_table_type;
|
||||||
lex->create_info.table_charset=default_charset_info;
|
lex->create_info.table_charset=NULL;
|
||||||
}
|
}
|
||||||
create2
|
create2
|
||||||
|
|
||||||
@ -795,6 +798,7 @@ create:
|
|||||||
lex->sql_command=SQLCOM_CREATE_DB;
|
lex->sql_command=SQLCOM_CREATE_DB;
|
||||||
lex->name=$4.str;
|
lex->name=$4.str;
|
||||||
lex->create_info.options=$3;
|
lex->create_info.options=$3;
|
||||||
|
lex->create_info.table_charset=lex->charset;
|
||||||
}
|
}
|
||||||
| CREATE udf_func_type UDF_SYM ident
|
| CREATE udf_func_type UDF_SYM ident
|
||||||
{
|
{
|
||||||
@ -881,6 +885,11 @@ create_table_option:
|
|||||||
table_list->next=0;
|
table_list->next=0;
|
||||||
lex->create_info.used_fields|= HA_CREATE_USED_UNION;
|
lex->create_info.used_fields|= HA_CREATE_USED_UNION;
|
||||||
}
|
}
|
||||||
|
| CHARSET EQ charset_or_nocharset
|
||||||
|
{
|
||||||
|
Lex->create_info.table_charset=Lex->charset;
|
||||||
|
Lex->create_info.used_fields|= HA_CREATE_USED_CHARSET;
|
||||||
|
}
|
||||||
| INSERT_METHOD EQ merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;}
|
| INSERT_METHOD EQ merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;}
|
||||||
| DATA_SYM DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.data_file_name= $4.str; }
|
| DATA_SYM DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.data_file_name= $4.str; }
|
||||||
| INDEX DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.index_file_name= $4.str; };
|
| INDEX DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.index_file_name= $4.str; };
|
||||||
@ -965,7 +974,7 @@ field_spec:
|
|||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->length=lex->dec=0; lex->type=0; lex->interval=0;
|
lex->length=lex->dec=0; lex->type=0; lex->interval=0;
|
||||||
lex->default_value=lex->comment=0;
|
lex->default_value=lex->comment=0;
|
||||||
lex->charset=default_charset_info;
|
lex->charset=NULL;
|
||||||
}
|
}
|
||||||
type opt_attribute
|
type opt_attribute
|
||||||
{
|
{
|
||||||
@ -1115,32 +1124,28 @@ attribute:
|
|||||||
| UNIQUE_SYM KEY_SYM { Lex->type|= UNIQUE_KEY_FLAG; }
|
| UNIQUE_SYM KEY_SYM { Lex->type|= UNIQUE_KEY_FLAG; }
|
||||||
| COMMENT_SYM text_literal { Lex->comment= $2; };
|
| COMMENT_SYM text_literal { Lex->comment= $2; };
|
||||||
|
|
||||||
opt_binary:
|
charset:
|
||||||
/* empty */ { Lex->charset=default_charset_info; }
|
ident
|
||||||
| BINARY { Lex->type|=BINARY_FLAG; Lex->charset=default_charset_info; }
|
|
||||||
| CHAR_SYM SET ident
|
|
||||||
{
|
{
|
||||||
CHARSET_INFO *cs=get_charset_by_name($3.str,MYF(MY_WME));
|
if (!(Lex->charset=get_charset_by_name($1.str,MYF(0))))
|
||||||
if (!cs)
|
|
||||||
{
|
{
|
||||||
net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$3);
|
net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$1);
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
Lex->charset=cs;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
charset_or_nocharset:
|
||||||
|
charset
|
||||||
|
| DEFAULT {Lex->charset=NULL; }
|
||||||
|
|
||||||
|
opt_binary:
|
||||||
|
/* empty */ { Lex->charset=NULL; }
|
||||||
|
| BINARY { Lex->type|=BINARY_FLAG; Lex->charset=NULL; }
|
||||||
|
| CHAR_SYM SET charset {/* charset is already in Lex->charset */} ;
|
||||||
|
|
||||||
default_charset:
|
default_charset:
|
||||||
/* empty */ { Lex->charset-default_charset_info; }
|
/* empty */ { Lex->charset=NULL; }
|
||||||
| DEFAULT CHAR_SYM SET ident
|
| DEFAULT CHAR_SYM SET charset_or_nocharset ;
|
||||||
{
|
|
||||||
CHARSET_INFO *cs=get_charset_by_name($4.str,MYF(MY_WME));
|
|
||||||
if (!cs)
|
|
||||||
{
|
|
||||||
net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$4);
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
Lex->charset=cs;
|
|
||||||
};
|
|
||||||
|
|
||||||
references:
|
references:
|
||||||
REFERENCES table_ident
|
REFERENCES table_ident
|
||||||
@ -1259,12 +1264,21 @@ alter:
|
|||||||
bzero((char*) &lex->create_info,sizeof(lex->create_info));
|
bzero((char*) &lex->create_info,sizeof(lex->create_info));
|
||||||
lex->create_info.db_type= DB_TYPE_DEFAULT;
|
lex->create_info.db_type= DB_TYPE_DEFAULT;
|
||||||
lex->create_info.row_type= ROW_TYPE_NOT_USED;
|
lex->create_info.row_type= ROW_TYPE_NOT_USED;
|
||||||
lex->create_info.table_charset=default_charset_info;
|
lex->create_info.table_charset=NULL;
|
||||||
lex->alter_keys_onoff=LEAVE_AS_IS;
|
lex->alter_keys_onoff=LEAVE_AS_IS;
|
||||||
lex->simple_alter=1;
|
lex->simple_alter=1;
|
||||||
}
|
}
|
||||||
alter_list;
|
alter_list;
|
||||||
|
|
||||||
|
| ALTER DATABASE ident default_charset
|
||||||
|
{
|
||||||
|
LEX *lex=Lex;
|
||||||
|
lex->sql_command=SQLCOM_ALTER_DB;
|
||||||
|
lex->name=$3.str;
|
||||||
|
lex->create_info.table_charset=lex->charset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
alter_list:
|
alter_list:
|
||||||
| alter_list_item
|
| alter_list_item
|
||||||
| alter_list ',' alter_list_item;
|
| alter_list ',' alter_list_item;
|
||||||
@ -1745,7 +1759,8 @@ simple_expr:
|
|||||||
| NOT expr %prec NEG { $$= new Item_func_not($2); }
|
| NOT expr %prec NEG { $$= new Item_func_not($2); }
|
||||||
| '!' expr %prec NEG { $$= new Item_func_not($2); }
|
| '!' expr %prec NEG { $$= new Item_func_not($2); }
|
||||||
| '(' expr ')' { $$= $2; }
|
| '(' expr ')' { $$= $2; }
|
||||||
| subselect { $$= $1; }
|
| EXISTS exists_subselect { $$= $2; }
|
||||||
|
| singleval_subselect { $$= $1; }
|
||||||
| '{' ident expr '}' { $$= $3; }
|
| '{' ident expr '}' { $$= $3; }
|
||||||
| MATCH ident_list_arg AGAINST '(' expr ')'
|
| MATCH ident_list_arg AGAINST '(' expr ')'
|
||||||
{ Select->ftfunc_list.push_back((Item_func_match *)
|
{ Select->ftfunc_list.push_back((Item_func_match *)
|
||||||
@ -1758,16 +1773,8 @@ simple_expr:
|
|||||||
| CASE_SYM opt_expr WHEN_SYM when_list opt_else END
|
| CASE_SYM opt_expr WHEN_SYM when_list opt_else END
|
||||||
{ $$= new Item_func_case(* $4, $2, $5 ); }
|
{ $$= new Item_func_case(* $4, $2, $5 ); }
|
||||||
| CONVERT_SYM '(' expr ',' cast_type ')' { $$= create_func_cast($3, $5); }
|
| CONVERT_SYM '(' expr ',' cast_type ')' { $$= create_func_cast($3, $5); }
|
||||||
| CONVERT_SYM '(' expr USING IDENT ')'
|
| CONVERT_SYM '(' expr USING charset ')'
|
||||||
{
|
{ $$= new Item_func_conv_charset($3,Lex->charset); }
|
||||||
CHARSET_INFO *cs=get_charset_by_name($5.str,MYF(MY_WME));
|
|
||||||
if (!cs)
|
|
||||||
{
|
|
||||||
net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$5);
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
$$= new Item_func_conv_charset($3,cs);
|
|
||||||
}
|
|
||||||
| CONVERT_SYM '(' expr ',' expr ',' expr ')'
|
| CONVERT_SYM '(' expr ',' expr ',' expr ')'
|
||||||
{
|
{
|
||||||
$$= new Item_func_conv_charset3($3,$7,$5);
|
$$= new Item_func_conv_charset3($3,$7,$5);
|
||||||
@ -1786,6 +1793,8 @@ simple_expr:
|
|||||||
{ $$= new Item_func_atan($3,$5); }
|
{ $$= new Item_func_atan($3,$5); }
|
||||||
| CHAR_SYM '(' expr_list ')'
|
| CHAR_SYM '(' expr_list ')'
|
||||||
{ $$= new Item_func_char(*$3); }
|
{ $$= new Item_func_char(*$3); }
|
||||||
|
| CHARSET '(' expr ')'
|
||||||
|
{ $$= new Item_func_charset($3); }
|
||||||
| COALESCE '(' expr_list ')'
|
| COALESCE '(' expr_list ')'
|
||||||
{ $$= new Item_func_coalesce(* $3); }
|
{ $$= new Item_func_coalesce(* $3); }
|
||||||
| CONCAT '(' expr_list ')'
|
| CONCAT '(' expr_list ')'
|
||||||
@ -2842,6 +2851,11 @@ show_param:
|
|||||||
lex->grant_user=$3;
|
lex->grant_user=$3;
|
||||||
lex->grant_user->password.str=NullS;
|
lex->grant_user->password.str=NullS;
|
||||||
}
|
}
|
||||||
|
| CREATE DATABASE ident
|
||||||
|
{
|
||||||
|
Lex->sql_command=SQLCOM_SHOW_CREATE_DB;
|
||||||
|
Lex->name=$3.str;
|
||||||
|
}
|
||||||
| CREATE TABLE_SYM table_ident
|
| CREATE TABLE_SYM table_ident
|
||||||
{
|
{
|
||||||
Lex->sql_command = SQLCOM_SHOW_CREATE;
|
Lex->sql_command = SQLCOM_SHOW_CREATE;
|
||||||
@ -2972,7 +2986,7 @@ kill:
|
|||||||
KILL_SYM expr
|
KILL_SYM expr
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
if ($2->fix_fields(lex->thd,0))
|
if ($2->fix_fields(lex->thd, 0, &$2))
|
||||||
{
|
{
|
||||||
send_error(&lex->thd->net, ER_SET_CONSTANTS_ONLY);
|
send_error(&lex->thd->net, ER_SET_CONSTANTS_ONLY);
|
||||||
YYABORT;
|
YYABORT;
|
||||||
@ -3075,6 +3089,7 @@ opt_ignore_lines:
|
|||||||
|
|
||||||
text_literal:
|
text_literal:
|
||||||
TEXT_STRING { $$ = new Item_string($1.str,$1.length,default_charset_info); }
|
TEXT_STRING { $$ = new Item_string($1.str,$1.length,default_charset_info); }
|
||||||
|
| UNDERSCORE_CHARSET TEXT_STRING { $$ = new Item_string($2.str,$2.length,Lex->charset); }
|
||||||
| text_literal TEXT_STRING
|
| text_literal TEXT_STRING
|
||||||
{ ((Item_string*) $1)->append($2.str,$2.length); };
|
{ ((Item_string*) $1)->append($2.str,$2.length); };
|
||||||
|
|
||||||
@ -3467,7 +3482,8 @@ option_value:
|
|||||||
| '@' ident_or_text equal expr
|
| '@' ident_or_text equal expr
|
||||||
{
|
{
|
||||||
Item_func_set_user_var *item = new Item_func_set_user_var($2,$4);
|
Item_func_set_user_var *item = new Item_func_set_user_var($2,$4);
|
||||||
if (item->fix_fields(current_thd,0) || item->update())
|
if (item->fix_fields(current_thd, 0, (Item**) &item) ||
|
||||||
|
item->update())
|
||||||
{
|
{
|
||||||
send_error(¤t_thd->net, ER_SET_CONSTANTS_ONLY);
|
send_error(¤t_thd->net, ER_SET_CONSTANTS_ONLY);
|
||||||
YYABORT;
|
YYABORT;
|
||||||
@ -3499,7 +3515,7 @@ option_value:
|
|||||||
{
|
{
|
||||||
THD *thd=current_thd;
|
THD *thd=current_thd;
|
||||||
Item *item= $3;
|
Item *item= $3;
|
||||||
if (item->fix_fields(current_thd,0))
|
if (item->fix_fields(current_thd, 0, &item))
|
||||||
{
|
{
|
||||||
send_error(&thd->net, ER_SET_CONSTANTS_ONLY);
|
send_error(&thd->net, ER_SET_CONSTANTS_ONLY);
|
||||||
YYABORT;
|
YYABORT;
|
||||||
@ -3973,17 +3989,30 @@ union_option:
|
|||||||
/* empty */ {}
|
/* empty */ {}
|
||||||
| ALL {Lex->union_option=1;};
|
| ALL {Lex->union_option=1;};
|
||||||
|
|
||||||
subselect:
|
singleval_subselect:
|
||||||
subselect_start subselect_init
|
subselect_start singleval_subselect_init
|
||||||
subselect_end
|
subselect_end
|
||||||
{
|
{
|
||||||
$$= $2;
|
$$= $2;
|
||||||
};
|
};
|
||||||
|
|
||||||
subselect_init:
|
singleval_subselect_init:
|
||||||
select_init
|
select_init
|
||||||
{
|
{
|
||||||
$$= new Item_subselect(current_thd, Lex->select);
|
$$= new Item_singleval_subselect(current_thd, Lex->select);
|
||||||
|
};
|
||||||
|
|
||||||
|
exists_subselect:
|
||||||
|
subselect_start exists_subselect_init
|
||||||
|
subselect_end
|
||||||
|
{
|
||||||
|
$$= $2;
|
||||||
|
};
|
||||||
|
|
||||||
|
exists_subselect_init:
|
||||||
|
select_init
|
||||||
|
{
|
||||||
|
$$= new Item_exists_subselect(current_thd, Lex->select);
|
||||||
};
|
};
|
||||||
|
|
||||||
subselect_start:
|
subselect_start:
|
||||||
|
11
sql/table.cc
11
sql/table.cc
@ -118,7 +118,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
|
|||||||
outparam->raid_chunks= head[42];
|
outparam->raid_chunks= head[42];
|
||||||
outparam->raid_chunksize= uint4korr(head+43);
|
outparam->raid_chunksize= uint4korr(head+43);
|
||||||
if (!(outparam->table_charset=get_charset((uint) head[38],MYF(0))))
|
if (!(outparam->table_charset=get_charset((uint) head[38],MYF(0))))
|
||||||
outparam->table_charset=default_charset_info;
|
outparam->table_charset=NULL; // QQ display error message?
|
||||||
null_field_first=1;
|
null_field_first=1;
|
||||||
}
|
}
|
||||||
outparam->db_record_offset=1;
|
outparam->db_record_offset=1;
|
||||||
@ -358,7 +358,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
|
|||||||
uint comment_length=uint2korr(strpos+13);
|
uint comment_length=uint2korr(strpos+13);
|
||||||
field_type=(enum_field_types) (uint) strpos[11];
|
field_type=(enum_field_types) (uint) strpos[11];
|
||||||
if (!(charset=get_charset((uint) strpos[12], MYF(0))))
|
if (!(charset=get_charset((uint) strpos[12], MYF(0))))
|
||||||
charset=outparam->table_charset;
|
charset=outparam->table_charset?outparam->table_charset:default_charset_info;
|
||||||
if (!comment_length)
|
if (!comment_length)
|
||||||
{
|
{
|
||||||
comment.str= (char*) "";
|
comment.str= (char*) "";
|
||||||
@ -375,7 +375,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
|
|||||||
{
|
{
|
||||||
/* old frm file */
|
/* old frm file */
|
||||||
field_type= (enum_field_types) f_packtype(pack_flag);
|
field_type= (enum_field_types) f_packtype(pack_flag);
|
||||||
charset=outparam->table_charset;
|
charset=outparam->table_charset?outparam->table_charset:default_charset_info;
|
||||||
bzero((char*) &comment, sizeof(comment));
|
bzero((char*) &comment, sizeof(comment));
|
||||||
}
|
}
|
||||||
*field_ptr=reg_field=
|
*field_ptr=reg_field=
|
||||||
@ -1041,7 +1041,7 @@ File create_frm(register my_string name, uint reclength, uchar *fileinfo,
|
|||||||
int2store(fileinfo+30,create_info->table_options);
|
int2store(fileinfo+30,create_info->table_options);
|
||||||
fileinfo[32]=0; // No filename anymore
|
fileinfo[32]=0; // No filename anymore
|
||||||
int4store(fileinfo+34,create_info->avg_row_length);
|
int4store(fileinfo+34,create_info->avg_row_length);
|
||||||
fileinfo[38]= create_info->table_charset->number;
|
fileinfo[38]= create_info->table_charset?create_info->table_charset->number:0;
|
||||||
fileinfo[40]= (uchar) create_info->row_type;
|
fileinfo[40]= (uchar) create_info->row_type;
|
||||||
fileinfo[41]= (uchar) create_info->raid_type;
|
fileinfo[41]= (uchar) create_info->raid_type;
|
||||||
fileinfo[42]= (uchar) create_info->raid_chunks;
|
fileinfo[42]= (uchar) create_info->raid_chunks;
|
||||||
@ -1072,6 +1072,7 @@ void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table)
|
|||||||
create_info->raid_type=table->raid_type;
|
create_info->raid_type=table->raid_type;
|
||||||
create_info->raid_chunks=table->raid_chunks;
|
create_info->raid_chunks=table->raid_chunks;
|
||||||
create_info->raid_chunksize=table->raid_chunksize;
|
create_info->raid_chunksize=table->raid_chunksize;
|
||||||
|
create_info->table_charset=table->table_charset;
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1094,7 +1095,7 @@ char *get_field(MEM_ROOT *mem, TABLE *table, uint fieldnr)
|
|||||||
{
|
{
|
||||||
Field *field=table->field[fieldnr];
|
Field *field=table->field[fieldnr];
|
||||||
char buff[MAX_FIELD_WIDTH];
|
char buff[MAX_FIELD_WIDTH];
|
||||||
String str(buff,sizeof(buff),table->table_charset);
|
String str(buff,sizeof(buff),default_charset_info);
|
||||||
field->val_str(&str,&str);
|
field->val_str(&str,&str);
|
||||||
uint length=str.length();
|
uint length=str.length();
|
||||||
if (!length)
|
if (!length)
|
||||||
|
@ -459,8 +459,7 @@ static bool pack_fields(File file,List<create_field> &create_fields)
|
|||||||
int2store(buff+8,field->unireg_check);
|
int2store(buff+8,field->unireg_check);
|
||||||
buff[10]= (uchar) field->interval_id;
|
buff[10]= (uchar) field->interval_id;
|
||||||
buff[11]= (uchar) field->sql_type;
|
buff[11]= (uchar) field->sql_type;
|
||||||
buff[12]= (uchar) (field->charset ? field->charset->number :
|
buff[12]= (uchar) field->charset->number;
|
||||||
default_charset_info->number);
|
|
||||||
int2store(buff+13, field->comment.length);
|
int2store(buff+13, field->comment.length);
|
||||||
comment_length+= field->comment.length;
|
comment_length+= field->comment.length;
|
||||||
set_if_bigger(int_count,field->interval_id);
|
set_if_bigger(int_count,field->interval_id);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user