Commit 66521277 authored by serg@serg.mysql.com's avatar serg@serg.mysql.com

Merge

parents 5f1599e4 71670dc9
...@@ -39,3 +39,5 @@ tonu@x3.internalnet ...@@ -39,3 +39,5 @@ tonu@x3.internalnet
jcole@sarvik.tfr.cafe.ee jcole@sarvik.tfr.cafe.ee
venu@work.mysql.com venu@work.mysql.com
bell@sanja.is.com.ua bell@sanja.is.com.ua
kaj@work.mysql.com
mwagner@cash.mwagner.org
%!PS-Adobe-3.0 EPSF-3.0
%%Creator: Adobe Photoshop Version 5.5
%%Title: slovenia.eps
%%CreationDate: Mon Jan 07 2002 15:19:42
%%BoundingBox: 0 0 32 22
%%HiResBoundingBox: 0 0 32 22
%%SuppressDotGainCompensation
%%EndComments
%%BeginProlog
%%EndProlog
%%BeginSetup
%%EndSetup
%ImageData: 32 22 8 3 1 32 2 "beginimage"
%BeginPhotoshop: 1300
% 3842494D03ED000000000010004800000001000200480000000100023842494D
% 040D000000000004000000783842494D03F30000000000080000000000000000
% 3842494D040A00000000000100003842494D271000000000000A000100000000
% 000000023842494D03F5000000000048002F66660001006C6666000600000000
% 0001002F6666000100A1999A0006000000000001003200000001005A00000006
% 000000000001003500000001002D000000060000000000013842494D03F80000
% 000000700000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03E80000
% 0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800000000FFFF
% FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800000000FFFFFFFFFFFF
% FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800003842494D0408000000000010
% 000000010000024000000240000000003842494D041400000000000400000001
% 3842494D040C0000000003960000000100000020000000160000006000000840
% 0000037A00180001FFD8FFE000104A46494600010201004800480000FFEE000E
% 41646F626500648000000001FFDB0084000C08080809080C09090C110B0A0B11
% 150F0C0C0F1518131315131318110C0C0C0C0C0C110C0C0C0C0C0C0C0C0C0C0C
% 0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C010D0B0B0D0E0D100E0E10140E0E0E
% 14140E0E0E0E14110C0C0C0C0C11110C0C0C0C0C0C110C0C0C0C0C0C0C0C0C0C
% 0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0CFFC0001108001600200301220002
% 1101031101FFDD00040002FFC4013F0000010501010101010100000000000000
% 030001020405060708090A0B0100010501010101010100000000000000010002
% 030405060708090A0B1000010401030204020507060805030C33010002110304
% 211231054151611322718132061491A1B14223241552C16233347282D1430725
% 9253F0E1F163733516A2B283264493546445C2A3743617D255E265F2B384C3D3
% 75E3F3462794A485B495C4D4E4F4A5B5C5D5E5F55666768696A6B6C6D6E6F637
% 475767778797A7B7C7D7E7F71100020201020404030405060707060535010002
% 1103213112044151617122130532819114A1B14223C152D1F0332462E1728292
% 435315637334F1250616A2B283072635C2D2449354A317644555367465E2F2B3
% 84C3D375E3F34694A485B495C4D4E4F4A5B5C5D5E5F55666768696A6B6C6D6E6
% F62737475767778797A7B7C7FFDA000C03010002110311003F0096759D1BA4FD
% 55E837E1F47E9B9D99978D48BFD4C6AED7EEF46B76FB366DB373AC77E91EF577
% EA93BA3F54CCCEC4EB1D0BA5E1D9850D8FB2D75CBB7D95BFF9EDFBB6FA6B84FA
% A3D5F2FA0751A73D949BA97B3D3BAB100BAB76D77B09FCF6ED6BD5AFAE5D7B27
% EB1F516DD5D0EAB171DA59435F1BCEE3BACB2CDBEDDCF77E6AD38F2FCA911C47
% 262F5478CF31EE438A12FDCF6B8BFC0641CBF32458C1908FF672FF00BD7D5FF6
% 0FD4AFFCAFE97FF6CE3FFE45677D64E89F546AFABBD52CC7C1E9CCBD98790EA9
% F5D5407878A9E58EADCC6EFDED77D0DABC6BECB91FE8CA85B8D7B6A7B8B0801A
% 493F2465C87282248E77192013578F5FFC711F77E646A706403FB93FFBD7FFD0
% E231AD78C7A80A5E406375059074F3B113D6B3FD03FEF67FE945CEA4B3A5567E
% 5DFF00ACF6587DCF6E1FCEFCB1FF0031D9E8BD6B3FD03FEF67FE9443C9B5E71E
% D06978058ED49640D3CAC5829251AB1F2EFF00D6566F73DB9FF3BF2CBFCC767F
% FFD93842494D03FD000000000006000000000000
%EndPhotoshop
%%BeginICCProfile: (Photoshop Profile) -1 Hex
% 00000C484C696E6F021000006D6E74725247422058595A2007CE000200090006
% 00310000616373704D5346540000000049454320735247420000000000000000
% 000000000000F6D6000100000000D32D48502020000000000000000000000000
% 0000000000000000000000000000000000000000000000000000000000000000
% 0000001163707274000001500000003364657363000001840000006C77747074
% 000001F000000014626B707400000204000000147258595A0000021800000014
% 6758595A0000022C000000146258595A0000024000000014646D6E6400000254
% 00000070646D6464000002C400000088767565640000034C0000008676696577
% 000003D4000000246C756D69000003F8000000146D6561730000040C00000024
% 74656368000004300000000C725452430000043C0000080C675452430000043C
% 0000080C625452430000043C0000080C7465787400000000436F707972696768
% 74202863292031393938204865776C6574742D5061636B61726420436F6D7061
% 6E790000646573630000000000000012735247422049454336313936362D322E
% 31000000000000000000000012735247422049454336313936362D322E310000
% 0000000000000000000000000000000000000000000000000000000000000000
% 0000000000000000000000000000000058595A20000000000000F35100010000
% 000116CC58595A200000000000000000000000000000000058595A2000000000
% 00006FA2000038F50000039058595A2000000000000062990000B785000018DA
% 58595A2000000000000024A000000F840000B6CF646573630000000000000016
% 49454320687474703A2F2F7777772E6965632E63680000000000000000000000
% 1649454320687474703A2F2F7777772E6965632E636800000000000000000000
% 0000000000000000000000000000000000000000000000000000000000000000
% 0000000064657363000000000000002E4945432036313936362D322E31204465
% 6661756C742052474220636F6C6F7572207370616365202D2073524742000000
% 00000000000000002E4945432036313936362D322E312044656661756C742052
% 474220636F6C6F7572207370616365202D207352474200000000000000000000
% 00000000000000000000000064657363000000000000002C5265666572656E63
% 652056696577696E6720436F6E646974696F6E20696E2049454336313936362D
% 322E3100000000000000000000002C5265666572656E63652056696577696E67
% 20436F6E646974696F6E20696E2049454336313936362D322E31000000000000
% 000000000000000000000000000000000000000076696577000000000013A4FE
% 00145F2E0010CF140003EDCC0004130B00035C9E0000000158595A2000000000
% 004C09560050000000571FE76D65617300000000000000010000000000000000
% 00000000000000000000028F0000000273696720000000004352542063757276
% 000000000000040000000005000A000F00140019001E00230028002D00320037
% 003B00400045004A004F00540059005E00630068006D00720077007C00810086
% 008B00900095009A009F00A400A900AE00B200B700BC00C100C600CB00D000D5
% 00DB00E000E500EB00F000F600FB01010107010D01130119011F0125012B0132
% 0138013E0145014C0152015901600167016E0175017C0183018B0192019A01A1
% 01A901B101B901C101C901D101D901E101E901F201FA0203020C0214021D0226
% 022F02380241024B0254025D02670271027A0284028E029802A202AC02B602C1
% 02CB02D502E002EB02F50300030B03160321032D03380343034F035A03660372
% 037E038A039603A203AE03BA03C703D303E003EC03F9040604130420042D043B
% 0448045504630471047E048C049A04A804B604C404D304E104F004FE050D051C
% 052B053A05490558056705770586059605A605B505C505D505E505F606060616
% 0627063706480659066A067B068C069D06AF06C006D106E306F507070719072B
% 073D074F076107740786079907AC07BF07D207E507F8080B081F08320846085A
% 086E0882089608AA08BE08D208E708FB09100925093A094F09640979098F09A4
% 09BA09CF09E509FB0A110A270A3D0A540A6A0A810A980AAE0AC50ADC0AF30B0B
% 0B220B390B510B690B800B980BB00BC80BE10BF90C120C2A0C430C5C0C750C8E
% 0CA70CC00CD90CF30D0D0D260D400D5A0D740D8E0DA90DC30DDE0DF80E130E2E
% 0E490E640E7F0E9B0EB60ED20EEE0F090F250F410F5E0F7A0F960FB30FCF0FEC
% 1009102610431061107E109B10B910D710F511131131114F116D118C11AA11C9
% 11E81207122612451264128412A312C312E31303132313431363138313A413C5
% 13E5140614271449146A148B14AD14CE14F01512153415561578159B15BD15E0
% 160316261649166C168F16B216D616FA171D17411765178917AE17D217F7181B
% 18401865188A18AF18D518FA19201945196B199119B719DD1A041A2A1A511A77
% 1A9E1AC51AEC1B141B3B1B631B8A1BB21BDA1C021C2A1C521C7B1CA31CCC1CF5
% 1D1E1D471D701D991DC31DEC1E161E401E6A1E941EBE1EE91F131F3E1F691F94
% 1FBF1FEA20152041206C209820C420F0211C2148217521A121CE21FB22272255
% 228222AF22DD230A23382366239423C223F0241F244D247C24AB24DA25092538
% 2568259725C725F726272657268726B726E827182749277A27AB27DC280D283F
% 287128A228D429062938296B299D29D02A022A352A682A9B2ACF2B022B362B69
% 2B9D2BD12C052C392C6E2CA22CD72D0C2D412D762DAB2DE12E162E4C2E822EB7
% 2EEE2F242F5A2F912FC72FFE3035306C30A430DB3112314A318231BA31F2322A
% 3263329B32D4330D3346337F33B833F1342B3465349E34D83513354D358735C2
% 35FD3637367236AE36E937243760379C37D738143850388C38C839053942397F
% 39BC39F93A363A743AB23AEF3B2D3B6B3BAA3BE83C273C653CA43CE33D223D61
% 3DA13DE03E203E603EA03EE03F213F613FA23FE24023406440A640E74129416A
% 41AC41EE4230427242B542F7433A437D43C044034447448A44CE45124555459A
% 45DE4622466746AB46F04735477B47C04805484B489148D7491D496349A949F0
% 4A374A7D4AC44B0C4B534B9A4BE24C2A4C724CBA4D024D4A4D934DDC4E254E6E
% 4EB74F004F494F934FDD5027507150BB51065150519B51E65231527C52C75313
% 535F53AA53F65442548F54DB5528557555C2560F565C56A956F75744579257E0
% 582F587D58CB591A596959B85A075A565AA65AF55B455B955BE55C355C865CD6
% 5D275D785DC95E1A5E6C5EBD5F0F5F615FB36005605760AA60FC614F61A261F5
% 6249629C62F06343639763EB6440649464E9653D659265E7663D669266E8673D
% 679367E9683F689668EC6943699A69F16A486A9F6AF76B4F6BA76BFF6C576CAF
% 6D086D606DB96E126E6B6EC46F1E6F786FD1702B708670E0713A719571F0724B
% 72A67301735D73B87414747074CC7528758575E1763E769B76F8775677B37811
% 786E78CC792A798979E77A467AA57B047B637BC27C217C817CE17D417DA17E01
% 7E627EC27F237F847FE5804780A8810A816B81CD8230829282F4835783BA841D
% 848084E3854785AB860E867286D7873B879F8804886988CE8933899989FE8A64
% 8ACA8B308B968BFC8C638CCA8D318D988DFF8E668ECE8F368F9E9006906E90D6
% 913F91A89211927A92E3934D93B69420948A94F4955F95C99634969F970A9775
% 97E0984C98B89924999099FC9A689AD59B429BAF9C1C9C899CF79D649DD29E40
% 9EAE9F1D9F8B9FFAA069A0D8A147A1B6A226A296A306A376A3E6A456A4C7A538
% A5A9A61AA68BA6FDA76EA7E0A852A8C4A937A9A9AA1CAA8FAB02AB75ABE9AC5C
% ACD0AD44ADB8AE2DAEA1AF16AF8BB000B075B0EAB160B1D6B24BB2C2B338B3AE
% B425B49CB513B58AB601B679B6F0B768B7E0B859B8D1B94AB9C2BA3BBAB5BB2E
% BBA7BC21BC9BBD15BD8FBE0ABE84BEFFBF7ABFF5C070C0ECC167C1E3C25FC2DB
% C358C3D4C451C4CEC54BC5C8C646C6C3C741C7BFC83DC8BCC93AC9B9CA38CAB7
% CB36CBB6CC35CCB5CD35CDB5CE36CEB6CF37CFB8D039D0BAD13CD1BED23FD2C1
% D344D3C6D449D4CBD54ED5D1D655D6D8D75CD7E0D864D8E8D96CD9F1DA76DAFB
% DB80DC05DC8ADD10DD96DE1CDEA2DF29DFAFE036E0BDE144E1CCE253E2DBE363
% E3EBE473E4FCE584E60DE696E71FE7A9E832E8BCE946E9D0EA5BEAE5EB70EBFB
% EC86ED11ED9CEE28EEB4EF40EFCCF058F0E5F172F1FFF28CF319F3A7F434F4C2
% F550F5DEF66DF6FBF78AF819F8A8F938F9C7FA57FAE7FB77FC07FC98FD29FDBA
% FE4BFEDCFF6DFFFF
%%EndICCProfile
gsave % EPS gsave
/hascolor
/deviceinfo where
{pop deviceinfo /Colors known
{deviceinfo /Colors get exec 1 gt}
{false} ifelse}
{/statusdict where
{pop statusdict /processcolors known
{statusdict /processcolors get exec 1 gt}
{false} ifelse}
{false} ifelse}
ifelse
def
40 dict begin
/_image systemdict /image get def
/_setgray systemdict /setgray get def
/_currentgray systemdict /currentgray get def
/_settransfer systemdict /settransfer get def
/_currenttransfer systemdict /currenttransfer get def
/blank 0 _currenttransfer exec
1 _currenttransfer exec eq def
/negative blank
{0 _currenttransfer exec 0.5 lt}
{0 _currenttransfer exec 1 _currenttransfer exec gt}
ifelse def
/inverted? negative def
/level2 systemdict /languagelevel known
{languagelevel 2 ge} {false} ifelse def
/level3 systemdict /languagelevel known
{languagelevel 3 ge} {false} ifelse def
/foureq {4 index eq 8 1 roll
4 index eq 8 1 roll
4 index eq 8 1 roll
4 index eq 8 1 roll
pop pop pop pop and and and} def
hascolor {/band 0 def} {/band 5 def} ifelse
/setcmykcolor where {pop
1 0 0 0 setcmykcolor _currentgray 1 exch sub
0 1 0 0 setcmykcolor _currentgray 1 exch sub
0 0 1 0 setcmykcolor _currentgray 1 exch sub
0 0 0 1 setcmykcolor _currentgray 1 exch sub
4 {4 copy} repeat
1 0 0 0 foureq {/band 1 store} if
0 1 0 0 foureq {/band 2 store} if
0 0 1 0 foureq {/band 3 store} if
0 0 0 1 foureq {/band 4 store} if
0 0 0 0 foureq {/band 6 store} if} if
blank {/band 6 store} if
gsave % Image Header gsave
/rows 22 def
/cols 32 def
32 22 scale
level2 {
band 0 eq {
/DeviceRGB
} {/DeviceGray} ifelse
setcolorspace currentdict /PhotoshopDuotoneColorSpace undef currentdict /PhotoshopDuotoneAltColorSpace undef } if
/picstr1 32 string def
/picstr2 32 string def
/picstr3 32 string def
/picstr4 32 string def
/readdata {currentfile exch readhexstring pop} def
/image2 level2 {/image load def} {{begin
Width Height BitsPerComponent ImageMatrix
Decode length 2 eq
{/DataSource load image} if
Decode length 6 eq
{DataSource 0 get DataSource 1 get DataSource 2 get
true 3 colorimage} if
Decode length 8 eq
{DataSource 0 get DataSource 1 get
DataSource 2 get DataSource 3 get
true 4 colorimage} if
end} def} ifelse
/_image2 level2 {/_image load def} {{begin
Width Height BitsPerComponent ImageMatrix
/DataSource load _image end} def} ifelse
/beginimage {
band 0 eq band 4 eq or band 5 eq or
{image2}
{negative {{pop 0}} {{pop 1}} ifelse
_settransfer _image2} ifelse
} def
12 dict begin
/ImageType 1 def
/Width cols def
/Height rows def
/ImageMatrix [cols 0 0 rows neg 0 rows] def
/BitsPerComponent 8 def
band 0 eq
{/Decode [0 1 0 1 0 1] def
/MultipleDataSources true def
/DataSource [
{picstr1 readdata}
{picstr2 readdata}
{picstr3 readdata picstr4 readdata pop}
] def}
{/Decode [0 1] def
/DataSource {
picstr1 readdata pop
picstr2 readdata pop
picstr3 readdata pop
picstr4 readdata
} def}
ifelse
currentdict end
%%BeginBinary: 5821
beginimage
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00F7F7F7F8FAF9F9F9F9F9F9F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F700
00F7F7F7F9FBFBFBFBFBFBFBF8F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F700
00F7F7F7F8F9F9F9F9F9F9F9F8F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F700
00F7F7F7F9FAFAFAFAFAFAFAF8F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F700
00F7F7F7F7F2F2F6F6F6F1F4F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F700
00F7F7F7F2E9E8ECECECE7EAF4F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F700
00F7F7F7F1EEEEEBEBEBEFEDF3F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F700
00F7F7F7F3ECECEFEFEFEBEDF5F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F700
00F7F7FDAB5B5D3F3C426657D5FCF7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F700
00F7F7FE8134381A151C422BB5FEF7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F700
00F7F7FDB8808CA3A4A0848ECCFDF7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F700
00F7F7FE94484C3430365443C1FDF7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F700
00F7F7FF8D33320833004623C8FEF7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F700
00F7F7FF6B2C310831004617A9FFF7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F700
00F7F7FDBE7F92B18FB98099CBFDF7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F700
00F7F7FF7E373C1B3C144C29B6FEF7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F700
00F7F7FF990000194E06000CCEFEF7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F700
00F7F7FF7700001148000000AFFFF7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F700
00F7F7FDB9ADBBA883B5BBAEC9FDF7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F700
00F7F7FF8813152450161517BBFEF7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F700
00FFFFFF9E0000248205000BD7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
00FFFFFF7C00001D7E000000B8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
00FAFAFFBBA8B2BFDEB5B3ABCCFFFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA00
00FEFEFF8D1214318A151416C3FFFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE00
00A4A4A968443E72FC37562B8EA8A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A400
00A1A1A7493B3A6DFC30521B71A7A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A100
00E0E0E5ABBCC5D2F9C2CCB5B7E5E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E000
00A9A9AE5D4C4A7AFC42613181AEA9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A900
0002020034D6E1E1FFD2EEA71900020202020202020202020202020202020200
0000000010D6E4DDFECEF59E0000000000000000000000000000000000000000
00B3B3B69AE8F3F0FAECF9D39BB6B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B300
001414142AD8E5E0FED2F3A71914141414141414141414141414141414141400
000707012BBFC8E8EEDEC4A70D04070707070707070707070707070707070700
000000000FCEF4F6F4F5F69A0000000000000000000000000000000000000000
00B5B5B6A3DCFCF8F6F8FEBEA9B6B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B500
0016161428CBE8F2F2EEE8A21615161616161616161616161616161616161600
000808070479D4B6B7B3CE460008080808080808080808080808080808080800
00000000005DF5E7E4EADE270000000000000000000000000000000000000000
00B5B5B5B0ACF5F7F4FAE4A2B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B500
00161616156EEBDAD8DBDA3E1416161616161616161616161616161616161600
000808080315B9EDD4F187030708080808080808080808080808080808080800
0000000000028DFDF6F257000000000000000000000000000000000000000000
00B5B5B5B7A6B6F8FEEEA6AFB6B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B5B500
00161616151A9FF8EDF16E141616161616161616161616161616161616161600
00070707070015AFF37F02040707070707070707070707070707070707070700
0000000000000184D55100000000000000000000000000000000000000000000
00B6B6B6B6B8A5B5D7A5ADB8B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B6B600
0016161616141996DE6814151616161616161616161616161616161616161600
0003030303030007270000030303030303030303030303030303030303030300
0000000000000000080000000000000000000000000000000000000000000000
00BABABABABABCB0A1B6BCBABABABABABABABABABABABABABABABABABABABA00
0015151515151515221415151515151515151515151515151515151515151500
00828282828282807B8182828282828282828282828282828282828282828200
0000000000000000000000000000000000000000000000000000000000000000
0041414141414142434140414141414141414141414141414141414141414100
002E2E2E2E2E2E2E2C2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E00
00D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0D000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
003E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E00
00C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C600
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
003B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B00
00C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C600
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
003B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B00
00C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C600
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
003B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B00
00C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C600
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
003B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B00
00C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C600
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
003B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B00
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
%%EndBinary
grestore end % Image Trailer grestore
grestore % EPS grestore
...@@ -5393,6 +5393,10 @@ You will need the following: ...@@ -5393,6 +5393,10 @@ You will need the following:
A Windows 32 bits Operational System of the family Win9x, ME, A Windows 32 bits Operational System of the family Win9x, ME,
NT and Win 2000. The NT family permits running the MySQL server NT and Win 2000. The NT family permits running the MySQL server
as a service. @xref{NT start}. as a service. @xref{NT start}.
If you want to use tables bigger than 4G, you should install MySQL
on NTFS or newer file system. Don't forget to use @code{MAX_ROWS} and
@code{AVG_ROW_LENGTH} when you create the table. @xref{CREATE TABLE}.
@item @item
TCP/IP protocol support. TCP/IP protocol support.
@item @item
...@@ -32227,6 +32231,25 @@ returns immediately. The return value is the number of log events it had to ...@@ -32227,6 +32231,25 @@ returns immediately. The return value is the number of log events it had to
wait to get to the specified position, or NULL in case of error. Useful for wait to get to the specified position, or NULL in case of error. Useful for
control of master-slave synchronisation, but was originally written to control of master-slave synchronisation, but was originally written to
facilitate replication testing. facilitate replication testing.
@findex FOUND_ROWS()
@findex LIMIT
@item FOUND_ROWS()
Returns the number of rows that the last @code{SELECT CALC_FOUND_ROWS ...}
command would have returned, if wasn't restricted with @code{LIMIT}.
@example
SELECT CALC_FOUND_ROWS * FROM table_name WHERE id > 100 LIMIT 10;
SELECT FOUND_ROWS();
@end example
The second select will return how many rows the SELECT should have
returned if we would remove the @code{LIMIT} clause.
Note that if you are using @code{SELECT CALC_FOUND_ROWS ...} MySQL has
to calculate all rows in the result set. This is however faster than
if you would not use @code{LIMIT} as the result set doesn't have to be sent
to the client.
@end table @end table
...@@ -32413,7 +32436,7 @@ mysql> SELECT id,FLOOR(value/100) FROM tbl_name ORDER BY RAND(); ...@@ -32413,7 +32436,7 @@ mysql> SELECT id,FLOOR(value/100) FROM tbl_name ORDER BY RAND();
@c help SELECT @c help SELECT
@example @example
SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[SQL_CACHE | SQL_NO_CACHE] [HIGH_PRIORITY] [SQL_CACHE | SQL_NO_CACHE] [CALC_FOUND_ROWS] [HIGH_PRIORITY]
[DISTINCT | DISTINCTROW | ALL] [DISTINCT | DISTINCTROW | ALL]
select_expression,... select_expression,...
[INTO @{OUTFILE | DUMPFILE@} 'file_name' export_options] [INTO @{OUTFILE | DUMPFILE@} 'file_name' export_options]
...@@ -32570,6 +32593,12 @@ result set will be small. In this case, MySQL will use fast ...@@ -32570,6 +32593,12 @@ result set will be small. In this case, MySQL will use fast
temporary tables to store the resulting table instead of using sorting. In temporary tables to store the resulting table instead of using sorting. In
MySQL Version 3.23 this shouldn't normally be needed. MySQL Version 3.23 this shouldn't normally be needed.
@item
@code{CALC_FOUND_ROWS} tells MySQL to calculate how many rows there
would be in the result, disregarding any @code{LIMIT} clause. The number
of rows can be obtained with @code{SELECT
FOUND_ROWS()}. @xref{Miscellaneous functions}.
@item @item
@code{SQL_CACHE} tells MySQL to store the query result in the query cache @code{SQL_CACHE} tells MySQL to store the query result in the query cache
if you are using @code{SQL_QUERY_CACHE_TYPE=2} (@code{DEMAND}). if you are using @code{SQL_QUERY_CACHE_TYPE=2} (@code{DEMAND}).
...@@ -34502,12 +34531,14 @@ original tables, MySQL will not allow concurrent inserts during ...@@ -34502,12 +34531,14 @@ original tables, MySQL will not allow concurrent inserts during
@item @item
The @code{RAID_TYPE} option will help you to break the 2G/4G limit for The @code{RAID_TYPE} option will help you to break the 2G/4G limit for
the MyISAM data file (not the index file) on operating systems that the MyISAM data file (not the index file) on operating systems that
don't support big files. don't support big files. Note that this option is not recommended for
You can get more speed from the I/O bottleneck by putting file system that supports big files!
@code{RAID} directories on different physical disks. @code{RAID_TYPE}
will work on any OS, as long as you have configured MySQL with You can get more speed from the I/O bottleneck by putting @code{RAID}
@code{--with-raid}. For now the only allowed @code{RAID_TYPE} is directories on different physical disks. @code{RAID_TYPE} will work on
@code{STRIPED} (@code{1} and @code{RAID0} are aliases for this). any OS, as long as you have configured MySQL with @code{--with-raid}.
For now the only allowed @code{RAID_TYPE} is @code{STRIPED} (@code{1}
and @code{RAID0} are aliases for this).
If you specify @code{RAID_TYPE=STRIPED} for a @code{MyISAM} table, If you specify @code{RAID_TYPE=STRIPED} for a @code{MyISAM} table,
@code{MyISAM} will create @code{RAID_CHUNKS} subdirectories named 00, @code{MyISAM} will create @code{RAID_CHUNKS} subdirectories named 00,
...@@ -43283,7 +43314,8 @@ No UDF functions. ...@@ -43283,7 +43314,8 @@ No UDF functions.
@item @item
No stack trace on core dump. No stack trace on core dump.
@item @item
No internal RAID support. No internal RAID support. (This is not normally needed as most OS has
nowadays support for big files).
@item @item
You can set this up as a server or a master (no replication). You can set this up as a server or a master (no replication).
@item @item
...@@ -48007,7 +48039,12 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}. ...@@ -48007,7 +48039,12 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}.
@item @item
ODBC compatibility: added @code{BIT_LENGTH()} function. ODBC compatibility: added @code{BIT_LENGTH()} function.
@item @item
Added @code{CAST()} and @code{CONVERT()} functions. Fixed bug in @code{FLUSH QUERY CACHE}.
@item
Added @code{CAST()} and @code{CONVERT()} functions. The @code{CAST} and
@code{CONVERT} functions are nearly identical and mainly useful when you
want to create a column with a specific type in a @code{CREATE ... SELECT}.
For more information, read @ref{Cast Functions}.
@item @item
Changed order of how keys are created in tables. Changed order of how keys are created in tables.
@item @item
...@@ -48032,7 +48069,7 @@ Fixed shutdown problem on HPUX. ...@@ -48032,7 +48069,7 @@ Fixed shutdown problem on HPUX.
@item @item
Added functions @code{des_encrypt()} and @code{des_decrypt()}. Added functions @code{des_encrypt()} and @code{des_decrypt()}.
@item @item
Added statement FLUSH DES_KEY_FILE. Added statement @code{FLUSH DES_KEY_FILE}.
@item @item
Added mysqld option @code{--des-key-file}. Added mysqld option @code{--des-key-file}.
@item @item
...@@ -48085,7 +48122,7 @@ Added boolean fulltext search code. It should be considered early alpha. ...@@ -48085,7 +48122,7 @@ Added boolean fulltext search code. It should be considered early alpha.
Extended @code{MODIFY} and @code{CHANGE} in @code{ALTER TABLE} to accept Extended @code{MODIFY} and @code{CHANGE} in @code{ALTER TABLE} to accept
the @code{AFTER} keyword. the @code{AFTER} keyword.
@item @item
Index are now used with @code{ORDER} BY on a whole InnoDB table. Index are now used with @code{ORDER BY} on a whole @code{InnoDB} table.
@end itemize @end itemize
@node News-4.0.0, , News-4.0.1, News-4.0.x @node News-4.0.0, , News-4.0.1, News-4.0.x
...@@ -48100,7 +48137,7 @@ Added documentation for @code{libmysqld}, the embedded MySQL server ...@@ -48100,7 +48137,7 @@ Added documentation for @code{libmysqld}, the embedded MySQL server
library. Also added example programs (a @code{mysql} client and library. Also added example programs (a @code{mysql} client and
@code{mysqltest} test program) which use @code{libmysqld}. @code{mysqltest} test program) which use @code{libmysqld}.
@item @item
Removed all Gemini hooks from MySQL. Removed all Gemini hooks from MySQL server.
@item @item
Removed @code{my_thread_init()} and @code{my_thread_end()} Removed @code{my_thread_init()} and @code{my_thread_end()}
from mysql_com.h, and added @code{mysql_thread_init()} and from mysql_com.h, and added @code{mysql_thread_init()} and
...@@ -170,6 +170,11 @@ FTP (@uref{ftp://ftp.dn.ru/pub/MySQL/}) ...@@ -170,6 +170,11 @@ FTP (@uref{ftp://ftp.dn.ru/pub/MySQL/})
@image{Flags/russia} Russia [Scientific Center/Chernogolovka] @@ @image{Flags/russia} Russia [Scientific Center/Chernogolovka] @@
FTP (@uref{ftp://ftp.chg.ru/pub/databases/mysql/}) FTP (@uref{ftp://ftp.chg.ru/pub/databases/mysql/})
@item
@image{Flags/slovenia} Slovenia [ARNES] @@
WWW (@uref{http://ftp.arnes.si/mysql/})
FTP (@uref{ftp://ftp.arnes.si/packages/mysql/})
@item @item
@image{Flags/spain} Spain [GMC Control Systems] @@ @image{Flags/spain} Spain [GMC Control Systems] @@
WWW (@uref{http://mysql.neptuno2000.com/}) WWW (@uref{http://mysql.neptuno2000.com/})
...@@ -317,6 +322,7 @@ FTP (@uref{ftp://ftp.shellhung.org/pub/Mirror/mysql/}) ...@@ -317,6 +322,7 @@ FTP (@uref{ftp://ftp.shellhung.org/pub/Mirror/mysql/})
@item @item
@image{Flags/indonesia} Indonesia [incaf.net] @@ @image{Flags/indonesia} Indonesia [incaf.net] @@
WWW (@uref{http://mysql.incaf.net/}) WWW (@uref{http://mysql.incaf.net/})
FTP (@uref{ftp://mysql.incaf.net/})
@item @item
@image{Flags/indonesia} Indonesia [web.id] @@ @image{Flags/indonesia} Indonesia [web.id] @@
...@@ -341,7 +347,7 @@ WWW (@uref{http://mysql.hjc.edu.sg/}) ...@@ -341,7 +347,7 @@ WWW (@uref{http://mysql.hjc.edu.sg/})
FTP (@uref{ftp://ftp.hjc.edu.sg/mysql/}) FTP (@uref{ftp://ftp.hjc.edu.sg/mysql/})
@item @item
@image{Flags/south-korea} South Korea [PanworldNet] @@ @image{Flags/south-korea} South Korea [HolyNet] @@
WWW (@uref{http://mysql.holywar.net/}) WWW (@uref{http://mysql.holywar.net/})
@item @item
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
** and adapted to mysqldump 05/11/01 by Jani Tolonen ** and adapted to mysqldump 05/11/01 by Jani Tolonen
*/ */
#define DUMP_VERSION "8.20" #define DUMP_VERSION "8.21"
#include <my_global.h> #include <my_global.h>
#include <my_sys.h> #include <my_sys.h>
...@@ -309,7 +309,7 @@ static int get_options(int *argc,char ***argv) ...@@ -309,7 +309,7 @@ static int get_options(int *argc,char ***argv)
load_defaults("my",load_default_groups,argc,argv); load_defaults("my",load_default_groups,argc,argv);
set_all_changeable_vars(md_changeable_vars); set_all_changeable_vars(md_changeable_vars);
while ((c=getopt_long(*argc,*argv, while ((c=getopt_long(*argc,*argv,
"#::p::h:u:O:P:r:S:T:EBaAcCdefFKlnqtvVw:?IxX", "#::p::h:u:O:P:r:S:T:EBaAcCdefFKlnqQtvVw:?IxX",
long_options, &option_index)) != EOF) long_options, &option_index)) != EOF)
{ {
switch(c) { switch(c) {
......
...@@ -56,7 +56,19 @@ enum ha_rkey_function { ...@@ -56,7 +56,19 @@ enum ha_rkey_function {
HA_READ_AFTER_KEY, /* Find next rec. after key-record */ HA_READ_AFTER_KEY, /* Find next rec. after key-record */
HA_READ_BEFORE_KEY, /* Find next rec. before key-record */ HA_READ_BEFORE_KEY, /* Find next rec. before key-record */
HA_READ_PREFIX, /* Key which as same prefix */ HA_READ_PREFIX, /* Key which as same prefix */
HA_READ_PREFIX_LAST /* Last key with the same prefix */ HA_READ_PREFIX_LAST, /* Last key with the same prefix */
HA_READ_MBR_CONTAIN,
HA_READ_MBR_INTERSECT,
HA_READ_MBR_WITHIN,
HA_READ_MBR_DISJOINT,
HA_READ_MBR_EQUAL
};
/* Key algorithm types */
enum ha_key_alg {
HA_KEY_ALG_BTREE=0, /* B-tree, default one */
HA_KEY_ALG_RTREE=1 /* R-tree, for spatial searches */
}; };
/* The following is parameter to ha_extra() */ /* The following is parameter to ha_extra() */
...@@ -136,6 +148,8 @@ enum ha_base_keytype { ...@@ -136,6 +148,8 @@ enum ha_base_keytype {
#define HA_BINARY_PACK_KEY 32 /* Packing of all keys to prev key */ #define HA_BINARY_PACK_KEY 32 /* Packing of all keys to prev key */
#define HA_FULLTEXT 128 /* SerG: for full-text search */ #define HA_FULLTEXT 128 /* SerG: for full-text search */
#define HA_UNIQUE_CHECK 256 /* Check the key for uniqueness */ #define HA_UNIQUE_CHECK 256 /* Check the key for uniqueness */
#define HA_SPATIAL 1024 /* Alex Barkov: for spatial search */
/* Automatic bits in key-flag */ /* Automatic bits in key-flag */
...@@ -239,6 +253,12 @@ enum ha_base_keytype { ...@@ -239,6 +253,12 @@ enum ha_base_keytype {
#define SEARCH_UPDATE 64 #define SEARCH_UPDATE 64
#define SEARCH_PREFIX 128 #define SEARCH_PREFIX 128
#define SEARCH_LAST 256 #define SEARCH_LAST 256
#define MBR_CONTAIN 512
#define MBR_INTERSECT 1024
#define MBR_WITHIN 2048
#define MBR_DISJOINT 4096
#define MBR_EQUAL 8192
#define MBR_DATA 16384
/* bits in opt_flag */ /* bits in opt_flag */
#define QUICK_USED 1 #define QUICK_USED 1
......
...@@ -126,6 +126,7 @@ typedef struct st_mi_keydef /* Key definition with open & info */ ...@@ -126,6 +126,7 @@ typedef struct st_mi_keydef /* Key definition with open & info */
uint16 keysegs; /* Number of key-segment */ uint16 keysegs; /* Number of key-segment */
uint16 flag; /* NOSAME, PACK_USED */ uint16 flag; /* NOSAME, PACK_USED */
uint8 key_alg; /* BTREE, RTREE */
uint16 block_length; /* Length of keyblock (auto) */ uint16 block_length; /* Length of keyblock (auto) */
uint16 underflow_block_length; /* When to execute underflow */ uint16 underflow_block_length; /* When to execute underflow */
uint16 keylength; /* Tot length of keyparts (auto) */ uint16 keylength; /* Tot length of keyparts (auto) */
......
...@@ -150,7 +150,8 @@ enum enum_field_types { FIELD_TYPE_DECIMAL, FIELD_TYPE_TINY, ...@@ -150,7 +150,8 @@ enum enum_field_types { FIELD_TYPE_DECIMAL, FIELD_TYPE_TINY,
FIELD_TYPE_LONG_BLOB=251, FIELD_TYPE_LONG_BLOB=251,
FIELD_TYPE_BLOB=252, FIELD_TYPE_BLOB=252,
FIELD_TYPE_VAR_STRING=253, FIELD_TYPE_VAR_STRING=253,
FIELD_TYPE_STRING=254 FIELD_TYPE_STRING=254,
FIELD_TYPE_GEOMETRY=255
}; };
#define FIELD_TYPE_CHAR FIELD_TYPE_TINY /* For compability */ #define FIELD_TYPE_CHAR FIELD_TYPE_TINY /* For compability */
......
...@@ -2,33 +2,95 @@ LIBRARY LIBMYSQL ...@@ -2,33 +2,95 @@ LIBRARY LIBMYSQL
DESCRIPTION 'MySQL 4.0 Client Library' DESCRIPTION 'MySQL 4.0 Client Library'
VERSION 4.0 VERSION 4.0
EXPORTS EXPORTS
mysql_affected_rows
mysql_num_rows mysql_close
mysql_num_fields mysql_connect
mysql_create_db
mysql_data_seek
mysql_debug
mysql_drop_db
mysql_dump_debug_info
mysql_eof mysql_eof
mysql_errno
mysql_error
mysql_escape_string
mysql_fetch_field
mysql_fetch_field_direct mysql_fetch_field_direct
mysql_fetch_fields mysql_fetch_fields
mysql_row_tell mysql_fetch_lengths
mysql_field_tell mysql_fetch_row
mysql_field_count mysql_field_count
mysql_affected_rows mysql_field_seek
mysql_insert_id mysql_field_tell
mysql_errno mysql_free_result
mysql_error mysql_get_client_info
mysql_get_host_info
mysql_get_proto_info
mysql_get_server_info
mysql_info mysql_info
mysql_thread_id
mysql_character_set_name
mysql_init mysql_init
mysql_ssl_set mysql_insert_id
mysql_ssl_clear mysql_kill
mysql_change_user mysql_list_dbs
mysql_list_fields
mysql_list_processes
mysql_list_tables
mysql_num_fields
mysql_num_rows
mysql_odbc_escape_string
mysql_options
mysql_ping
mysql_query
mysql_real_connect mysql_real_connect
mysql_close mysql_real_query
mysql_refresh
mysql_row_seek
mysql_row_tell
mysql_select_db mysql_select_db
mysql_query mysql_shutdown
mysql_stat
mysql_store_result
mysql_thread_id
mysql_use_result
bmove_upp
delete_dynamic
_dig_vec
init_dynamic_array
insert_dynamic
int2str
is_prefix
list_add
list_delete
max_allowed_packet
my_casecmp
my_init
my_end
my_strdup
my_malloc
my_memdup
my_no_flags_free
my_realloc
my_thread_end
my_thread_init
net_buffer_length
set_dynamic
strcend
strdup_root
strfill
strinstr
strmake
strmov
strxmov
myodbc_remove_escape
mysql_thread_safe
mysql_character_set_name
mysql_change_user
mysql_send_query mysql_send_query
mysql_read_query_result mysql_read_query_result
mysql_real_query mysql_real_escape_string
mysql_ssl_set
mysql_ssl_clear
mysql_real_connect
mysql_master_query mysql_master_query
mysql_master_send_query mysql_master_send_query
mysql_slave_query mysql_slave_query
...@@ -43,34 +105,18 @@ EXPORTS ...@@ -43,34 +105,18 @@ EXPORTS
mysql_rpl_probe mysql_rpl_probe
mysql_set_master mysql_set_master
mysql_add_slave mysql_add_slave
mysql_shutdown
mysql_dump_debug_info
mysql_refresh
mysql_kill
mysql_ping
mysql_stat
mysql_get_server_info
mysql_get_client_info
mysql_get_host_info
mysql_get_proto_info
mysql_list_dbs
mysql_list_tables
mysql_list_fields
mysql_list_processes
mysql_store_result
mysql_use_result
mysql_options
mysql_free_result
mysql_data_seek
mysql_row_seek
mysql_field_seek
mysql_fetch_row
mysql_fetch_lengths
mysql_fetch_field
mysql_escape_string
mysql_real_escape_string
mysql_debug
mysql_odbc_escape_string
myodbc_remove_escape
mysql_thread_safe
...@@ -36,4 +36,9 @@ mysql_load(THD * thd, sql_exchange * ex, TABLE_LIST * table_list, ...@@ -36,4 +36,9 @@ mysql_load(THD * thd, sql_exchange * ex, TABLE_LIST * table_list,
#define mysql_load mysql_load_internal #define mysql_load mysql_load_internal
#if defined (__WIN__)
#include "../sql/sql_load.cpp"
#else
#include "../sql/sql_load.cc" #include "../sql/sql_load.cc"
#endif
...@@ -24,8 +24,10 @@ ...@@ -24,8 +24,10 @@
#define main main1 #define main main1
#define mysql_unix_port mysql_inix_port1 #define mysql_unix_port mysql_inix_port1
#define mysql_port mysql_port1 #define mysql_port mysql_port1
#if !defined(__WIN__)
#define net_read_timeout net_read_timeout1 #define net_read_timeout net_read_timeout1
#define net_write_timeout net_write_timeout1 #define net_write_timeout net_write_timeout1
#endif
#define changeable_vars changeable_vars1 #define changeable_vars changeable_vars1
extern "C" extern "C"
...@@ -45,7 +47,11 @@ static bool check_user(THD *thd, enum_server_command command, ...@@ -45,7 +47,11 @@ static bool check_user(THD *thd, enum_server_command command,
void free_defaults_internal(char ** argv) {if (argv) free_defaults(argv);} void free_defaults_internal(char ** argv) {if (argv) free_defaults(argv);}
#define free_defaults free_defaults_internal #define free_defaults free_defaults_internal
#if defined (__WIN__)
#include "../sql/mysqld.cpp"
#else
#include "../sql/mysqld.cc" #include "../sql/mysqld.cc"
#endif
#define SCRAMBLE_LENGTH 8 #define SCRAMBLE_LENGTH 8
C_MODE_START C_MODE_START
......
LIBRARY LIBMYSQLD
DESCRIPTION 'MySQL 4.0 Embedded Server Library'
VERSION 4.0
EXPORTS
mysql_server_end
mysql_server_init
mysql_use_result
mysql_thread_safe
mysql_thread_id
mysql_store_result
mysql_stat
mysql_shutdown
mysql_select_db
mysql_row_tell
mysql_row_seek
mysql_real_query
mysql_real_connect
mysql_query
mysql_ping
mysql_options
mysql_num_rows
mysql_num_fields
mysql_list_tables
mysql_list_processes
mysql_list_fields
mysql_list_dbs
mysql_kill
mysql_insert_id
mysql_init
mysql_info
mysql_get_server_info
mysql_get_proto_info
mysql_get_host_info
mysql_get_client_info
mysql_free_result
mysql_field_tell
mysql_field_count
mysql_field_seek
mysql_fetch_row
mysql_fetch_lengths
mysql_fetch_fields
mysql_fetch_field_direct
mysql_fetch_field
mysql_escape_string
mysql_real_escape_string
mysql_error
mysql_errno
mysql_eof
mysql_dump_debug_info
mysql_drop_db
mysql_debug
mysql_data_seek
mysql_create_db
mysql_character_set_name
mysql_change_user
mysql_connect
mysql_close
mysql_affected_rows
mysql_thread_init
mysql_thread_end
mysql_send_query
mysql_read_query_result
mysql_refresh
mysql_odbc_escape_string
myodbc_remove_escape
...@@ -33,7 +33,7 @@ static uint lengths[256]; ...@@ -33,7 +33,7 @@ static uint lengths[256];
int main(int argc,char *argv[]) int main(int argc,char *argv[])
{ {
int error=0; int error=0;
uint keylen, keylen2, inx, doc_cnt=0; uint keylen, keylen2=0, inx, doc_cnt=0;
float weight; float weight;
double gws, min_gws=0, avg_gws=0; double gws, min_gws=0, avg_gws=0;
MI_INFO *info; MI_INFO *info;
...@@ -151,7 +151,7 @@ int main(int argc,char *argv[]) ...@@ -151,7 +151,7 @@ int main(int argc,char *argv[])
for (inx=0;inx<256;inx++) for (inx=0;inx<256;inx++)
{ {
count+=lengths[inx]; count+=lengths[inx];
if (count >= total/2) if ((ulong) count >= total/2)
break; break;
} }
printf("Total rows: %qu\nTotal words: %lu\n" printf("Total rows: %qu\nTotal words: %lu\n"
...@@ -170,7 +170,8 @@ int main(int argc,char *argv[]) ...@@ -170,7 +170,8 @@ int main(int argc,char *argv[])
count+=lengths[inx]; count+=lengths[inx];
if (count && lengths[inx]) if (count && lengths[inx])
printf("%3u: %10lu %5.2f%% %20lu %4.1f%%\n", inx, printf("%3u: %10lu %5.2f%% %20lu %4.1f%%\n", inx,
lengths[inx],100.0*lengths[inx]/total,count, 100.0*count/total); (ulong) lengths[inx],100.0*lengths[inx]/total,(ulong) count,
100.0*count/total);
} }
} }
} }
......
...@@ -179,8 +179,6 @@ create table t2 (a text not null); ...@@ -179,8 +179,6 @@ create table t2 (a text not null);
create table t21 (a text not null); create table t21 (a text not null);
create table t3 (a text not null); create table t3 (a text not null);
insert into t1 values("1111111111111111111111111111111111111111111111111111"); insert into t1 values("1111111111111111111111111111111111111111111111111111");
insert into t11 select * from t1;
insert into t21 select * from t1;
insert into t2 select * from t1; insert into t2 select * from t1;
insert into t1 select * from t2; insert into t1 select * from t2;
insert into t2 select * from t1; insert into t2 select * from t1;
...@@ -196,6 +194,8 @@ insert into t1 select * from t2; ...@@ -196,6 +194,8 @@ insert into t1 select * from t2;
insert into t2 select * from t1; insert into t2 select * from t1;
insert into t1 select * from t2; insert into t1 select * from t2;
insert into t2 select * from t1; insert into t2 select * from t1;
insert into t11 select * from t1;
insert into t21 select * from t1;
insert into t1 select * from t2; insert into t1 select * from t2;
insert into t2 select * from t1; insert into t2 select * from t1;
insert into t1 select * from t2; insert into t1 select * from t2;
......
...@@ -93,8 +93,6 @@ create table t2 (a text not null); ...@@ -93,8 +93,6 @@ create table t2 (a text not null);
create table t21 (a text not null); create table t21 (a text not null);
create table t3 (a text not null); create table t3 (a text not null);
insert into t1 values("1111111111111111111111111111111111111111111111111111"); insert into t1 values("1111111111111111111111111111111111111111111111111111");
insert into t11 select * from t1;
insert into t21 select * from t1;
insert into t2 select * from t1; insert into t2 select * from t1;
insert into t1 select * from t2; insert into t1 select * from t2;
insert into t2 select * from t1; insert into t2 select * from t1;
...@@ -110,6 +108,9 @@ insert into t1 select * from t2; ...@@ -110,6 +108,9 @@ insert into t1 select * from t2;
insert into t2 select * from t1; insert into t2 select * from t1;
insert into t1 select * from t2; insert into t1 select * from t2;
insert into t2 select * from t1; insert into t2 select * from t1;
# t11 and t21 must be over 4Kb (QUERY_CACHE_MIN_RESULT_DATA_SIZE)
insert into t11 select * from t1;
insert into t21 select * from t1;
insert into t1 select * from t2; insert into t1 select * from t2;
insert into t2 select * from t1; insert into t2 select * from t1;
insert into t1 select * from t2; insert into t1 select * from t2;
......
...@@ -177,7 +177,7 @@ uint calc_hashnr_caseup(const byte *key, uint len) ...@@ -177,7 +177,7 @@ uint calc_hashnr_caseup(const byte *key, uint len)
#endif #endif
#ifndef _FORTREC_ #ifndef __SUNPRO_C /* SUNPRO can't handle this */
inline inline
#endif #endif
uint rec_hashnr(HASH *hash,const byte *record) uint rec_hashnr(HASH *hash,const byte *record)
......
...@@ -380,10 +380,12 @@ enum db_type default_table_type=DB_TYPE_MYISAM; ...@@ -380,10 +380,12 @@ enum db_type default_table_type=DB_TYPE_MYISAM;
#ifdef __WIN__ #ifdef __WIN__
#undef getpid #undef getpid
#include <process.h> #include <process.h>
#if !defined(EMBEDDED_LIBRARY)
HANDLE hEventShutdown; HANDLE hEventShutdown;
#include "nt_servc.h" #include "nt_servc.h"
static NTService Service; // Service object for WinNT static NTService Service; // Service object for WinNT
#endif #endif
#endif
#ifdef OS2 #ifdef OS2
pthread_cond_t eventShutdown; pthread_cond_t eventShutdown;
...@@ -609,6 +611,7 @@ void kill_mysql(void) ...@@ -609,6 +611,7 @@ void kill_mysql(void)
#endif #endif
#if defined(__WIN__) #if defined(__WIN__)
#if !defined(EMBEDDED_LIBRARY)
{ {
if (!SetEvent(hEventShutdown)) if (!SetEvent(hEventShutdown))
{ {
...@@ -621,6 +624,7 @@ void kill_mysql(void) ...@@ -621,6 +624,7 @@ void kill_mysql(void)
CloseHandle(hEvent); CloseHandle(hEvent);
*/ */
} }
#endif
#elif defined(OS2) #elif defined(OS2)
pthread_cond_signal( &eventShutdown); // post semaphore pthread_cond_signal( &eventShutdown); // post semaphore
#elif defined(HAVE_PTHREAD_KILL) #elif defined(HAVE_PTHREAD_KILL)
...@@ -1558,8 +1562,9 @@ pthread_handler_decl(handle_shutdown,arg) ...@@ -1558,8 +1562,9 @@ pthread_handler_decl(handle_shutdown,arg)
/* this call should create the message queue for this thread */ /* this call should create the message queue for this thread */
PeekMessage(&msg, NULL, 1, 65534,PM_NOREMOVE); PeekMessage(&msg, NULL, 1, 65534,PM_NOREMOVE);
#if !defined(EMBEDDED_LIBRARY)
if (WaitForSingleObject(hEventShutdown,INFINITE)==WAIT_OBJECT_0) if (WaitForSingleObject(hEventShutdown,INFINITE)==WAIT_OBJECT_0)
#endif
kill_server(MYSQL_KILL_SIGNAL); kill_server(MYSQL_KILL_SIGNAL);
return 0; return 0;
} }
...@@ -1976,7 +1981,7 @@ The server will not act as a slave."); ...@@ -1976,7 +1981,7 @@ The server will not act as a slave.");
} }
} }
(void) thr_setconcurrency(concurrency); // 10 by default (void) thr_setconcurrency(concurrency); // 10 by default
#ifdef __WIN__ //IRENA #if defined(__WIN__) && !defined(EMBEDDED_LIBRARY) //IRENA
{ {
hEventShutdown=CreateEvent(0, FALSE, FALSE, "MySqlShutdown"); hEventShutdown=CreateEvent(0, FALSE, FALSE, "MySqlShutdown");
pthread_t hThread; pthread_t hThread;
...@@ -2084,6 +2089,7 @@ The server will not act as a slave."); ...@@ -2084,6 +2089,7 @@ The server will not act as a slave.");
sql_print_error("After lock_thread_count"); sql_print_error("After lock_thread_count");
#endif #endif
#else #else
#if !defined(EMBEDDED_LIBRARY)
if (Service.IsNT()) if (Service.IsNT())
{ {
if(start_mode) if(start_mode)
...@@ -2103,6 +2109,7 @@ The server will not act as a slave."); ...@@ -2103,6 +2109,7 @@ The server will not act as a slave.");
if(hEventShutdown) CloseHandle(hEventShutdown); if(hEventShutdown) CloseHandle(hEventShutdown);
} }
#endif #endif
#endif
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
my_free((gptr)ssl_acceptor_fd,MYF(MY_ALLOW_ZERO_PTR)); my_free((gptr)ssl_acceptor_fd,MYF(MY_ALLOW_ZERO_PTR));
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
...@@ -2123,7 +2130,7 @@ The server will not act as a slave."); ...@@ -2123,7 +2130,7 @@ The server will not act as a slave.");
} }
#ifdef __WIN__ #if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
/* ------------------------------------------------------------------------ /* ------------------------------------------------------------------------
main and thread entry function for Win32 main and thread entry function for Win32
(all this is needed only to run mysqld as a service on WinNT) (all this is needed only to run mysqld as a service on WinNT)
......
...@@ -54,32 +54,32 @@ ...@@ -54,32 +54,32 @@
ulong max_allowed_packet=65536; ulong max_allowed_packet=65536;
extern ulong net_read_timeout,net_write_timeout; extern ulong net_read_timeout,net_write_timeout;
extern uint test_flags; extern uint test_flags;
#define USE_QUERY_CACHE
extern void query_cache_insert(NET *net, const char *packet, ulong length);
#else #else
ulong max_allowed_packet=16*1024*1024L; ulong max_allowed_packet=16*1024*1024L;
ulong net_read_timeout= NET_READ_TIMEOUT; ulong net_read_timeout= NET_READ_TIMEOUT;
ulong net_write_timeout= NET_WRITE_TIMEOUT; ulong net_write_timeout= NET_WRITE_TIMEOUT;
#endif #endif
#ifdef __WIN__ #if defined(__WIN__) || !defined(MYSQL_SERVER)
/* The following is because alarms doesn't work on windows. */ /* The following is because alarms doesn't work on windows. */
#undef MYSQL_SERVER #define NO_ALARM
#endif #endif
#ifdef MYSQL_SERVER #ifndef NO_ALARM
#include "my_pthread.h" #include "my_pthread.h"
void sql_print_error(const char *format,...); void sql_print_error(const char *format,...);
#define RETRY_COUNT mysqld_net_retry_count #define RETRY_COUNT mysqld_net_retry_count
extern ulong mysqld_net_retry_count; extern ulong mysqld_net_retry_count;
extern ulong bytes_sent, bytes_received; extern ulong bytes_sent, bytes_received;
extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received; extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received;
extern void query_cache_insert(NET *net, const char *packet, ulong length);
#else #else
#undef statistic_add #undef statistic_add
#define statistic_add(A,B,C) #define statistic_add(A,B,C)
#define DONT_USE_THR_ALARM #define DONT_USE_THR_ALARM
#define RETRY_COUNT 1 #define RETRY_COUNT 1
#endif /* MYSQL_SERVER */ #endif /* NO_ALARM */
#include "thr_alarm.h" #include "thr_alarm.h"
...@@ -322,7 +322,7 @@ net_real_write(NET *net,const char *packet,ulong len) ...@@ -322,7 +322,7 @@ net_real_write(NET *net,const char *packet,ulong len)
long int length; long int length;
char *pos,*end; char *pos,*end;
thr_alarm_t alarmed; thr_alarm_t alarmed;
#if defined(MYSQL_SERVER) #ifndef NO_ALARM
ALARM alarm_buff; ALARM alarm_buff;
#endif #endif
uint retry_count=0; uint retry_count=0;
...@@ -371,13 +371,13 @@ net_real_write(NET *net,const char *packet,ulong len) ...@@ -371,13 +371,13 @@ net_real_write(NET *net,const char *packet,ulong len)
#endif /* HAVE_COMPRESS */ #endif /* HAVE_COMPRESS */
/* DBUG_DUMP("net",packet,len); */ /* DBUG_DUMP("net",packet,len); */
#ifdef MYSQL_SERVER #ifndef NO_ALARM
thr_alarm_init(&alarmed); thr_alarm_init(&alarmed);
if (net_blocking) if (net_blocking)
thr_alarm(&alarmed,(uint) net_write_timeout,&alarm_buff); thr_alarm(&alarmed,(uint) net_write_timeout,&alarm_buff);
#else #else
alarmed=0; alarmed=0;
#endif /* MYSQL_SERVER */ #endif /* NO_ALARM */
pos=(char*) packet; end=pos+len; pos=(char*) packet; end=pos+len;
while (pos != end) while (pos != end)
...@@ -459,8 +459,7 @@ net_real_write(NET *net,const char *packet,ulong len) ...@@ -459,8 +459,7 @@ net_real_write(NET *net,const char *packet,ulong len)
** Read something from server/clinet ** Read something from server/clinet
*****************************************************************************/ *****************************************************************************/
#ifdef MYSQL_SERVER #ifndef NO_ALARM
/* /*
Help function to clear the commuication buffer when we get a too Help function to clear the commuication buffer when we get a too
big packet big packet
...@@ -493,7 +492,7 @@ static void my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed) ...@@ -493,7 +492,7 @@ static void my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed)
statistic_add(bytes_received,length,&LOCK_bytes_received); statistic_add(bytes_received,length,&LOCK_bytes_received);
} }
} }
#endif /* MYSQL_SERVER */ #endif /* NO_ALARM */
/* /*
...@@ -510,7 +509,7 @@ my_real_read(NET *net, ulong *complen) ...@@ -510,7 +509,7 @@ my_real_read(NET *net, ulong *complen)
uint i,retry_count=0; uint i,retry_count=0;
ulong len=packet_error; ulong len=packet_error;
thr_alarm_t alarmed; thr_alarm_t alarmed;
#if defined(MYSQL_SERVER) #ifndef NO_ALARM
ALARM alarm_buff; ALARM alarm_buff;
#endif #endif
my_bool net_blocking=vio_is_blocking(net->vio); my_bool net_blocking=vio_is_blocking(net->vio);
...@@ -520,10 +519,10 @@ my_real_read(NET *net, ulong *complen) ...@@ -520,10 +519,10 @@ my_real_read(NET *net, ulong *complen)
net->reading_or_writing=1; net->reading_or_writing=1;
thr_alarm_init(&alarmed); thr_alarm_init(&alarmed);
#ifdef MYSQL_SERVER #ifndef NO_ALARM
if (net_blocking) if (net_blocking)
thr_alarm(&alarmed,net->timeout,&alarm_buff); thr_alarm(&alarmed,net->timeout,&alarm_buff);
#endif /* MYSQL_SERVER */ #endif /* NO_ALARM */
pos = net->buff + net->where_b; /* net->packet -4 */ pos = net->buff + net->where_b; /* net->packet -4 */
for (i=0 ; i < 2 ; i++) for (i=0 ; i < 2 ; i++)
...@@ -646,7 +645,7 @@ my_real_read(NET *net, ulong *complen) ...@@ -646,7 +645,7 @@ my_real_read(NET *net, ulong *complen)
{ {
if (net_realloc(net,helping)) if (net_realloc(net,helping))
{ {
#ifdef MYSQL_SERVER #ifndef NO_ALARM
if (i == 1) if (i == 1)
my_net_skip_rest(net, (uint32) len, &alarmed); my_net_skip_rest(net, (uint32) len, &alarmed);
#endif #endif
......
...@@ -268,6 +268,20 @@ are stored in one block. ...@@ -268,6 +268,20 @@ are stored in one block.
+-------------+ +-------------+ +-------------+ +-------------+
If join_results allocated new block(s) then we need call pack_cache again. If join_results allocated new block(s) then we need call pack_cache again.
TODO list:
- Invalidate queries that use innoDB tables changed in transaction & remove
invalidation by table type
- Delayed till after-parsing qache answer (for column rights processing)
- Optimize cache resizing
- if new_size < old_size then pack & shrink
- if new_size > old_size copy cached query to new cache
- Move MRG_MYISAM table type processing to handlers, something like:
tables_used->table->file->register_used_filenames(callback,
first_argument);
- In Query_cache::insert_table eliminate strlen(). To do this we have to
add db_len to the TABLE_LIST and TABLE structures.
*/ */
#include "mysql_priv.h" #include "mysql_priv.h"
...@@ -615,8 +629,8 @@ void query_cache_abort(NET *net) ...@@ -615,8 +629,8 @@ void query_cache_abort(NET *net)
query_cache.free_query(query_block); query_cache.free_query(query_block);
} }
net->query_cache_query=0; net->query_cache_query=0;
DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1););
STRUCT_UNLOCK(&query_cache.structure_guard_mutex); STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0););
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -640,9 +654,14 @@ void query_cache_end_of_result(NET *net) ...@@ -640,9 +654,14 @@ void query_cache_end_of_result(NET *net)
{ {
DUMP(&query_cache); DUMP(&query_cache);
BLOCK_LOCK_WR(query_block); BLOCK_LOCK_WR(query_block);
Query_cache_query *header = query_block->query();
Query_cache_block *last_result_block = header->result()->prev;
ulong allign_size = ALIGN_SIZE(last_result_block->used);
ulong len = max(query_cache.min_allocation_unit, allign_size);
if (last_result_block->length >= query_cache.min_allocation_unit + len)
query_cache.split_block(last_result_block,len);
STRUCT_UNLOCK(&query_cache.structure_guard_mutex); STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
Query_cache_query *header = query_block->query();
#ifndef DBUG_OFF #ifndef DBUG_OFF
if (header->result() == 0) if (header->result() == 0)
{ {
...@@ -705,13 +724,6 @@ Query_cache::Query_cache(ulong query_cache_limit, ...@@ -705,13 +724,6 @@ Query_cache::Query_cache(ulong query_cache_limit,
ulong Query_cache::resize(ulong query_cache_size) ulong Query_cache::resize(ulong query_cache_size)
{ {
/*
TODO:
When will be realized pack() optimize case when
query_cache_size < this->query_cache_size
Try to copy old cache in new memory
*/
DBUG_ENTER("Query_cache::resize"); DBUG_ENTER("Query_cache::resize");
DBUG_PRINT("qcache", ("from %lu to %lu",this->query_cache_size, DBUG_PRINT("qcache", ("from %lu to %lu",this->query_cache_size,
query_cache_size)); query_cache_size));
...@@ -723,11 +735,6 @@ ulong Query_cache::resize(ulong query_cache_size) ...@@ -723,11 +735,6 @@ ulong Query_cache::resize(ulong query_cache_size)
void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used) void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
{ {
/*
TODO:
Maybe better convert keywords to upper case when query stored/compared.
(Not important at this stage)
*/
TABLE_COUNTER_TYPE tables; TABLE_COUNTER_TYPE tables;
ulong tot_length; ulong tot_length;
DBUG_ENTER("Query_cache::store_query"); DBUG_ENTER("Query_cache::store_query");
...@@ -879,18 +886,9 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) ...@@ -879,18 +886,9 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
/* Check that we haven't forgot to reset the query cache variables */ /* Check that we haven't forgot to reset the query cache variables */
DBUG_ASSERT(thd->net.query_cache_query == 0); DBUG_ASSERT(thd->net.query_cache_query == 0);
/* if (!thd->safe_to_cache_query)
We can't cache the query if we are using a temporary table because
we don't know if the query is using a temporary table.
TODO: We could parse the query and then check if the query used
a temporary table.
*/
if (thd->temporary_tables != 0 || !thd->safe_to_cache_query)
{ {
DBUG_PRINT("qcache", ("SELECT is non-cacheable: tmp_tables: %d safe: %d", DBUG_PRINT("qcache", ("SELECT is non-cacheable"));
thd->temporary_tables,
thd->safe_to_cache_query));
goto err; goto err;
} }
...@@ -1066,12 +1064,8 @@ void Query_cache::invalidate(TABLE *table) ...@@ -1066,12 +1064,8 @@ void Query_cache::invalidate(TABLE *table)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/* /*
Remove all cached queries that uses the given table type. Remove all cached queries that uses the given table type.
TODO: This is currently used to invalidate InnoDB tables on commit.
We should remove this function and only invalidate tables
used in the transaction.
*/ */
void Query_cache::invalidate(Query_cache_table::query_cache_table_type type) void Query_cache::invalidate(Query_cache_table::query_cache_table_type type)
...@@ -1153,6 +1147,8 @@ void Query_cache::flush() ...@@ -1153,6 +1147,8 @@ void Query_cache::flush()
flush_cache(); flush_cache();
DUMP(this); DUMP(this);
} }
DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1););
STRUCT_UNLOCK(&structure_guard_mutex); STRUCT_UNLOCK(&structure_guard_mutex);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -1173,6 +1169,11 @@ void Query_cache::pack(ulong join_limit, uint iteration_limit) ...@@ -1173,6 +1169,11 @@ void Query_cache::pack(ulong join_limit, uint iteration_limit)
void Query_cache::destroy() void Query_cache::destroy()
{ {
if ( !initialized )
{
DBUG_PRINT("qcache", ("Query Cache not initialized"));
return;
}
DBUG_ENTER("Query_cache::destroy"); DBUG_ENTER("Query_cache::destroy");
free_cache(1); free_cache(1);
pthread_mutex_destroy(&structure_guard_mutex); pthread_mutex_destroy(&structure_guard_mutex);
...@@ -1586,15 +1587,15 @@ Query_cache::append_result_data(Query_cache_block **current_block, ...@@ -1586,15 +1587,15 @@ Query_cache::append_result_data(Query_cache_block **current_block,
*/ */
// Try join blocks if physically next block is free... // Try join blocks if physically next block is free...
ulong tail = data_len - last_block_free_space;
ulong append_min = get_min_append_result_data_size();
if (last_block_free_space < data_len && if (last_block_free_space < data_len &&
append_next_free_block(last_block, append_next_free_block(last_block,
max(data_len - last_block_free_space, max(tail, append_min)))
QUERY_CACHE_MIN_RESULT_DATA_SIZE)))
last_block_free_space = last_block->length - last_block->used; last_block_free_space = last_block->length - last_block->used;
// If no space in last block (even after join) allocate new block // If no space in last block (even after join) allocate new block
if (last_block_free_space < data_len) if (last_block_free_space < data_len)
{ {
// TODO: Try get memory from next free block (if exist) (is it needed?)
DBUG_PRINT("qcache", ("allocate new block for %lu bytes", DBUG_PRINT("qcache", ("allocate new block for %lu bytes",
data_len-last_block_free_space)); data_len-last_block_free_space));
Query_cache_block *new_block = 0; Query_cache_block *new_block = 0;
...@@ -1650,7 +1651,8 @@ my_bool Query_cache::write_result_data(Query_cache_block **result_block, ...@@ -1650,7 +1651,8 @@ my_bool Query_cache::write_result_data(Query_cache_block **result_block,
structure_guard_mutex and copy data. structure_guard_mutex and copy data.
*/ */
my_bool success = allocate_data_chain(result_block, data_len, query_block); my_bool success = allocate_data_chain(result_block, data_len, query_block,
type == Query_cache_block::RES_BEG);
if (success) if (success)
{ {
// It is success (nobody can prevent us write data) // It is success (nobody can prevent us write data)
...@@ -1695,13 +1697,28 @@ my_bool Query_cache::write_result_data(Query_cache_block **result_block, ...@@ -1695,13 +1697,28 @@ my_bool Query_cache::write_result_data(Query_cache_block **result_block,
DBUG_RETURN(success); DBUG_RETURN(success);
} }
inline ulong Query_cache::get_min_first_result_data_size()
{
if (queries_in_cache < QUERY_CACHE_MIN_ESTIMATED_QUERIES_NUMBER)
return min_result_data_size;
ulong avg_result = (query_cache_size - free_memory) / queries_in_cache;
avg_result = min(avg_result, query_cache_limit);
return max(min_result_data_size, avg_result);
}
inline ulong Query_cache::get_min_append_result_data_size()
{
return min_result_data_size;
}
/* /*
Allocate one or more blocks to hold data Allocate one or more blocks to hold data
*/ */
my_bool Query_cache::allocate_data_chain(Query_cache_block **result_block, my_bool Query_cache::allocate_data_chain(Query_cache_block **result_block,
ulong data_len, ulong data_len,
Query_cache_block *query_block) Query_cache_block *query_block,
my_bool first_block)
{ {
ulong all_headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) + ulong all_headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
ALIGN_SIZE(sizeof(Query_cache_result))); ALIGN_SIZE(sizeof(Query_cache_result)));
...@@ -1710,7 +1727,10 @@ my_bool Query_cache::allocate_data_chain(Query_cache_block **result_block, ...@@ -1710,7 +1727,10 @@ my_bool Query_cache::allocate_data_chain(Query_cache_block **result_block,
DBUG_PRINT("qcache", ("data_len %lu, all_headers_len %lu", DBUG_PRINT("qcache", ("data_len %lu, all_headers_len %lu",
data_len, all_headers_len)); data_len, all_headers_len));
*result_block = allocate_block(max(min_result_data_size,len), ulong min_size = (first_block ?
get_min_first_result_data_size():
get_min_append_result_data_size());
*result_block = allocate_block(max(min_size,len),
min_result_data_size == 0, min_result_data_size == 0,
all_headers_len + min_result_data_size, all_headers_len + min_result_data_size,
1); 1);
...@@ -1734,7 +1754,7 @@ my_bool Query_cache::allocate_data_chain(Query_cache_block **result_block, ...@@ -1734,7 +1754,7 @@ my_bool Query_cache::allocate_data_chain(Query_cache_block **result_block,
Query_cache_block *next_block; Query_cache_block *next_block;
if ((success = allocate_data_chain(&next_block, if ((success = allocate_data_chain(&next_block,
len - new_block->length, len - new_block->length,
query_block))) query_block, first_block)))
double_linked_list_join(new_block, next_block); double_linked_list_join(new_block, next_block);
} }
if (success) if (success)
...@@ -1825,15 +1845,7 @@ my_bool Query_cache::register_all_tables(Query_cache_block *block, ...@@ -1825,15 +1845,7 @@ my_bool Query_cache::register_all_tables(Query_cache_block *block,
Query_cache_table::type_convertion(tables_used->table-> Query_cache_table::type_convertion(tables_used->table->
db_type))) db_type)))
break; break;
/*
TODO: (Low priority)
The following has to be recoded to not test for a specific table
type but instead call a handler function that does this for us.
Something like the following:
tables_used->table->file->register_used_filenames(callback,
first_argument);
*/
if (tables_used->table->db_type == DB_TYPE_MRG_MYISAM) if (tables_used->table->db_type == DB_TYPE_MRG_MYISAM)
{ {
ha_myisammrg *handler = (ha_myisammrg *) tables_used->table->file; ha_myisammrg *handler = (ha_myisammrg *) tables_used->table->file;
...@@ -1911,10 +1923,6 @@ Query_cache::insert_table(uint key_len, char *key, ...@@ -1911,10 +1923,6 @@ Query_cache::insert_table(uint key_len, char *key,
DBUG_RETURN(0); DBUG_RETURN(0);
} }
char *db = header->db(); char *db = header->db();
/*
TODO: Eliminate strlen() by sending this to the function
To do this we have to add db_len to the TABLE_LIST and TABLE structures.
*/
header->table(db + strlen(db) + 1); header->table(db + strlen(db) + 1);
} }
...@@ -1978,7 +1986,7 @@ Query_cache::allocate_block(ulong len, my_bool not_less, ulong min, ...@@ -1978,7 +1986,7 @@ Query_cache::allocate_block(ulong len, my_bool not_less, ulong min,
if (block != 0) // If we found a suitable block if (block != 0) // If we found a suitable block
{ {
if (block->length > ALIGN_SIZE(len) + min_allocation_unit) if (block->length >= ALIGN_SIZE(len) + min_allocation_unit)
split_block(block,ALIGN_SIZE(len)); split_block(block,ALIGN_SIZE(len));
} }
...@@ -2083,7 +2091,7 @@ void Query_cache::free_memory_block(Query_cache_block *block) ...@@ -2083,7 +2091,7 @@ void Query_cache::free_memory_block(Query_cache_block *block)
} }
void Query_cache::split_block(Query_cache_block *block,ulong len) void Query_cache::split_block(Query_cache_block *block, ulong len)
{ {
DBUG_ENTER("Query_cache::split_block"); DBUG_ENTER("Query_cache::split_block");
Query_cache_block *new_block = (Query_cache_block*)(((byte*) block)+len); Query_cache_block *new_block = (Query_cache_block*)(((byte*) block)+len);
...@@ -2096,7 +2104,11 @@ void Query_cache::split_block(Query_cache_block *block,ulong len) ...@@ -2096,7 +2104,11 @@ void Query_cache::split_block(Query_cache_block *block,ulong len)
new_block->pprev = block; new_block->pprev = block;
new_block->pnext->pprev = new_block; new_block->pnext->pprev = new_block;
insert_into_free_memory_list(new_block); if (block->type == Query_cache_block::FREE)
// if block was free then it already joined with all free neighbours
insert_into_free_memory_list(new_block);
else
free_memory_block(new_block);
DBUG_PRINT("qcache", ("split 0x%lx (%lu) new 0x%lx", DBUG_PRINT("qcache", ("split 0x%lx (%lu) new 0x%lx",
(ulong) block, len, (ulong) new_block)); (ulong) block, len, (ulong) new_block));
...@@ -2407,13 +2419,15 @@ TABLE_COUNTER_TYPE Query_cache::is_cacheable(THD *thd, uint32 query_len, ...@@ -2407,13 +2419,15 @@ TABLE_COUNTER_TYPE Query_cache::is_cacheable(THD *thd, uint32 query_len,
void Query_cache::pack_cache() void Query_cache::pack_cache()
{ {
DBUG_ENTER("Query_cache::pack_cache");
STRUCT_LOCK(&structure_guard_mutex); STRUCT_LOCK(&structure_guard_mutex);
DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1););
byte *border = 0; byte *border = 0;
Query_cache_block *before = 0; Query_cache_block *before = 0;
ulong gap = 0; ulong gap = 0;
my_bool ok = 1; my_bool ok = 1;
Query_cache_block *block = first_block; Query_cache_block *block = first_block;
DBUG_ENTER("Query_cache::pack_cache");
DUMP(this); DUMP(this);
if (first_block) if (first_block)
...@@ -2438,6 +2452,8 @@ void Query_cache::pack_cache() ...@@ -2438,6 +2452,8 @@ void Query_cache::pack_cache()
} }
DUMP(this); DUMP(this);
} }
DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1););
STRUCT_UNLOCK(&structure_guard_mutex); STRUCT_UNLOCK(&structure_guard_mutex);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -2502,22 +2518,14 @@ my_bool Query_cache::move_by_type(byte **border, ...@@ -2502,22 +2518,14 @@ my_bool Query_cache::move_by_type(byte **border,
Query_cache_block_table *nlist_root = new_block->table(0); Query_cache_block_table *nlist_root = new_block->table(0);
nlist_root->n = 0; nlist_root->n = 0;
if (tnext == list_root) nlist_root->next = tnext;
{ tnext->prev = nlist_root;
nlist_root->next = nlist_root; nlist_root->prev = tprev;
nlist_root->prev = nlist_root; tprev->next = nlist_root;
} DBUG_PRINT("qcache",
else ("list_root: 0x%lx tnext 0x%lx tprev 0x%lx tprev->next 0x%lx tnext->prev 0x%lx",
{ (ulong) list_root, (ulong) tnext, (ulong) tprev,
nlist_root->next = tnext; (ulong)tprev->next, (ulong)tnext->prev));
tnext->prev = nlist_root;
}
if (tprev != list_root)
{
nlist_root->prev = tnext;
tprev->next = nlist_root;
}
/* /*
Go through all queries that uses this table and change them to Go through all queries that uses this table and change them to
point to the new table object point to the new table object
...@@ -3076,10 +3084,23 @@ my_bool Query_cache::check_integrity(bool not_locked) ...@@ -3076,10 +3084,23 @@ my_bool Query_cache::check_integrity(bool not_locked)
case Query_cache_block::TABLE: case Query_cache_block::TABLE:
if (in_list(tables_blocks[block->table()->type()], block, "tables")) if (in_list(tables_blocks[block->table()->type()], block, "tables"))
result = 1; result = 1;
if (in_table_list(block->table(0), block->table(0), "table list root"))
result = 1;
break; break;
case Query_cache_block::QUERY: case Query_cache_block::QUERY:
if (in_list(queries_blocks, block, "query")) if (in_list(queries_blocks, block, "query"))
result = 1; result = 1;
for (TABLE_COUNTER_TYPE j=0; j < block->n_tables; j++)
{
Query_cache_block_table *block_table = block->table(j);
Query_cache_block_table *block_table_root =
(Query_cache_block_table *)
(((byte*)block_table->parent) -
ALIGN_SIZE(sizeof(Query_cache_block_table)));
if (in_table_list(block_table, block_table_root, "table list"))
result = 1;
}
break; break;
case Query_cache_block::RES_INCOMPLETE: case Query_cache_block::RES_INCOMPLETE:
// This type of block can be not lincked yet (in multithread environment) // This type of block can be not lincked yet (in multithread environment)
...@@ -3341,4 +3362,85 @@ my_bool Query_cache::in_list(Query_cache_block * root, ...@@ -3341,4 +3362,85 @@ my_bool Query_cache::in_list(Query_cache_block * root,
return result; return result;
} }
void dump_node(Query_cache_block_table * node,
const char * call, const char * descr)
{
DBUG_PRINT("qcache", ("%s: %s: node: 0x%lx", call, descr, (ulong) node));
DBUG_PRINT("qcache", ("%s: %s: node block: 0x%lx",
call, descr, (ulong) node->block()));
DBUG_PRINT("qcache", ("%s: %s: next: 0x%lx", call, descr,
(ulong) node->next));
DBUG_PRINT("qcache", ("%s: %s: prev: 0x%lx", call, descr,
(ulong) node->prev));
}
my_bool Query_cache::in_table_list(Query_cache_block_table * root,
Query_cache_block_table * point,
const char *name)
{
my_bool result = 0;
Query_cache_block_table *table = point;
dump_node(root, name, "parameter root");
//back
do
{
dump_node(table, name, "list element << ");
if (table->prev->next != table)
{
DBUG_PRINT("error",
("table 0x%lx(0x%lx) in list '%s' 0x%lx(0x%lx) is incorrect linked, prev table 0x%lx(0x%lx) refered as next to 0x%lx(0x%lx) (check from 0x%lx(0x%lx))",
(ulong) table, (ulong) table->block(), name,
(ulong) root, (ulong) root->block(),
(ulong) table->prev, (ulong) table->prev->block(),
(ulong) table->prev->next,
(ulong) table->prev->next->block(),
(ulong) point, (ulong) point->block()));
//back trace
for(; table != point; table = table->next)
DBUG_PRINT("error", ("back trace 0x%lx(0x%lx)",
(ulong) table, (ulong) table->block()));
result = 1;
goto err1;
}
table = table->prev;
} while (table != root && table != point);
if (table != root)
{
DBUG_PRINT("error",
("table 0x%lx(0x%lx) (0x%lx(0x%lx)<-->0x%lx(0x%lx)) not owned by list '%s' 0x%lx(0x%lx)",
(ulong) table, (ulong) table->block(),
(ulong) table->prev, (ulong) table->prev->block(),
(ulong) table->next, (ulong) table->next->block(),
name, (ulong) root, (ulong) root->block()));
return 1;
}
err1:
// forward
table = point;
do
{
dump_node(table, name, "list element >> ");
if (table->next->prev != table)
{
DBUG_PRINT("error",
("table 0x%lx(0x%lx) in list '%s' 0x%lx(0x%lx) is incorrect linked, next table 0x%lx(0x%lx) refered as prev to 0x%lx(0x%lx) (check from 0x%lx(0x%lx))",
(ulong) table, (ulong) table->block(),
name, (ulong) root, (ulong) root->block(),
(ulong) table->next, (ulong) table->next->block(),
(ulong) table->next->prev,
(ulong) table->next->prev->block(),
(ulong) point, (ulong) point->block()));
//back trace
for (; table != point; table = table->prev)
DBUG_PRINT("error", ("back trace 0x%lx(0x%lx)",
(ulong) table, (ulong) table->block()));
result = 1;
goto err2;
}
table = table->next;
} while (table != root);
err2:
return result;
}
#endif /* DBUG_OFF */ #endif /* DBUG_OFF */
...@@ -25,14 +25,22 @@ ...@@ -25,14 +25,22 @@
if QUERY_CACHE_MIN_ALLOCATION_UNIT == 0 then if QUERY_CACHE_MIN_ALLOCATION_UNIT == 0 then
QUERY_CACHE_MIN_ALLOCATION_UNIT choosed automaticaly QUERY_CACHE_MIN_ALLOCATION_UNIT choosed automaticaly
*/ */
#define QUERY_CACHE_MIN_ALLOCATION_UNIT 0 #define QUERY_CACHE_MIN_ALLOCATION_UNIT 512
/* inittial size of hashes */ /* inittial size of hashes */
#define QUERY_CACHE_DEF_QUERY_HASH_SIZE 1024 #define QUERY_CACHE_DEF_QUERY_HASH_SIZE 1024
#define QUERY_CACHE_DEF_TABLE_HASH_SIZE 1024 #define QUERY_CACHE_DEF_TABLE_HASH_SIZE 1024
/* minimal result data size when data allocated */ /* minimal result data size when data allocated */
#define QUERY_CACHE_MIN_RESULT_DATA_SIZE 1024 #define QUERY_CACHE_MIN_RESULT_DATA_SIZE 1024*4
/*
start estimation of first result block size only when number of queries
bigger then:
*/
#define QUERY_CACHE_MIN_ESTIMATED_QUERIES_NUMBER 3
/* memory bins size spacing (see at Query_cache::init_cache (sql_cache.cc)) */ /* memory bins size spacing (see at Query_cache::init_cache (sql_cache.cc)) */
#define QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2 4 #define QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2 4
...@@ -234,8 +242,7 @@ class Query_cache ...@@ -234,8 +242,7 @@ class Query_cache
query structure we locked an internal query block mutex. query structure we locked an internal query block mutex.
LOCK SEQUENCE (to prevent deadlocks): LOCK SEQUENCE (to prevent deadlocks):
1. structure_guard_mutex 1. structure_guard_mutex
2. query block / table block / free block 2. query block (for operation inside query (query block/results))
3. results blocks (only when must become free).
*/ */
pthread_mutex_t structure_guard_mutex; pthread_mutex_t structure_guard_mutex;
byte *cache; // cache memory byte *cache; // cache memory
...@@ -271,7 +278,8 @@ class Query_cache ...@@ -271,7 +278,8 @@ class Query_cache
void free_query(Query_cache_block *point); void free_query(Query_cache_block *point);
my_bool allocate_data_chain(Query_cache_block **result_block, my_bool allocate_data_chain(Query_cache_block **result_block,
ulong data_len, ulong data_len,
Query_cache_block *query_block); Query_cache_block *query_block,
my_bool first_block);
void invalidate_table(TABLE_LIST *table); void invalidate_table(TABLE_LIST *table);
void invalidate_table(TABLE *table); void invalidate_table(TABLE *table);
void invalidate_table(Query_cache_block *table_block); void invalidate_table(Query_cache_block *table_block);
...@@ -328,6 +336,8 @@ class Query_cache ...@@ -328,6 +336,8 @@ class Query_cache
Query_cache_block *parent, Query_cache_block *parent,
Query_cache_block::block_type Query_cache_block::block_type
type=Query_cache_block::RESULT); type=Query_cache_block::RESULT);
inline ulong get_min_first_result_data_size();
inline ulong get_min_append_result_data_size();
Query_cache_block *allocate_block(ulong len, my_bool not_less, Query_cache_block *allocate_block(ulong len, my_bool not_less,
ulong min, ulong min,
my_bool under_guard=0); my_bool under_guard=0);
...@@ -394,6 +404,9 @@ class Query_cache ...@@ -394,6 +404,9 @@ class Query_cache
my_bool check_integrity(bool not_locked); my_bool check_integrity(bool not_locked);
my_bool in_list(Query_cache_block * root, Query_cache_block * point, my_bool in_list(Query_cache_block * root, Query_cache_block * point,
const char *name); const char *name);
my_bool in_table_list(Query_cache_block_table * root,
Query_cache_block_table * point,
const char *name);
my_bool in_blocks(Query_cache_block * point); my_bool in_blocks(Query_cache_block * point);
}; };
......
...@@ -656,7 +656,7 @@ class Unique :public Sql_alloc ...@@ -656,7 +656,7 @@ class Unique :public Sql_alloc
uint num_of_tables; uint num_of_tables;
int error; int error;
thr_lock_type lock_option; thr_lock_type lock_option;
bool do_delete; bool do_delete, not_trans_safe;
public: public:
multi_delete(THD *thd, TABLE_LIST *dt, thr_lock_type lock_option_arg, multi_delete(THD *thd, TABLE_LIST *dt, thr_lock_type lock_option_arg,
uint num_of_tables); uint num_of_tables);
......
...@@ -216,6 +216,7 @@ multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt, ...@@ -216,6 +216,7 @@ multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt,
do_delete(false) do_delete(false)
{ {
uint counter=0; uint counter=0;
not_trans_safe=false;
tempfiles = (Unique **) sql_calloc(sizeof(Unique *) * (num_of_tables-1)); tempfiles = (Unique **) sql_calloc(sizeof(Unique *) * (num_of_tables-1));
(void) dt->table->file->extra(HA_EXTRA_NO_READCHECK); (void) dt->table->file->extra(HA_EXTRA_NO_READCHECK);
...@@ -225,8 +226,9 @@ multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt, ...@@ -225,8 +226,9 @@ multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt,
for (dt=dt->next ; dt ; dt=dt->next,counter++) for (dt=dt->next ; dt ; dt=dt->next,counter++)
{ {
TABLE *table=dt->table; TABLE *table=dt->table;
(void) dt->table->file->extra(HA_EXTRA_NO_READCHECK); (void) table->file->extra(HA_EXTRA_NO_READCHECK);
(void) dt->table->file->extra(HA_EXTRA_NO_KEYREAD); (void) table->file->extra(HA_EXTRA_NO_KEYREAD);
table->used_keys=0;
tempfiles[counter] = new Unique (refposcmp2, tempfiles[counter] = new Unique (refposcmp2,
(void *) &table->file->ref_length, (void *) &table->file->ref_length,
table->file->ref_length, table->file->ref_length,
...@@ -279,8 +281,11 @@ multi_delete::initialize_tables(JOIN *join) ...@@ -279,8 +281,11 @@ multi_delete::initialize_tables(JOIN *join)
walk=walk->next; walk=walk->next;
if (tab == join->join_tab) if (tab == join->join_tab)
tab->table->no_keyread=1; tab->table->no_keyread=1;
if (!not_trans_safe && !tab->table->file->has_transactions())
not_trans_safe=true;
} }
} }
init_ftfuncs(thd,1);
} }
...@@ -290,7 +295,11 @@ multi_delete::~multi_delete() ...@@ -290,7 +295,11 @@ multi_delete::~multi_delete()
for (table_being_deleted=delete_tables ; for (table_being_deleted=delete_tables ;
table_being_deleted ; table_being_deleted ;
table_being_deleted=table_being_deleted->next) table_being_deleted=table_being_deleted->next)
(void) table_being_deleted->table->file->extra(HA_EXTRA_READCHECK); {
TABLE *t=table_being_deleted->table;
(void) t->file->extra(HA_EXTRA_READCHECK);
t->no_keyread=0;
}
for (uint counter = 0; counter < num_of_tables-1; counter++) for (uint counter = 0; counter < num_of_tables-1; counter++)
{ {
...@@ -339,28 +348,13 @@ bool multi_delete::send_data(List<Item> &values) ...@@ -339,28 +348,13 @@ bool multi_delete::send_data(List<Item> &values)
return 0; return 0;
} }
/* Return true if some table is not transaction safe */
static bool some_table_is_not_transaction_safe (TABLE_LIST *tl)
{
for (; tl ; tl=tl->next)
{
if (!(tl->table->file->has_transactions()))
return true;
}
return false;
}
void multi_delete::send_error(uint errcode,const char *err) void multi_delete::send_error(uint errcode,const char *err)
{ {
/* First send error what ever it is ... */ /* First send error what ever it is ... */
::send_error(&thd->net,errcode,err); ::send_error(&thd->net,errcode,err);
/* reset used flags */ /* reset used flags */
delete_tables->table->no_keyread=0; // delete_tables->table->no_keyread=0;
/* If nothing deleted return */ /* If nothing deleted return */
if (!deleted) if (!deleted)
...@@ -376,8 +370,7 @@ void multi_delete::send_error(uint errcode,const char *err) ...@@ -376,8 +370,7 @@ void multi_delete::send_error(uint errcode,const char *err)
In all other cases do attempt deletes ... In all other cases do attempt deletes ...
*/ */
if ((table_being_deleted->table->file->has_transactions() && if ((table_being_deleted->table->file->has_transactions() &&
table_being_deleted == delete_tables) || table_being_deleted == delete_tables) || !not_trans_safe)
!some_table_is_not_transaction_safe(delete_tables->next))
ha_rollback_stmt(thd); ha_rollback_stmt(thd);
else if (do_delete) else if (do_delete)
VOID(do_deletes(true)); VOID(do_deletes(true));
...@@ -441,7 +434,6 @@ int multi_delete::do_deletes (bool from_send_error) ...@@ -441,7 +434,6 @@ int multi_delete::do_deletes (bool from_send_error)
READ_RECORD info; READ_RECORD info;
init_read_record(&info,thd,table,NULL,0,0); init_read_record(&info,thd,table,NULL,0,0);
bool not_trans_safe = some_table_is_not_transaction_safe(delete_tables);
while (!(error=info.read_record(&info)) && while (!(error=info.read_record(&info)) &&
(!thd->killed || from_send_error || not_trans_safe)) (!thd->killed || from_send_error || not_trans_safe))
{ {
...@@ -468,7 +460,7 @@ bool multi_delete::send_eof() ...@@ -468,7 +460,7 @@ bool multi_delete::send_eof()
int error = do_deletes(false); /* do_deletes returns 0 if success */ int error = do_deletes(false); /* do_deletes returns 0 if success */
/* reset used flags */ /* reset used flags */
delete_tables->table->no_keyread=0; // delete_tables->table->no_keyread=0; // Will stay in comment until Monty approves changes
thd->proc_info="end"; thd->proc_info="end";
if (error) if (error)
{ {
...@@ -481,20 +473,21 @@ bool multi_delete::send_eof() ...@@ -481,20 +473,21 @@ bool multi_delete::send_eof()
was a non-transaction-safe table involved, since was a non-transaction-safe table involved, since
modifications in it cannot be rolled back. */ modifications in it cannot be rolled back. */
if (deleted || some_table_is_not_transaction_safe(delete_tables)) if (deleted || not_trans_safe)
{ {
mysql_update_log.write(thd,thd->query,thd->query_length); mysql_update_log.write(thd,thd->query,thd->query_length);
if (mysql_bin_log.is_open()) if (mysql_bin_log.is_open())
{ {
Query_log_event qinfo(thd, thd->query); Query_log_event qinfo(thd, thd->query);
if (mysql_bin_log.write(&qinfo) && if (mysql_bin_log.write(&qinfo) &&
!some_table_is_not_transaction_safe(delete_tables)) !not_trans_safe)
error=1; // Log write failed: roll back the SQL statement error=1; // Log write failed: roll back the SQL statement
} }
/* Commit or rollback the current SQL statement */ /* Commit or rollback the current SQL statement */
VOID(ha_autocommit_or_rollback(thd,error > 0)); VOID(ha_autocommit_or_rollback(thd,error > 0));
} }
if (deleted)
query_cache.invalidate(delete_tables);
::send_ok(&thd->net,deleted); ::send_ok(&thd->net,deleted);
return 0; return 0;
} }
......
...@@ -1328,7 +1328,7 @@ void select_insert::send_error(uint errcode,const char *err) ...@@ -1328,7 +1328,7 @@ void select_insert::send_error(uint errcode,const char *err)
::send_error(&thd->net,errcode,err); ::send_error(&thd->net,errcode,err);
table->file->extra(HA_EXTRA_NO_CACHE); table->file->extra(HA_EXTRA_NO_CACHE);
table->file->activate_all_index(thd); table->file->activate_all_index(thd);
ha_rollback(thd); ha_rollback_stmt(thd);
if (info.copied || info.deleted) if (info.copied || info.deleted)
query_cache.invalidate(table); query_cache.invalidate(table);
} }
......
...@@ -1216,7 +1216,6 @@ mysql_execute_command(void) ...@@ -1216,7 +1216,6 @@ mysql_execute_command(void)
#endif #endif
} }
thread_safe_increment(com_stat[lex->sql_command],&LOCK_thread_count);
/* /*
Skip if we are in the slave thread, some table rules have been given Skip if we are in the slave thread, some table rules have been given
and the table list says the query should not be replicated and the table list says the query should not be replicated
...@@ -1863,8 +1862,8 @@ mysql_execute_command(void) ...@@ -1863,8 +1862,8 @@ mysql_execute_command(void)
/* Fix tables-to-be-deleted-from list to point at opened tables */ /* Fix tables-to-be-deleted-from list to point at opened tables */
for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next) for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next)
auxi->table= ((TABLE_LIST*) auxi->table)->table; auxi->table= ((TABLE_LIST*) auxi->table)->table;
if ((result=new multi_delete(thd,aux_tables,lex->lock_option, if (!thd->fatal_error && (result=new multi_delete(thd,aux_tables,
table_count)) && ! thd->fatal_error) lex->lock_option,table_count)))
{ {
res=mysql_select(thd,tables,select_lex->item_list, res=mysql_select(thd,tables,select_lex->item_list,
select_lex->where, select_lex->where,
...@@ -1873,10 +1872,10 @@ mysql_execute_command(void) ...@@ -1873,10 +1872,10 @@ mysql_execute_command(void)
select_lex->options | thd->options | select_lex->options | thd->options |
SELECT_NO_JOIN_CACHE, SELECT_NO_JOIN_CACHE,
result); result);
delete result;
} }
else else
res= -1; // Error is not sent res= -1; // Error is not sent
delete result;
close_thread_tables(thd); close_thread_tables(thd);
break; break;
} }
......
...@@ -212,8 +212,6 @@ int quick_rm_table(enum db_type base,const char *db, ...@@ -212,8 +212,6 @@ int quick_rm_table(enum db_type base,const char *db,
static int sort_keys(KEY *a, KEY *b) static int sort_keys(KEY *a, KEY *b)
{ {
if (a == b) // Safety
return 0;
if (a->flags & HA_NOSAME) if (a->flags & HA_NOSAME)
{ {
if (!(b->flags & HA_NOSAME)) if (!(b->flags & HA_NOSAME))
...@@ -235,7 +233,13 @@ static int sort_keys(KEY *a, KEY *b) ...@@ -235,7 +233,13 @@ static int sort_keys(KEY *a, KEY *b)
{ {
return (a->flags & HA_FULLTEXT) ? 1 : -1; return (a->flags & HA_FULLTEXT) ? 1 : -1;
} }
return a < b ? -1 : 1; // Prefer original key order /*
Prefer original key order. usable_key_parts contains here
the original key position.
*/
return ((a->usable_key_parts < b->usable_key_parts) ? -1 :
(a->usable_key_parts > b->usable_key_parts) ? 1 :
0);
} }
...@@ -396,7 +400,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, ...@@ -396,7 +400,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
List<Key> keys_in_order; // Add new keys here List<Key> keys_in_order; // Add new keys here
bool primary_key=0,unique_key=0; bool primary_key=0,unique_key=0;
Key *key; Key *key;
uint tmp; uint tmp, key_number;
tmp=min(file->max_keys(), MAX_KEY); tmp=min(file->max_keys(), MAX_KEY);
if (key_count > tmp) if (key_count > tmp)
{ {
...@@ -428,7 +432,8 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, ...@@ -428,7 +432,8 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
DBUG_RETURN(-1); // Out of memory DBUG_RETURN(-1); // Out of memory
key_iterator.rewind(); key_iterator.rewind();
for (; (key=key_iterator++) ; key_info++) key_number=0;
for (; (key=key_iterator++) ; key_info++, key_number++)
{ {
uint key_length=0; uint key_length=0;
key_part_spec *column; key_part_spec *column;
...@@ -437,6 +442,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, ...@@ -437,6 +442,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
(key->type == Key::FULLTEXT) ? HA_FULLTEXT : HA_NOSAME; (key->type == Key::FULLTEXT) ? HA_FULLTEXT : HA_NOSAME;
key_info->key_parts=(uint8) key->columns.elements; key_info->key_parts=(uint8) key->columns.elements;
key_info->key_part=key_part_info; key_info->key_part=key_part_info;
key_info->usable_key_parts= key_number;
if (key->type == Key::FULLTEXT) if (key->type == Key::FULLTEXT)
{ {
......
...@@ -792,6 +792,8 @@ bool multi_update::send_eof() ...@@ -792,6 +792,8 @@ bool multi_update::send_eof()
char buff[80]; char buff[80];
sprintf(buff,ER(ER_UPDATE_INFO), (long) found, (long) updated, sprintf(buff,ER(ER_UPDATE_INFO), (long) found, (long) updated,
(long) thd->cuted_fields); (long) thd->cuted_fields);
if (updated)
query_cache.invalidate(update_tables);
::send_ok(&thd->net, ::send_ok(&thd->net,
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated, (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated,
thd->insert_id_used ? thd->insert_id() : 0L,buff); thd->insert_id_used ? thd->insert_id() : 0L,buff);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment